Bug 1403260 - [Mac] Remove access to print server from content process sandbox. r=mconley draft
authorHaik Aftandilian <haftandilian@mozilla.com>
Mon, 30 Oct 2017 11:14:08 -0700
changeset 689156 8a6859d411b332aca404bb6a78b91cdae6b498c0
parent 689153 de9f281d9150a590157282f4d1ebcb03b6351603
child 738243 8d9041850d389baa049d892434421e4025ca789b
push id86939
push userhaftandilian@mozilla.com
push dateTue, 31 Oct 2017 06:05:34 +0000
reviewersmconley
bugs1403260
milestone58.0a1
Bug 1403260 - [Mac] Remove access to print server from content process sandbox. r=mconley MozReview-Commit-ID: Ia21je8TTIg
security/sandbox/mac/SandboxPolicies.h
widget/cocoa/nsPrintOptionsX.h
widget/cocoa/nsPrintOptionsX.mm
widget/cocoa/nsPrintSettingsX.mm
--- a/security/sandbox/mac/SandboxPolicies.h
+++ b/security/sandbox/mac/SandboxPolicies.h
@@ -245,20 +245,16 @@ static const char contentSandboxRules[] 
   (if (string? debugWriteDir)
     (begin
       (allow file-write-data (subpath debugWriteDir))
       (allow file-write-create
         (require-all
           (subpath debugWriteDir)
           (vnode-type REGULAR-FILE)))))
 
-  ; bug 1324610
-  (allow network-outbound file-read*
-    (literal "/private/var/run/cupsd"))
-
   (allow-shared-list "org.mozilla.plugincontainer")
 
 ; the following rule should be removed when microphone access
 ; is brokered through the content process
   (allow device-microphone)
 
 ; Per-user and system-wide Extensions dir
   (allow file-read*
--- a/widget/cocoa/nsPrintOptionsX.h
+++ b/widget/cocoa/nsPrintOptionsX.h
@@ -34,11 +34,22 @@ public:
                                      mozilla::embedding::PrintData* data);
   NS_IMETHODIMP DeserializeToPrintSettings(const mozilla::embedding::PrintData& data,
                                            nsIPrintSettings* settings);
 
 protected:
   nsresult   _CreatePrintSettings(nsIPrintSettings **_retval);
   nsresult   ReadPrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName, uint32_t aFlags);
   nsresult   WritePrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName, uint32_t aFlags);
+
+private:
+  /* Serialization done in child to be deserialized in the parent */
+  nsresult SerializeToPrintDataChild(nsIPrintSettings* aSettings,
+                                     nsIWebBrowserPrint* aWBP,
+                                     mozilla::embedding::PrintData* data);
+
+  /* Serialization done in parent to be deserialized in the child */
+  nsresult SerializeToPrintDataParent(nsIPrintSettings* aSettings,
+                                      nsIWebBrowserPrint* aWBP,
+                                      mozilla::embedding::PrintData* data);
 };
 
 #endif // nsPrintOptionsX_h_
--- a/widget/cocoa/nsPrintOptionsX.mm
+++ b/widget/cocoa/nsPrintOptionsX.mm
@@ -26,52 +26,82 @@ nsPrintOptionsX::SerializeToPrintData(ns
                                       nsIWebBrowserPrint* aWBP,
                                       PrintData* data)
 {
   nsresult rv = nsPrintOptions::SerializeToPrintData(aSettings, aWBP, data);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
+  RefPtr<nsPrintSettingsX> settingsX(do_QueryObject(aSettings));
+  if (NS_WARN_IF(!settingsX)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  double adjustedWidth, adjustedHeight;
+  settingsX->GetAdjustedPaperSize(&adjustedWidth, &adjustedHeight);
+  data->adjustedPaperWidth() = adjustedWidth;
+  data->adjustedPaperHeight() = adjustedHeight;
+
+  if (XRE_IsParentProcess()) {
+    return SerializeToPrintDataParent(aSettings, aWBP, data);
+  }
+
+  return SerializeToPrintDataChild(aSettings, aWBP, data);
+}
+
+nsresult
+nsPrintOptionsX::SerializeToPrintDataChild(nsIPrintSettings* aSettings,
+                                           nsIWebBrowserPrint* aWBP,
+                                           PrintData* data)
+{
+  // If we are in the child process, we don't need to populate
+  // nsPrintSettingsX completely. The parent discards almost all of
+  // this data (bug 1328975). Furthermore, reading some of the
+  // printer/printing settings from the OS causes a connection to the
+  // printer to be made which is blocked by sandboxing and results in hangs.
   if (aWBP) {
     // When serializing an nsIWebBrowserPrint, we need to pass up the first
     // document name. We could pass up the entire collection of document
     // names, but the OS X printing prompt code only really cares about
     // the first one, so we just send the first to save IPC traffic.
     char16_t** docTitles;
     uint32_t titleCount;
-    rv = aWBP->EnumerateDocumentNames(&titleCount, &docTitles);
+    nsresult rv = aWBP->EnumerateDocumentNames(&titleCount, &docTitles);
     if (NS_SUCCEEDED(rv)) {
       if (titleCount > 0) {
         data->printJobName().Assign(docTitles[0]);
       }
 
       for (int32_t i = titleCount - 1; i >= 0; i--) {
         free(docTitles[i]);
       }
       free(docTitles);
       docTitles = nullptr;
     }
   }
 
+  return NS_OK;
+}
+
+nsresult
+nsPrintOptionsX::SerializeToPrintDataParent(nsIPrintSettings* aSettings,
+                                            nsIWebBrowserPrint* aWBP,
+                                            PrintData* data)
+{
   RefPtr<nsPrintSettingsX> settingsX(do_QueryObject(aSettings));
   if (NS_WARN_IF(!settingsX)) {
     return NS_ERROR_FAILURE;
   }
 
   NSPrintInfo* printInfo = settingsX->GetCocoaPrintInfo();
   if (NS_WARN_IF(!printInfo)) {
     return NS_ERROR_FAILURE;
   }
 
-  double adjustedWidth, adjustedHeight;
-  settingsX->GetAdjustedPaperSize(&adjustedWidth, &adjustedHeight);
-  data->adjustedPaperWidth() = adjustedWidth;
-  data->adjustedPaperHeight() = adjustedHeight;
-
   NSDictionary* dict = [printInfo dictionary];
   if (NS_WARN_IF(!dict)) {
     return NS_ERROR_FAILURE;
   }
 
   NSString* printerName = [dict objectForKey: NSPrintPrinterName];
   if (printerName) {
     nsCocoaUtils::GetStringForNSString(printerName, data->printerName());
@@ -151,136 +181,26 @@ NS_IMETHODIMP
 nsPrintOptionsX::DeserializeToPrintSettings(const PrintData& data,
                                             nsIPrintSettings* settings)
 {
   nsresult rv = nsPrintOptions::DeserializeToPrintSettings(data, settings);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
+  if (data.orientation() == nsIPrintSettings::kPortraitOrientation) {
+    settings->SetOrientation(nsIPrintSettings::kPortraitOrientation);
+  } else {
+    settings->SetOrientation(nsIPrintSettings::kLandscapeOrientation);
+  }
+
   RefPtr<nsPrintSettingsX> settingsX(do_QueryObject(settings));
   if (NS_WARN_IF(!settingsX)) {
     return NS_ERROR_FAILURE;
   }
-
-  NSPrintInfo* sharedPrintInfo = [NSPrintInfo sharedPrintInfo];
-  if (NS_WARN_IF(!sharedPrintInfo)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  NSDictionary* sharedDict = [sharedPrintInfo dictionary];
-  if (NS_WARN_IF(!sharedDict)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // We need to create a new NSMutableDictionary to pass to NSPrintInfo with
-  // the values that we got from the other process.
-  NSMutableDictionary* newPrintInfoDict =
-    [NSMutableDictionary dictionaryWithDictionary:sharedDict];
-  if (NS_WARN_IF(!newPrintInfoDict)) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  NSString* printerName = nsCocoaUtils::ToNSString(data.printerName());
-  if (printerName) {
-    NSPrinter* printer = [NSPrinter printerWithName: printerName];
-    if (printer) {
-      [newPrintInfoDict setObject: printer forKey: NSPrintPrinter];
-      [newPrintInfoDict setObject: printerName forKey: NSPrintPrinterName];
-    }
-  }
-
-  [newPrintInfoDict setObject: [NSNumber numberWithInt: data.numCopies()]
-                    forKey: NSPrintCopies];
-  [newPrintInfoDict setObject: [NSNumber numberWithBool: data.printAllPages()]
-                    forKey: NSPrintAllPages];
-  [newPrintInfoDict setObject: [NSNumber numberWithInt: data.startPageRange()]
-                    forKey: NSPrintFirstPage];
-  [newPrintInfoDict setObject: [NSNumber numberWithInt: data.endPageRange()]
-                    forKey: NSPrintLastPage];
-  [newPrintInfoDict setObject: [NSNumber numberWithBool: data.mustCollate()]
-                    forKey: NSPrintMustCollate];
-  [newPrintInfoDict setObject: [NSNumber numberWithBool: data.printReversed()]
-                    forKey: NSPrintReversePageOrder];
-
-  [newPrintInfoDict setObject: nsCocoaUtils::ToNSString(data.disposition())
-                    forKey: NSPrintJobDisposition];
-
-  [newPrintInfoDict setObject: nsCocoaUtils::ToNSString(data.paperName())
-                    forKey: NSPrintPaperName];
-
-  [newPrintInfoDict setObject: [NSNumber numberWithFloat: data.scalingFactor()]
-                    forKey: NSPrintScalingFactor];
-
-  CGFloat width = data.paperWidth() * data.widthScale();
-  CGFloat height = data.paperHeight() * data.heightScale();
-  [newPrintInfoDict setObject: [NSValue valueWithSize:NSMakeSize(width,height)]
-                    forKey: NSPrintPaperSize];
-
-  int paperOrientation;
-  if (data.orientation() == nsIPrintSettings::kPortraitOrientation) {
-    paperOrientation = NS_PAPER_ORIENTATION_PORTRAIT;
-    settings->SetOrientation(nsIPrintSettings::kPortraitOrientation);
-  } else {
-    paperOrientation = NS_PAPER_ORIENTATION_LANDSCAPE;
-    settings->SetOrientation(nsIPrintSettings::kLandscapeOrientation);
-  }
-  [newPrintInfoDict setObject: [NSNumber numberWithInt:paperOrientation]
-                    forKey: NSPrintOrientation];
-
-  [newPrintInfoDict setObject: [NSNumber numberWithShort: data.pagesAcross()]
-                    forKey: NSPrintPagesAcross];
-  [newPrintInfoDict setObject: [NSNumber numberWithShort: data.pagesDown()]
-                    forKey: NSPrintPagesDown];
-  [newPrintInfoDict setObject: [NSNumber numberWithBool: data.detailedErrorReporting()]
-                    forKey: NSPrintDetailedErrorReporting];
-  [newPrintInfoDict setObject: nsCocoaUtils::ToNSString(data.faxNumber())
-                    forKey: NSPrintFaxNumber];
-  [newPrintInfoDict setObject: [NSNumber numberWithBool: data.addHeaderAndFooter()]
-                    forKey: NSPrintHeaderAndFooter];
-  [newPrintInfoDict setObject: [NSNumber numberWithBool: data.fileNameExtensionHidden()]
-                    forKey: NSPrintJobSavingFileNameExtensionHidden];
-
-  // At this point, the base class should have properly deserialized the print
-  // options bitfield for nsIPrintSettings, so that it holds the correct value
-  // for kEnableSelectionRB, which we use to set NSPrintSelectionOnly.
-
-  bool printSelectionOnly = false;
-  rv = settings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &printSelectionOnly);
-  if (NS_SUCCEEDED(rv)) {
-    [newPrintInfoDict setObject: [NSNumber numberWithBool: printSelectionOnly]
-                      forKey: NSPrintSelectionOnly];
-  } else {
-    [newPrintInfoDict setObject: [NSNumber numberWithBool: NO]
-                      forKey: NSPrintSelectionOnly];
-  }
-
-  NSURL* jobSavingURL =
-    [NSURL URLWithString: nsCocoaUtils::ToNSString(data.toFileName())];
-  if (jobSavingURL) {
-    [newPrintInfoDict setObject: jobSavingURL forKey: NSPrintJobSavingURL];
-  }
-
-  NSTimeInterval timestamp = data.printTime();
-  NSDate* printTime = [NSDate dateWithTimeIntervalSinceReferenceDate: timestamp];
-  if (printTime) {
-    [newPrintInfoDict setObject: printTime forKey: NSPrintTime];
-  }
-
-  // Next, we create a new NSPrintInfo with the values in our dictionary.
-  NSPrintInfo* newPrintInfo =
-    [[NSPrintInfo alloc] initWithDictionary: newPrintInfoDict];
-  if (NS_WARN_IF(!newPrintInfo)) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  // And now swap in the new NSPrintInfo we've just populated.
-  settingsX->SetCocoaPrintInfo(newPrintInfo);
-  [newPrintInfo release];
-
   settingsX->SetAdjustedPaperSize(data.adjustedPaperWidth(),
                                   data.adjustedPaperHeight());
 
   return NS_OK;
 }
 
 nsresult
 nsPrintOptionsX::ReadPrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName, uint32_t aFlags)
--- a/widget/cocoa/nsPrintSettingsX.mm
+++ b/widget/cocoa/nsPrintSettingsX.mm
@@ -289,43 +289,57 @@ void nsPrintSettingsX::GetAdjustedPaperS
   *aHeight = mAdjustedPaperHeight;
 }
 
 NS_IMETHODIMP
 nsPrintSettingsX::SetScaling(double aScaling)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
-  NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
-  [printInfoDict setObject: [NSNumber numberWithFloat: aScaling]
-   forKey: NSPrintScalingFactor];
-  NSPrintInfo* newPrintInfo =
-      [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
-  if (NS_WARN_IF(!newPrintInfo)) {
-    return NS_ERROR_OUT_OF_MEMORY;
+  // Only use NSPrintInfo data in the parent process. The
+  // child process' instance is not needed or used.
+  if (XRE_IsParentProcess()) {
+    NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
+    [printInfoDict setObject: [NSNumber numberWithFloat: aScaling]
+     forKey: NSPrintScalingFactor];
+    NSPrintInfo* newPrintInfo =
+        [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
+    if (NS_WARN_IF(!newPrintInfo)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    SetCocoaPrintInfo(newPrintInfo);
+    [newPrintInfo release];
+  } else {
+    nsPrintSettings::SetScaling(aScaling);
   }
 
-  SetCocoaPrintInfo(newPrintInfo);
-  [newPrintInfo release];
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 NS_IMETHODIMP
 nsPrintSettingsX::GetScaling(double *aScaling)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
-  NSDictionary* printInfoDict = [mPrintInfo dictionary];
+  // Only use NSPrintInfo data in the parent process. The
+  // child process' instance is not needed or used.
+  if (XRE_IsParentProcess()) {
+    NSDictionary* printInfoDict = [mPrintInfo dictionary];
 
-  *aScaling = [[printInfoDict objectForKey: NSPrintScalingFactor] doubleValue];
+    *aScaling =
+      [[printInfoDict objectForKey: NSPrintScalingFactor] doubleValue];
 
-  // Limit scaling precision to whole number percent values
-  *aScaling = round(*aScaling * 100.0) / 100.0;
+    // Limit scaling precision to whole number percent values
+    *aScaling = round(*aScaling * 100.0) / 100.0;
+  } else {
+    nsPrintSettings::GetScaling(aScaling);
+  }
 
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 NS_IMETHODIMP
 nsPrintSettingsX::SetToFileName(const nsAString& aToFileName)
@@ -364,133 +378,171 @@ nsPrintSettingsX::SetToFileName(const ns
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 NS_IMETHODIMP
 nsPrintSettingsX::GetOrientation(int32_t *aOrientation)
 {
-  if ([mPrintInfo orientation] == NS_PAPER_ORIENTATION_PORTRAIT) {
-    *aOrientation = nsIPrintSettings::kPortraitOrientation;
+  // Only use NSPrintInfo data in the parent process. The
+  // child process' instance is not needed or used.
+  if (XRE_IsParentProcess()) {
+    if ([mPrintInfo orientation] == NS_PAPER_ORIENTATION_PORTRAIT) {
+      *aOrientation = nsIPrintSettings::kPortraitOrientation;
+    } else {
+      *aOrientation = nsIPrintSettings::kLandscapeOrientation;
+    }
   } else {
-    *aOrientation = nsIPrintSettings::kLandscapeOrientation;
+    nsPrintSettings::GetOrientation(aOrientation);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPrintSettingsX::SetOrientation(int32_t aOrientation)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
-  NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
-  if (aOrientation == nsIPrintSettings::kPortraitOrientation) {
-    [printInfoDict setObject: [NSNumber numberWithInt: NS_PAPER_ORIENTATION_PORTRAIT]
-     forKey: NSPrintOrientation];
+  // Only use NSPrintInfo data in the parent process. The
+  // child process' instance is not needed or used.
+  if (XRE_IsParentProcess()) {
+    NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
+    if (aOrientation == nsIPrintSettings::kPortraitOrientation) {
+      [printInfoDict setObject: [NSNumber numberWithInt: NS_PAPER_ORIENTATION_PORTRAIT]
+       forKey: NSPrintOrientation];
+    } else {
+      [printInfoDict setObject: [NSNumber numberWithInt: NS_PAPER_ORIENTATION_LANDSCAPE]
+       forKey: NSPrintOrientation];
+    }
+    NSPrintInfo* newPrintInfo =
+        [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
+    if (NS_WARN_IF(!newPrintInfo)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    SetCocoaPrintInfo(newPrintInfo);
+    [newPrintInfo release];
   } else {
-    [printInfoDict setObject: [NSNumber numberWithInt: NS_PAPER_ORIENTATION_LANDSCAPE]
-     forKey: NSPrintOrientation];
-  }
-  NSPrintInfo* newPrintInfo =
-      [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
-  if (NS_WARN_IF(!newPrintInfo)) {
-    return NS_ERROR_OUT_OF_MEMORY;
+    nsPrintSettings::SetOrientation(aOrientation);
   }
 
-  SetCocoaPrintInfo(newPrintInfo);
-  [newPrintInfo release];
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 NS_IMETHODIMP
 nsPrintSettingsX::SetUnwriteableMarginTop(double aUnwriteableMarginTop)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   nsPrintSettings::SetUnwriteableMarginTop(aUnwriteableMarginTop);
-  NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
-  [printInfoDict setObject : [NSNumber numberWithDouble: aUnwriteableMarginTop]
-   forKey : NSPrintTopMargin];
-  NSPrintInfo* newPrintInfo =
-      [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
-  if (NS_WARN_IF(!newPrintInfo)) {
-    return NS_ERROR_OUT_OF_MEMORY;
+
+  // Only use NSPrintInfo data in the parent process. The
+  // child process' instance is not needed or used.
+  if (XRE_IsParentProcess()) {
+    NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
+    [printInfoDict setObject :
+        [NSNumber numberWithDouble: aUnwriteableMarginTop]
+        forKey : NSPrintTopMargin];
+    NSPrintInfo* newPrintInfo =
+        [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
+    if (NS_WARN_IF(!newPrintInfo)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    SetCocoaPrintInfo(newPrintInfo);
+    [newPrintInfo release];
   }
 
-  SetCocoaPrintInfo(newPrintInfo);
-  [newPrintInfo release];
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 NS_IMETHODIMP
 nsPrintSettingsX::SetUnwriteableMarginLeft(double aUnwriteableMarginLeft)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   nsPrintSettings::SetUnwriteableMarginLeft(aUnwriteableMarginLeft);
-  NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
-  [printInfoDict setObject : [NSNumber numberWithDouble: aUnwriteableMarginLeft]
-   forKey : NSPrintLeftMargin];
-  NSPrintInfo* newPrintInfo =
-      [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
-  if (NS_WARN_IF(!newPrintInfo)) {
-    return NS_ERROR_OUT_OF_MEMORY;
+
+  // Only use NSPrintInfo data in the parent process. The
+  // child process' instance is not needed or used.
+  if (XRE_IsParentProcess()) {
+    NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
+    [printInfoDict setObject : [NSNumber numberWithDouble: aUnwriteableMarginLeft]
+     forKey : NSPrintLeftMargin];
+    NSPrintInfo* newPrintInfo =
+        [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
+    if (NS_WARN_IF(!newPrintInfo)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    SetCocoaPrintInfo(newPrintInfo);
+    [newPrintInfo release];
   }
 
-  SetCocoaPrintInfo(newPrintInfo);
-  [newPrintInfo release];
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 NS_IMETHODIMP
 nsPrintSettingsX::SetUnwriteableMarginBottom(double aUnwriteableMarginBottom)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   nsPrintSettings::SetUnwriteableMarginBottom(aUnwriteableMarginBottom);
-  NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
-  [printInfoDict setObject : [NSNumber numberWithDouble: aUnwriteableMarginBottom]
-   forKey : NSPrintBottomMargin];
-  NSPrintInfo* newPrintInfo =
-      [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
-  if (NS_WARN_IF(!newPrintInfo)) {
-    return NS_ERROR_OUT_OF_MEMORY;
+
+  // Only use NSPrintInfo data in the parent process. The
+  // child process' instance is not needed or used.
+  if (XRE_IsParentProcess()) {
+    NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
+    [printInfoDict setObject : [NSNumber numberWithDouble: aUnwriteableMarginBottom]
+     forKey : NSPrintBottomMargin];
+    NSPrintInfo* newPrintInfo =
+        [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
+    if (NS_WARN_IF(!newPrintInfo)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    SetCocoaPrintInfo(newPrintInfo);
+    [newPrintInfo release];
   }
 
-  SetCocoaPrintInfo(newPrintInfo);
-  [newPrintInfo release];
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 NS_IMETHODIMP
 nsPrintSettingsX::SetUnwriteableMarginRight(double aUnwriteableMarginRight)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   nsPrintSettings::SetUnwriteableMarginRight(aUnwriteableMarginRight);
-  NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
-  [printInfoDict setObject : [NSNumber numberWithDouble: aUnwriteableMarginRight]
-   forKey : NSPrintRightMargin];
-  NSPrintInfo* newPrintInfo =
-      [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
-  if (NS_WARN_IF(!newPrintInfo)) {
-    return NS_ERROR_OUT_OF_MEMORY;
+
+  // Only use NSPrintInfo data in the parent process. The
+  // child process' instance is not needed or used.
+  if (XRE_IsParentProcess()) {
+    NSMutableDictionary* printInfoDict = [mPrintInfo dictionary];
+    [printInfoDict setObject : [NSNumber numberWithDouble: aUnwriteableMarginRight]
+     forKey : NSPrintRightMargin];
+    NSPrintInfo* newPrintInfo =
+        [[NSPrintInfo alloc] initWithDictionary: printInfoDict];
+    if (NS_WARN_IF(!newPrintInfo)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    SetCocoaPrintInfo(newPrintInfo);
+    [newPrintInfo release];
   }
 
-  SetCocoaPrintInfo(newPrintInfo);
-  [newPrintInfo release];
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 int
 nsPrintSettingsX::GetCocoaUnit(int16_t aGeckoUnit)
 {