summaryrefslogtreecommitdiffstats
path: root/security/sandbox/test/browser_content_sandbox_fs.js
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/test/browser_content_sandbox_fs.js')
-rw-r--r--security/sandbox/test/browser_content_sandbox_fs.js169
1 files changed, 169 insertions, 0 deletions
diff --git a/security/sandbox/test/browser_content_sandbox_fs.js b/security/sandbox/test/browser_content_sandbox_fs.js
new file mode 100644
index 000000000..946f86bb9
--- /dev/null
+++ b/security/sandbox/test/browser_content_sandbox_fs.js
@@ -0,0 +1,169 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var prefs = Cc["@mozilla.org/preferences-service;1"]
+ .getService(Ci.nsIPrefBranch);
+
+Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/" +
+ "security/sandbox/test/browser_content_sandbox_utils.js", this);
+
+/*
+ * This test exercises file I/O from the content process using OS.File
+ * methods to validate that calls that are meant to be blocked by content
+ * sandboxing are blocked.
+ */
+
+// Creates file at |path| and returns a promise that resolves with true
+// if the file was successfully created, otherwise false. Include imports
+// so this can be safely serialized and run remotely by ContentTask.spawn.
+function createFile(path) {
+ Components.utils.import("resource://gre/modules/osfile.jsm");
+ let encoder = new TextEncoder();
+ let array = encoder.encode("WRITING FROM CONTENT PROCESS");
+ return OS.File.writeAtomic(path, array).then(function(value) {
+ return true;
+ }, function(reason) {
+ return false;
+ });
+}
+
+// Deletes file at |path| and returns a promise that resolves with true
+// if the file was successfully deleted, otherwise false. Include imports
+// so this can be safely serialized and run remotely by ContentTask.spawn.
+function deleteFile(path) {
+ Components.utils.import("resource://gre/modules/osfile.jsm");
+ return OS.File.remove(path, {ignoreAbsent: false}).then(function(value) {
+ return true;
+ }).catch(function(err) {
+ return false;
+ });
+}
+
+// Returns true if the current content sandbox level, passed in
+// the |level| argument, supports filesystem sandboxing.
+function isContentFileIOSandboxed(level) {
+ let fileIOSandboxMinLevel = 0;
+
+ // Set fileIOSandboxMinLevel to the lowest level that has
+ // content filesystem sandboxing enabled. For now, this
+ // varies across Windows, Mac, Linux, other.
+ switch (Services.appinfo.OS) {
+ case "WINNT":
+ fileIOSandboxMinLevel = 1;
+ break;
+ case "Darwin":
+ fileIOSandboxMinLevel = 1;
+ break;
+ case "Linux":
+ fileIOSandboxMinLevel = 2;
+ break;
+ default:
+ Assert.ok(false, "Unknown OS");
+ }
+
+ return (level >= fileIOSandboxMinLevel);
+}
+
+//
+// Drive tests for a single content process.
+//
+// Tests attempting to write to a file in the home directory from the
+// content process--expected to fail.
+//
+// Tests attempting to write to a file in the content temp directory
+// from the content process--expected to succeed. On Mac and Windows,
+// use "ContentTmpD", but on Linux use "TmpD" until Linux uses the
+// content temp dir key.
+//
+add_task(function*() {
+ // This test is only relevant in e10s
+ if (!gMultiProcessBrowser) {
+ ok(false, "e10s is enabled");
+ info("e10s is not enabled, exiting");
+ return;
+ }
+
+ let level = 0;
+ let prefExists = true;
+
+ // Read the security.sandbox.content.level pref.
+ // If the pref isn't set and we're running on Linux on !isNightly(),
+ // exit without failing. The Linux content sandbox is only enabled
+ // on Nightly at this time.
+ try {
+ level = prefs.getIntPref("security.sandbox.content.level");
+ } catch (e) {
+ prefExists = false;
+ }
+
+ // Special case Linux on !isNightly
+ if (isLinux() && !isNightly()) {
+ todo(prefExists, "pref security.sandbox.content.level exists");
+ if (!prefExists) {
+ return;
+ }
+ }
+
+ ok(prefExists, "pref security.sandbox.content.level exists");
+ if (!prefExists) {
+ return;
+ }
+
+ // Special case Linux on !isNightly
+ if (isLinux() && !isNightly()) {
+ todo(level > 0, "content sandbox enabled for !nightly.");
+ return;
+ }
+
+ info(`security.sandbox.content.level=${level}`);
+ ok(level > 0, "content sandbox is enabled.");
+ if (level == 0) {
+ info("content sandbox is not enabled, exiting");
+ return;
+ }
+
+ let isFileIOSandboxed = isContentFileIOSandboxed(level);
+
+ // Special case Linux on !isNightly
+ if (isLinux() && !isNightly()) {
+ todo(isFileIOSandboxed, "content file I/O sandbox enabled for !nightly.");
+ return;
+ }
+
+ // Content sandbox enabled, but level doesn't include file I/O sandboxing.
+ ok(isFileIOSandboxed, "content file I/O sandboxing is enabled.");
+ if (!isFileIOSandboxed) {
+ info("content sandbox level too low for file I/O tests, exiting\n");
+ return;
+ }
+
+ let browser = gBrowser.selectedBrowser;
+
+ {
+ // test if the content process can create in $HOME, this should fail
+ let homeFile = fileInHomeDir();
+ let path = homeFile.path;
+ let fileCreated = yield ContentTask.spawn(browser, path, createFile);
+ ok(fileCreated == false, "creating a file in home dir is not permitted");
+ if (fileCreated == true) {
+ // content process successfully created the file, now remove it
+ homeFile.remove(false);
+ }
+ }
+
+ {
+ // test if the content process can create a temp file, should pass
+ let path = fileInTempDir().path;
+ let fileCreated = yield ContentTask.spawn(browser, path, createFile);
+ if (!fileCreated && isWin()) {
+ // TODO: fix 1329294 and enable this test for Windows.
+ // Not using todo() because this only fails on automation.
+ info("ignoring failure to write to content temp due to 1329294\n");
+ return;
+ }
+ ok(fileCreated == true, "creating a file in content temp is permitted");
+ // now delete the file
+ let fileDeleted = yield ContentTask.spawn(browser, path, deleteFile);
+ ok(fileDeleted == true, "deleting a file in content temp is permitted");
+ }
+});