diff --git a/README.md b/README.md index f2655b75a..af0a6a3ca 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,8 @@ Zen is a firefox-based browser with the aim of pushing your productivity to a ne ### Firefox Versions -- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `151.0.3`! 🚀 -- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 151.0.3`! +- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `151.0.4`! 🚀 +- [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 151.0.4`! ### Contributing diff --git a/build/firefox-cache/l10n-last-commit-hash b/build/firefox-cache/l10n-last-commit-hash index dce1749c7..f138bc25d 100644 --- a/build/firefox-cache/l10n-last-commit-hash +++ b/build/firefox-cache/l10n-last-commit-hash @@ -1 +1 @@ -5c4d14a559bf26eb4ab3e136d2084310ebe51ac0 \ No newline at end of file +9a6aa4c359d1fb6ac60decc82402f82d49a17cea \ No newline at end of file diff --git a/src/zen/tests/manifest.toml b/src/zen/tests/manifest.toml index fa3d7c84f..c3f444157 100644 --- a/src/zen/tests/manifest.toml +++ b/src/zen/tests/manifest.toml @@ -17,16 +17,6 @@ disable = [ source = "browser/components/safebrowsing/content/test" is_direct_path = true -[sandbox] -source = "security/sandbox/test" -is_direct_path = true -disable = [ - "browser_bug1393259.js", -] - -[sandbox.replace-manifest] -"../../../" = "../../../../" - [shell] source = "browser/components/shell/test" is_direct_path = true diff --git a/src/zen/tests/mochitests/moz.build b/src/zen/tests/mochitests/moz.build index 9aed50afd..bbf85269c 100644 --- a/src/zen/tests/mochitests/moz.build +++ b/src/zen/tests/mochitests/moz.build @@ -10,7 +10,6 @@ BROWSER_CHROME_MANIFESTS += [ "readermode/browser.toml", "safebrowsing/browser.toml", - "sandbox/browser.toml", "shell/browser.toml", "tabMediaIndicator/browser.toml", "tooltiptext/browser.toml", diff --git a/src/zen/tests/mochitests/sandbox/browser.toml b/src/zen/tests/mochitests/sandbox/browser.toml deleted file mode 100644 index f12d053b9..000000000 --- a/src/zen/tests/mochitests/sandbox/browser.toml +++ /dev/null @@ -1,44 +0,0 @@ -[DEFAULT] -skip-if = [ - "ccov", - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && asan", # bug 1784517 - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && tsan", # bug 1784517 -] -tags = "contentsandbox" -support-files = [ - "browser_content_sandbox_utils.js", - "browser_content_sandbox_fs_tests.js", - "mac_register_font.py", - "../../../../layout/reftests/fonts/fira/FiraSans-Regular.otf" -] - -["browser_bug1393259.js"] -disabled="Disabled by import_external_tests.py" -support-files = ["bug1393259.html"] -run-if = [ - "os == 'mac'", # This is a Mac-specific test -] -skip-if = [ - "os == 'mac' && os_version == '14.70' && arch == 'x86_64'", # Bug 1929424 -] -tags = "os_integration" - -["browser_content_sandbox_fs.js"] -skip-if = [ - "os == 'mac' && os_version == '15.30' && arch == 'aarch64'", # Bug 2023967 - "os == 'win' && os_version == '11.26100' && arch == 'x86' && debug", # bug 1379635 - "os == 'win' && os_version == '11.26100' && arch == 'x86_64' && debug", # bug 1379635 - "os == 'win' && os_version == '11.26200' && arch == 'x86' && debug", # bug 1379635 - "os == 'win' && os_version == '11.26200' && arch == 'x86_64' && debug", # bug 1379635 -] - -["browser_content_sandbox_syscalls.js"] - -["browser_sandbox_test.js"] -skip-if = [ - "os == 'win' && os_version == '11.26200' && arch == 'x86' && debug", # bug 2028636 - "os == 'win' && os_version == '11.26200' && arch == 'x86_64' && debug", # bug 2028636 -] -run-if = [ - "debug", -] diff --git a/src/zen/tests/mochitests/sandbox/browser_bug1393259.js b/src/zen/tests/mochitests/sandbox/browser_bug1393259.js deleted file mode 100644 index 8fbeb1b9d..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_bug1393259.js +++ /dev/null @@ -1,203 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -/* - * This test validates that an OTF font installed in a directory not - * accessible to content processes is rendered correctly by checking that - * content displayed never uses the OS fallback font "LastResort". When - * a content process renders a page with the fallback font, that is an - * indication the content process failed to read or load the computed font. - * The test uses a version of the Fira Sans font and depends on the font - * not being already installed and enabled. - */ - -const kPageURL = - "http://example.com/browser/security/sandbox/test/bug1393259.html"; - -// Parameters for running the python script that registers/unregisters fonts. -let kPythonPath = "/usr/bin/python"; -if (AppConstants.isPlatformAndVersionAtLeast("macosx", 23.0)) { - kPythonPath = "/usr/local/bin/python3"; -} -const kFontInstallerPath = "browser/security/sandbox/test/mac_register_font.py"; -const kUninstallFlag = "-u"; -const kVerboseFlag = "-v"; - -// Where to find the font in the test environment. -const kRepoFontPath = "browser/security/sandbox/test/FiraSans-Regular.otf"; - -// Font name strings to check for. -const kLastResortFontName = "LastResort"; -const kTestFontName = "Fira Sans"; - -// Home-relative path to install a private font. Where a private font is -// a font at a location not readable by content processes. -const kPrivateFontSubPath = "/FiraSans-Regular.otf"; - -add_task(async function () { - await new Promise(resolve => waitForFocus(resolve, window)); - - await BrowserTestUtils.withNewTab( - { - gBrowser, - url: kPageURL, - }, - async function (aBrowser) { - function runProcess(aCmd, aArgs, blocking = true) { - let cmdFile = Cc["@mozilla.org/file/local;1"].createInstance( - Ci.nsIFile - ); - cmdFile.initWithPath(aCmd); - - let process = Cc["@mozilla.org/process/util;1"].createInstance( - Ci.nsIProcess - ); - process.init(cmdFile); - process.run(blocking, aArgs, aArgs.length); - return process.exitValue; - } - - // Register the font at path |fontPath| and wait - // for the browser to detect the change. - async function registerFont(fontPath) { - let fontRegistered = getFontNotificationPromise(); - let exitCode = runProcess(kPythonPath, [ - kFontInstallerPath, - kVerboseFlag, - fontPath, - ]); - Assert.equal(exitCode, 0, "registering font" + fontPath); - if (exitCode == 0) { - // Wait for the font registration to be detected by the browser. - await fontRegistered; - } - } - - // Unregister the font at path |fontPath|. If |waitForUnreg| is true, - // don't wait for the browser to detect the change and don't use - // the verbose arg for the unregister command. - async function unregisterFont(fontPath, waitForUnreg = true) { - let args = [kFontInstallerPath, kUninstallFlag]; - let fontUnregistered; - - if (waitForUnreg) { - args.push(kVerboseFlag); - fontUnregistered = getFontNotificationPromise(); - } - - let exitCode = runProcess(kPythonPath, args.concat(fontPath)); - if (waitForUnreg) { - Assert.equal(exitCode, 0, "unregistering font" + fontPath); - if (exitCode == 0) { - await fontUnregistered; - } - } - } - - // Returns a promise that resolves when font info is changed. - let getFontNotificationPromise = () => - new Promise(resolve => { - const kTopic = "font-info-updated"; - function observe() { - Services.obs.removeObserver(observe, kTopic); - resolve(); - } - - Services.obs.addObserver(observe, kTopic); - }); - - let homeDir = Services.dirsvc.get("Home", Ci.nsIFile); - let privateFontPath = homeDir.path + kPrivateFontSubPath; - - registerCleanupFunction(function () { - unregisterFont(privateFontPath, /* waitForUnreg = */ false); - runProcess("/bin/rm", [privateFontPath], /* blocking = */ false); - }); - - // Copy the font file to the private path. - runProcess("/bin/cp", [kRepoFontPath, privateFontPath]); - - // Cleanup previous aborted tests. - unregisterFont(privateFontPath, /* waitForUnreg = */ false); - - // Get the original width, using the fallback monospaced font - let origWidth = await SpecialPowers.spawn( - aBrowser, - [], - async function () { - let window = content.window.wrappedJSObject; - let contentDiv = window.document.getElementById("content"); - return contentDiv.offsetWidth; - } - ); - - // Activate the font we want to test at a non-standard path. - await registerFont(privateFontPath); - - // Assign the new font to the content. - await SpecialPowers.spawn(aBrowser, [], async function () { - let window = content.window.wrappedJSObject; - let contentDiv = window.document.getElementById("content"); - contentDiv.style.fontFamily = "'Fira Sans', monospace"; - }); - - // Wait until the width has changed, indicating the content process - // has recognized the newly-activated font. - while (true) { - let width = await SpecialPowers.spawn(aBrowser, [], async function () { - let window = content.window.wrappedJSObject; - let contentDiv = window.document.getElementById("content"); - return contentDiv.offsetWidth; - }); - if (width != origWidth) { - break; - } - // If the content wasn't ready yet, wait a little before re-checking. - // eslint-disable-next-line mozilla/no-arbitrary-setTimeout - await new Promise(c => setTimeout(c, 100)); - } - - // Get a list of fonts now being used to display the web content. - let fontList = await SpecialPowers.spawn(aBrowser, [], async function () { - let window = content.window.wrappedJSObject; - let range = window.document.createRange(); - let contentDiv = window.document.getElementById("content"); - range.selectNode(contentDiv); - let fonts = InspectorUtils.getUsedFontFaces(range); - - let fontList = []; - for (let i = 0; i < fonts.length; i++) { - fontList.push({ name: fonts[i].name }); - } - return fontList; - }); - - let lastResortFontUsed = false; - let testFontUsed = false; - - for (let font of fontList) { - // Did we fall back to the "LastResort" font? - if (!lastResortFontUsed && font.name.includes(kLastResortFontName)) { - lastResortFontUsed = true; - continue; - } - // Did we render using our test font as expected? - if (!testFontUsed && font.name.includes(kTestFontName)) { - testFontUsed = true; - continue; - } - } - - Assert.ok( - !lastResortFontUsed, - `The ${kLastResortFontName} fallback font was not used` - ); - - Assert.ok(testFontUsed, `The test font "${kTestFontName}" was used`); - - await unregisterFont(privateFontPath); - } - ); -}); diff --git a/src/zen/tests/mochitests/sandbox/browser_bug1717599_XDG-CONFIG-DIRS.toml b/src/zen/tests/mochitests/sandbox/browser_bug1717599_XDG-CONFIG-DIRS.toml deleted file mode 100644 index 6a16ad95c..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_bug1717599_XDG-CONFIG-DIRS.toml +++ /dev/null @@ -1,15 +0,0 @@ -# Any copyright is dedicated to the Public Domain. -# http://creativecommons.org/publicdomain/zero/1.0/ -[DEFAULT] -skip-if = [ - "ccov", - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && asan", # bug 1784517 - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && tsan", # bug 1784517 -] -tags = "contentsandbox" -environment = "XDG_CONFIG_DIRS=:/opt" - -["browser_content_sandbox_bug1717599_XDG-CONFIG-DIRS.js"] -run-if = [ - "os == 'linux'", -] diff --git a/src/zen/tests/mochitests/sandbox/browser_bug1717599_XDG-CONFIG-HOME.toml b/src/zen/tests/mochitests/sandbox/browser_bug1717599_XDG-CONFIG-HOME.toml deleted file mode 100644 index 7d524f137..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_bug1717599_XDG-CONFIG-HOME.toml +++ /dev/null @@ -1,13 +0,0 @@ -[DEFAULT] -skip-if = [ - "ccov", - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && asan", # bug 1784517 - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && tsan", # bug 1784517 -] -tags = "contentsandbox" -environment = "XDG_CONFIG_HOME=" - -["browser_content_sandbox_bug1717599_XDG-CONFIG-HOME.js"] -run-if = [ - "os == 'linux'", -] diff --git a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_bug1717599_XDG-CONFIG-DIRS.js b/src/zen/tests/mochitests/sandbox/browser_content_sandbox_bug1717599_XDG-CONFIG-DIRS.js deleted file mode 100644 index e45c0cb07..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_bug1717599_XDG-CONFIG-DIRS.js +++ /dev/null @@ -1,11 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -/* import-globals-from browser_content_sandbox_utils.js */ -"use strict"; - -// -// Just test that browser does not die on empty env var -// -add_task(async function () { - ok(true, "Process can run"); -}); diff --git a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_bug1717599_XDG-CONFIG-HOME.js b/src/zen/tests/mochitests/sandbox/browser_content_sandbox_bug1717599_XDG-CONFIG-HOME.js deleted file mode 100644 index e45c0cb07..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_bug1717599_XDG-CONFIG-HOME.js +++ /dev/null @@ -1,11 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -/* import-globals-from browser_content_sandbox_utils.js */ -"use strict"; - -// -// Just test that browser does not die on empty env var -// -add_task(async function () { - ok(true, "Process can run"); -}); diff --git a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs.js b/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs.js deleted file mode 100644 index cff7a872f..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs.js +++ /dev/null @@ -1,56 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -/* import-globals-from browser_content_sandbox_utils.js */ -"use strict"; - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "security/sandbox/test/browser_content_sandbox_utils.js", - this -); - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "security/sandbox/test/browser_content_sandbox_fs_tests.js", - this -); - -/* - * This test exercises file I/O from web and file content processes using - * nsIFile etc. methods to validate that calls that are meant to be blocked by - * content sandboxing are blocked. - */ - -// -// Checks that sandboxing is enabled and at the appropriate level -// setting before triggering tests that do the file I/O. -// -// 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. Uses "ContentTmpD". -// -// Tests reading various files and directories from file and web -// content processes. -// -add_task(async function () { - sanityChecks(); - - // Test creating a file in the home directory from a web content process - add_task(createFileInHome); // eslint-disable-line no-undef - - // Test creating a file content temp from a web content process - add_task(createTempFile); // eslint-disable-line no-undef - - // Test reading files/dirs from web and file content processes - add_task(testFileAccessAllPlatforms); // eslint-disable-line no-undef - - add_task(testFileAccessMacOnly); // eslint-disable-line no-undef - - add_task(testFileAccessLinuxOnly); // eslint-disable-line no-undef - - add_task(testFileAccessWindowsOnly); // eslint-disable-line no-undef - - add_task(cleanupBrowserTabs); // eslint-disable-line no-undef -}); diff --git a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_snap.js b/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_snap.js deleted file mode 100644 index 06f04c1d3..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_snap.js +++ /dev/null @@ -1,31 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -/* import-globals-from browser_content_sandbox_utils.js */ -"use strict"; - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "security/sandbox/test/browser_content_sandbox_utils.js", - this -); - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "security/sandbox/test/browser_content_sandbox_fs_tests.js", - this -); - -add_task(async function () { - // Ensure that SNAP is there - const snap = Services.env.get("SNAP"); - Assert.greater(snap.length, 1, "SNAP is defined"); - - // If it is there, do actual testing - sanityChecks(); - - add_task(testFileAccessLinuxOnly); // eslint-disable-line no-undef - - add_task(testFileAccessLinuxSnap); // eslint-disable-line no-undef - - add_task(cleanupBrowserTabs); // eslint-disable-line no-undef -}); diff --git a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_tests.js b/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_tests.js deleted file mode 100644 index 9e2232f40..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_tests.js +++ /dev/null @@ -1,719 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -/* import-globals-from browser_content_sandbox_utils.js */ -"use strict"; - -const lazy = {}; - -/* getLibcConstants is only present on *nix */ -ChromeUtils.defineLazyGetter(lazy, "LIBC", () => - ChromeUtils.getLibcConstants() -); - -// Test if the content process can create in $HOME, this should fail -async function createFileInHome() { - let browser = gBrowser.selectedBrowser; - let homeFile = fileInHomeDir(); - let path = homeFile.path; - let fileCreated = await SpecialPowers.spawn(browser, [path], createFile); - ok(!fileCreated.ok, "creating a file in home dir failed"); - is( - fileCreated.code, - Cr.NS_ERROR_FILE_ACCESS_DENIED, - "creating a file in home dir failed with access denied" - ); - if (fileCreated.ok) { - // content process successfully created the file, now remove it - homeFile.remove(false); - } -} - -// Test if the content process can create a temp file, this is forbidden on all -// platforms. Also test that the content process cannot create symlinks on -// macOS/Linux or delete files. -async function createTempFile() { - // On Windows we allow access to the temp dir for DEBUG builds, because of - // logging that uses that dir. - let isDbgWin = isWin() && SpecialPowers.isDebugBuild; - - let browser = gBrowser.selectedBrowser; - let path = fileInTempDir().path; - let fileCreated = await SpecialPowers.spawn(browser, [path], createFile); - if (isDbgWin) { - ok(fileCreated.ok, "creating a file in temp suceeded"); - } else { - ok(!fileCreated.ok, "creating a file in temp failed"); - is( - fileCreated.code, - Cr.NS_ERROR_FILE_ACCESS_DENIED, - "creating a file in temp failed with access denied" - ); - } - - // now delete the file - let fileDeleted = await SpecialPowers.spawn(browser, [path], deleteFile); - if (isDbgWin) { - ok(fileDeleted.ok, "deleting a file in temp succeeded"); - } else { - ok(!fileDeleted.ok, "deleting a file in temp failed"); - const expectedError = isLinux() - ? Cr.NS_ERROR_FILE_ACCESS_DENIED - : Cr.NS_ERROR_FILE_NOT_FOUND; - is( - fileDeleted.code, - expectedError, - "deleting a file in temp failed with access denied" - ); - } - - // Test that symlink creation is not allowed on macOS/Linux. - if (isMac() || isLinux()) { - let path = fileInTempDir().path; - let symlinkCreated = await SpecialPowers.spawn( - browser, - [path], - createSymlink - ); - ok(!symlinkCreated.ok, "created a symlink in temp failed"); - const expectedError = isLinux() ? lazy.LIBC.EACCES : lazy.LIBC.EPERM; - is( - symlinkCreated.code, - expectedError, - "created a symlink in temp failed with access denied" - ); - } -} - -// Test reading files and dirs from web and file content processes. -async function testFileAccessAllPlatforms() { - let webBrowser = GetWebBrowser(); - let fileContentProcessEnabled = isFileContentProcessEnabled(); - let fileBrowser = GetFileBrowser(); - - // Directories/files to test accessing from content processes. - // For directories, we test whether a directory listing is allowed - // or blocked. For files, we test if we can read from the file. - // Each entry in the array represents a test file or directory - // that will be read from either a web or file process. - let tests = []; - - let profileDir = GetProfileDir(); - tests.push({ - desc: "profile dir", // description - ok: false, // expected to succeed? - browser: webBrowser, // browser to run test in - file: profileDir, // nsIFile object - minLevel: minProfileReadSandboxLevel(), // min level to enable test - func: readDir, - }); - if (fileContentProcessEnabled) { - tests.push({ - desc: "profile dir", - ok: true, - browser: fileBrowser, - file: profileDir, - minLevel: 0, - func: readDir, - }); - } - - let homeDir = GetHomeDir(); - tests.push({ - desc: "home dir", - ok: false, - browser: webBrowser, - file: homeDir, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - if (fileContentProcessEnabled) { - tests.push({ - desc: "home dir", - ok: true, - browser: fileBrowser, - file: homeDir, - minLevel: 0, - func: readDir, - }); - } - - let extensionsDir = GetProfileEntry("extensions"); - if (extensionsDir.exists() && extensionsDir.isDirectory()) { - tests.push({ - desc: "extensions dir", - ok: true, - browser: webBrowser, - file: extensionsDir, - minLevel: 0, - func: readDir, - }); - } else { - ok(false, `${extensionsDir.path} is a valid dir`); - } - - let chromeDir = GetProfileEntry("chrome"); - if (chromeDir.exists() && chromeDir.isDirectory()) { - tests.push({ - desc: "chrome dir", - ok: true, - browser: webBrowser, - file: chromeDir, - minLevel: 0, - func: readDir, - }); - } else { - ok(false, `${chromeDir.path} is valid dir`); - } - - let cookiesFile = GetProfileEntry("cookies.sqlite"); - if (cookiesFile.exists() && !cookiesFile.isDirectory()) { - tests.push({ - desc: "cookies file", - ok: false, - browser: webBrowser, - file: cookiesFile, - minLevel: minProfileReadSandboxLevel(), - func: readFile, - }); - if (fileContentProcessEnabled) { - tests.push({ - desc: "cookies file", - ok: true, - browser: fileBrowser, - file: cookiesFile, - minLevel: 0, - func: readFile, - }); - } - } else { - ok(false, `${cookiesFile.path} is a valid file`); - } - - if (isMac() || isLinux()) { - let varDir = GetDir("/var"); - - if (isMac()) { - // Mac sandbox rules use /private/var because /var is a symlink - // to /private/var on OS X. Make sure that hasn't changed. - varDir.normalize(); - Assert.strictEqual( - varDir.path, - "/private/var", - "/var resolves to /private/var" - ); - } - - tests.push({ - desc: "/var", - ok: false, - browser: webBrowser, - file: varDir, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - if (fileContentProcessEnabled) { - tests.push({ - desc: "/var", - ok: true, - browser: fileBrowser, - file: varDir, - minLevel: 0, - func: readDir, - }); - } - } - - await runTestsList(tests); -} - -async function testFileAccessMacOnly() { - if (!isMac()) { - return; - } - - let webBrowser = GetWebBrowser(); - let fileContentProcessEnabled = isFileContentProcessEnabled(); - let fileBrowser = GetFileBrowser(); - let level = GetSandboxLevel(); - - let tests = []; - - // If ~/Library/Caches/TemporaryItems exists, when level <= 2 we - // make sure it's readable. For level 3, we make sure it isn't. - let homeTempDir = GetHomeDir(); - homeTempDir.appendRelativePath("Library/Caches/TemporaryItems"); - if (homeTempDir.exists()) { - let shouldBeReadable, minLevel; - if (level >= minHomeReadSandboxLevel()) { - shouldBeReadable = false; - minLevel = minHomeReadSandboxLevel(); - } else { - shouldBeReadable = true; - minLevel = 0; - } - tests.push({ - desc: "home library cache temp dir", - ok: shouldBeReadable, - browser: webBrowser, - file: homeTempDir, - minLevel, - func: readDir, - }); - } - - // Test if we can read from $TMPDIR because we expect it - // to be within /private/var. Reading from it should be - // prevented in a 'web' process. - let macTempDir = GetDirFromEnvVariable("TMPDIR"); - - macTempDir.normalize(); - Assert.ok( - macTempDir.path.startsWith("/private/var"), - "$TMPDIR is in /private/var" - ); - - tests.push({ - desc: `$TMPDIR (${macTempDir.path})`, - ok: false, - browser: webBrowser, - file: macTempDir, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - if (fileContentProcessEnabled) { - tests.push({ - desc: `$TMPDIR (${macTempDir.path})`, - ok: true, - browser: fileBrowser, - file: macTempDir, - minLevel: 0, - func: readDir, - }); - } - - // The font registry directory is in the Darwin user cache dir which is - // accessible with the getconf(1) library call using DARWIN_USER_CACHE_DIR. - // For this test, assume the cache dir is located at $TMPDIR/../C and use - // the $TMPDIR to derive the path to the registry. - let fontRegistryDir = macTempDir.parent.clone(); - fontRegistryDir.appendRelativePath("C/com.apple.FontRegistry"); - if (fontRegistryDir.exists()) { - tests.push({ - desc: `FontRegistry (${fontRegistryDir.path})`, - ok: true, - browser: webBrowser, - file: fontRegistryDir, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - // Check that we can read the file named `font` which typically - // exists in the the font registry directory. - let fontFile = fontRegistryDir.clone(); - fontFile.appendRelativePath("font"); - if (fontFile.exists()) { - tests.push({ - desc: `FontRegistry file (${fontFile.path})`, - ok: true, - browser: webBrowser, - file: fontFile, - minLevel: minHomeReadSandboxLevel(), - func: readFile, - }); - } - } - - // Test that we cannot read from /Volumes at level 3 - let volumes = GetDir("/Volumes"); - tests.push({ - desc: "/Volumes", - ok: false, - browser: webBrowser, - file: volumes, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - - // Test that we cannot read from /Users at level 3 - let users = GetDir("/Users"); - tests.push({ - desc: "/Users", - ok: false, - browser: webBrowser, - file: users, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - - // Test that we can stat /Users at level 3 - tests.push({ - desc: "/Users", - ok: true, - browser: webBrowser, - file: users, - minLevel: minHomeReadSandboxLevel(), - func: statPath, - }); - - // Test that we can stat /Library at level 3, but can't get a - // directory listing of /Library. This test uses "/Library" - // because it's a path that is expected to always be present. - let libraryDir = GetDir("/Library"); - tests.push({ - desc: "/Library", - ok: true, - browser: webBrowser, - file: libraryDir, - minLevel: minHomeReadSandboxLevel(), - func: statPath, - }); - tests.push({ - desc: "/Library", - ok: false, - browser: webBrowser, - file: libraryDir, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - - // Similarly, test that we can stat /private, but not /private/etc. - let privateDir = GetDir("/private"); - tests.push({ - desc: "/private", - ok: true, - browser: webBrowser, - file: privateDir, - minLevel: minHomeReadSandboxLevel(), - func: statPath, - }); - - await runTestsList(tests); -} - -async function testFileAccessLinuxOnly() { - if (!isLinux()) { - return; - } - - let webBrowser = GetWebBrowser(); - let fileContentProcessEnabled = isFileContentProcessEnabled(); - let fileBrowser = GetFileBrowser(); - - let tests = []; - - // Test /proc/self/fd, because that can be used to unfreeze - // frozen shared memory. - let selfFdDir = GetDir("/proc/self/fd"); - tests.push({ - desc: "/proc/self/fd", - ok: false, - browser: webBrowser, - file: selfFdDir, - minLevel: isContentFileIOSandboxed(), - func: readDir, - }); - - let cacheFontConfigDir = GetHomeSubdir(".cache/fontconfig/"); - tests.push({ - desc: `$HOME/.cache/fontconfig/ (${cacheFontConfigDir.path})`, - ok: true, - browser: webBrowser, - file: cacheFontConfigDir, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - - // allows to handle both $HOME/.config/ or $XDG_CONFIG_HOME - let configDir = GetHomeSubdir(".config"); - - const xdgConfigHome = Services.env.get("XDG_CONFIG_HOME"); - if (xdgConfigHome) { - configDir = GetDir(xdgConfigHome); - configDir.normalize(); - } - - tests.push({ - desc: `$XDG_CONFIG_HOME (${configDir.path})`, - ok: true, // access should not be granted outside of XDG support - browser: webBrowser, - file: configDir, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - - tests.push({ - desc: `XDG_CONFIG_HOME=${configDir.path} dir should have rdonly`, - ok: true, // should be allowed only if XDG support is there - browser: webBrowser, - file: configDir, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - - if (fileContentProcessEnabled) { - tests.push({ - desc: `${configDir.path} dir`, - ok: true, // should be allowed only if XDG support is there - browser: fileBrowser, - file: configDir, - minLevel: 0, - func: readDir, - }); - } - - if (isXdgEnabled() && xdgConfigHome) { - const homeConfigDir = GetHomeSubdir(".config"); - tests.push({ - desc: `XDG_CONFIG_HOME=${homeConfigDir.path} dir should deny $HOME/.config`, - ok: false, - browser: webBrowser, - file: homeConfigDir, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - if (fileContentProcessEnabled) { - tests.push({ - desc: `${homeConfigDir.path} dir`, - ok: true, - browser: fileBrowser, - file: homeConfigDir, - minLevel: 0, - func: readDir, - }); - } - } else { - // WWhen XDG_CONFIG_HOME is not set, verify we do not allow $HOME/.configlol - // (i.e., check allow the dir and not the prefix) - // - // Checking $HOME/.config is already done above. - const homeConfigPrefix = GetHomeSubdir(".configlol"); - tests.push({ - desc: `No XDG_CONFIG_HOME we dont allow ${homeConfigPrefix.path} access`, - ok: false, - browser: webBrowser, - file: homeConfigPrefix, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - if (fileContentProcessEnabled) { - tests.push({ - desc: `No XDG_CONFIG_HOME we dont allow ${homeConfigPrefix.path} access`, - ok: false, - browser: fileBrowser, - file: homeConfigPrefix, - minLevel: 0, - func: readDir, - }); - } - } - - // Create a file under $HOME/.config/ or $XDG_CONFIG_HOME and ensure we can - // read it - let fileUnderConfig = GetSubdirFile(configDir); - await IOUtils.writeUTF8(fileUnderConfig.path, "TEST FILE DUMMY DATA"); - ok( - await IOUtils.exists(fileUnderConfig.path), - `File ${fileUnderConfig.path} was properly created` - ); - - tests.push({ - desc: `${configDir.path}/xxx is readable (${fileUnderConfig.path})`, - ok: true, - browser: webBrowser, - file: fileUnderConfig, - minLevel: minHomeReadSandboxLevel(), - func: readFile, - cleanup: aPath => IOUtils.remove(aPath), - }); - - let configFile = GetSubdirFile(configDir); - tests.push({ - desc: `${configDir.path} file write`, - ok: false, - browser: webBrowser, - file: configFile, - minLevel: minHomeReadSandboxLevel(), - func: createFile, - }); - if (fileContentProcessEnabled) { - tests.push({ - desc: `${configDir.path} file write`, - ok: false, - browser: fileBrowser, - file: configFile, - minLevel: 0, - func: createFile, - }); - } - - // Create a $HOME/.config/mozilla/ or $XDG_CONFIG_HOME/mozilla/ if none - // exists and assert content process cannot access it - let configMozilla = GetSubdir(configDir, "mozilla"); - const emptyFileName = ".test_run_browser_sandbox.tmp"; - let emptyFile = configMozilla.clone(); - emptyFile.appendRelativePath(emptyFileName); - - let populateFakeConfigMozilla = async aPath => { - // called with configMozilla - await IOUtils.makeDirectory(aPath, { permissions: 0o700 }); - await IOUtils.writeUTF8(emptyFile.path, ""); - ok( - await IOUtils.exists(emptyFile.path), - `Temp file ${emptyFile.path} was created` - ); - }; - - let unpopulateFakeConfigMozilla = async aPath => { - // called with emptyFile - await IOUtils.remove(aPath); - ok(!(await IOUtils.exists(aPath)), `Temp file ${aPath} was removed`); - const parentDir = PathUtils.parent(aPath); - try { - await IOUtils.remove(parentDir, { recursive: false }); - } catch (ex) { - if ( - !DOMException.isInstance(ex) || - ex.name !== "OperationError" || - /Could not remove the non-empty directory/.test(ex.message) - ) { - // If we get here it means the directory was not empty and since we assert - // earlier we removed the temp file we created it means we should not - // worrying about removing this directory ... - throw ex; - } - } - }; - - await populateFakeConfigMozilla(configMozilla.path); - - tests.push({ - desc: `stat ${configDir.path}/mozilla (${configMozilla.path})`, - ok: false, - browser: webBrowser, - file: configMozilla, - minLevel: minHomeReadSandboxLevel(), - func: statPath, - }); - - tests.push({ - desc: `read ${configDir.path}/mozilla (${configMozilla.path})`, - ok: false, - browser: webBrowser, - file: configMozilla, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - - tests.push({ - desc: `stat ${configDir.path}/mozilla/${emptyFileName} (${emptyFile.path})`, - ok: false, - browser: webBrowser, - file: emptyFile, - minLevel: minHomeReadSandboxLevel(), - func: statPath, - }); - - tests.push({ - desc: `read ${configDir.path}/mozilla/${emptyFileName} (${emptyFile.path})`, - ok: false, - browser: webBrowser, - file: emptyFile, - minLevel: minHomeReadSandboxLevel(), - func: readFile, - cleanup: unpopulateFakeConfigMozilla, - }); - - // Only needed to perform cleanup - if (isXdgEnabled()) { - tests.push({ - desc: `$XDG_CONFIG_HOME (${configDir.path}) cleanup`, - ok: true, - browser: webBrowser, - file: configDir, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - } - - await runTestsList(tests); -} - -async function testFileAccessLinuxSnap() { - let webBrowser = GetWebBrowser(); - - let tests = []; - - // Assert that if we run with SNAP= env, then we allow access to it in the - // content process - let snap = Services.env.get("SNAP"); - let snapExpectedResult = false; - if (snap.length > 1) { - snapExpectedResult = true; - } else { - snap = "/tmp/.snap_firefox_current/"; - } - - let snapDir = GetDir(snap); - snapDir.normalize(); - - let snapFile = GetSubdirFile(snapDir); - await createFile(snapFile.path); - ok(await IOUtils.exists(snapFile.path), `SNAP ${snapFile.path} was created`); - info(`SNAP (file) ${snapFile.path} was created`); - - tests.push({ - desc: `$SNAP (${snapDir.path} => ${snapFile.path})`, - ok: snapExpectedResult, - browser: webBrowser, - file: snapFile, - minLevel: minHomeReadSandboxLevel(), - func: readFile, - }); - - await runTestsList(tests); -} - -async function testFileAccessWindowsOnly() { - if (!isWin()) { - return; - } - - let webBrowser = GetWebBrowser(); - - let tests = []; - - let extDir = GetPerUserExtensionDir(); - // We used to unconditionally create this directory from Firefox, but that - // was dropped in bug 2001887. The value of this directory is questionable; - // the test was added in Firefox 56 (bug 1403744) to cover legacy add-ons, - // but legacy add-on support was discontinued in Firefox 57, and we stopped - // sideloading add-ons from this directory on all builds except ESR in - // Firefox 74 (bug 1602840). - await IOUtils.makeDirectory(extDir.path); - tests.push({ - desc: "per-user extensions dir", - ok: true, - browser: webBrowser, - file: extDir, - minLevel: minHomeReadSandboxLevel(), - func: readDir, - }); - - await runTestsList(tests); -} - -function cleanupBrowserTabs() { - let fileBrowser = GetFileBrowser(); - if (fileBrowser.selectedTab) { - gBrowser.removeTab(fileBrowser.selectedTab); - } - - let webBrowser = GetWebBrowser(); - if (webBrowser.selectedTab) { - gBrowser.removeTab(webBrowser.selectedTab); - } - - let tab1 = gBrowser.tabs[1]; - if (tab1) { - gBrowser.removeTab(tab1); - } -} diff --git a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_xdg_default.js b/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_xdg_default.js deleted file mode 100644 index f828308bf..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_xdg_default.js +++ /dev/null @@ -1,40 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -/* import-globals-from browser_content_sandbox_utils.js */ -"use strict"; - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "security/sandbox/test/browser_content_sandbox_utils.js", - this -); - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "security/sandbox/test/browser_content_sandbox_fs_tests.js", - this -); - -SimpleTest.requestCompleteLog(); - -add_setup(async function setup() { - const xdgConfigHome = Services.env.exists("XDG_CONFIG_HOME"); - Assert.equal(xdgConfigHome, false, `XDG_CONFIG_HOME is not set`); - - const mozLegacyHome = Services.env.exists("MOZ_LEGACY_HOME"); - Assert.equal(mozLegacyHome, false, "MOZ_LEGACY_HOME is not set"); - - // If it is there, do actual testing - sanityChecks(); -}); - -add_task(async function () { - // Make sure we dont break others. - add_task(testFileAccessAllPlatforms); // eslint-disable-line no-undef - - // The linux only tests are the ones that can behave differently based on - // existence of XDG_CONFIG_HOME - add_task(testFileAccessLinuxOnly); // eslint-disable-line no-undef - - add_task(cleanupBrowserTabs); // eslint-disable-line no-undef -}); diff --git a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_xdg_mozLegacyHome.js b/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_xdg_mozLegacyHome.js deleted file mode 100644 index f76ee5d92..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_xdg_mozLegacyHome.js +++ /dev/null @@ -1,42 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -/* import-globals-from browser_content_sandbox_utils.js */ -"use strict"; - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "security/sandbox/test/browser_content_sandbox_utils.js", - this -); - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "security/sandbox/test/browser_content_sandbox_fs_tests.js", - this -); - -SimpleTest.requestCompleteLog(); - -add_setup(async function setup() { - const xdgConfigHome = Services.env.exists("XDG_CONFIG_HOME"); - Assert.equal(xdgConfigHome, true, "XDG_CONFIG_HOME is defined"); - - if (isXdgEnabled()) { - const mozLegacyHome = Services.env.get("MOZ_LEGACY_HOME"); - Assert.equal(mozLegacyHome, 1, "MOZ_LEGACY_HOME is set to 1"); - } - - // If it is there, do actual testing - sanityChecks(); -}); - -add_task(async function () { - // Make sure we dont break others. - add_task(testFileAccessAllPlatforms); // eslint-disable-line no-undef - - // The linux only tests are the ones that can behave differently based on - // existence of XDG_CONFIG_HOME - add_task(testFileAccessLinuxOnly); // eslint-disable-line no-undef - - add_task(cleanupBrowserTabs); // eslint-disable-line no-undef -}); diff --git a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_xdg_xdgConfigHome.js b/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_xdg_xdgConfigHome.js deleted file mode 100644 index 678101c5a..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_fs_xdg_xdgConfigHome.js +++ /dev/null @@ -1,45 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -/* import-globals-from browser_content_sandbox_utils.js */ -"use strict"; - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "security/sandbox/test/browser_content_sandbox_utils.js", - this -); - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "security/sandbox/test/browser_content_sandbox_fs_tests.js", - this -); - -SimpleTest.requestCompleteLog(); - -add_setup(async function setup() { - // Ensure that XDG_CONFIG_HOME is there - const xdgConfigHome = Services.env.get("XDG_CONFIG_HOME"); - Assert.greater(xdgConfigHome.length, 1, "XDG_CONFIG_HOME is defined"); - - // Verify the profile directory is inside XDG_CONFIG_HOME - const profileDir = Services.dirsvc.get("ProfD", Ci.nsIFile); - Assert.ok( - profileDir.path.startsWith(xdgConfigHome), - `Profile directory (${profileDir.path}) should be inside XDG_CONFIG_HOME (${xdgConfigHome})` - ); - - // If it is there, do actual testing - sanityChecks(); -}); - -add_task(async function () { - // Make sure we dont break others. - add_task(testFileAccessAllPlatforms); // eslint-disable-line no-undef - - // The linux only tests are the ones that can behave differently based on - // existence of XDG_CONFIG_HOME - add_task(testFileAccessLinuxOnly); // eslint-disable-line no-undef - - add_task(cleanupBrowserTabs); // eslint-disable-line no-undef -}); diff --git a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_syscalls.js b/src/zen/tests/mochitests/sandbox/browser_content_sandbox_syscalls.js deleted file mode 100644 index 1040ac473..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_syscalls.js +++ /dev/null @@ -1,405 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -/* import-globals-from browser_content_sandbox_utils.js */ -"use strict"; - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "security/sandbox/test/browser_content_sandbox_utils.js", - this -); - -const lazy = {}; - -/* getLibcConstants is only present on *nix */ -ChromeUtils.defineLazyGetter(lazy, "LIBC", () => - ChromeUtils.getLibcConstants() -); - -/* - * This test is for executing system calls in content processes to validate - * that calls that are meant to be blocked by content sandboxing are blocked. - * We use the term system calls loosely so that any OS API call such as - * fopen could be included. - */ - -// Calls the native execv library function. Include imports so this can be -// safely serialized and run remotely by SpecialPowers.spawn. -function callExec(args) { - const { ctypes } = ChromeUtils.importESModule( - "resource://gre/modules/ctypes.sys.mjs" - ); - let { lib, cmd } = args; - let libc = ctypes.open(lib); - let exec = libc.declare( - "execv", - ctypes.default_abi, - ctypes.int, - ctypes.char.ptr - ); - let rv = exec(cmd); - libc.close(); - return rv; -} - -// Calls the native fork syscall. -function callFork(args) { - const { ctypes } = ChromeUtils.importESModule( - "resource://gre/modules/ctypes.sys.mjs" - ); - let { lib } = args; - let libc = ctypes.open(lib); - let fork = libc.declare("fork", ctypes.default_abi, ctypes.int); - let rv = fork(); - libc.close(); - return rv; -} - -// Calls the native sysctl syscall. -function callSysctl(args) { - const { ctypes } = ChromeUtils.importESModule( - "resource://gre/modules/ctypes.sys.mjs" - ); - let { lib, name } = args; - let libc = ctypes.open(lib); - let sysctlbyname = libc.declare( - "sysctlbyname", - ctypes.default_abi, - ctypes.int, - ctypes.char.ptr, - ctypes.voidptr_t, - ctypes.size_t.ptr, - ctypes.voidptr_t, - ctypes.size_t.ptr - ); - let rv = sysctlbyname(name, null, null, null, null); - libc.close(); - return rv; -} - -function callPrctl(args) { - const { ctypes } = ChromeUtils.importESModule( - "resource://gre/modules/ctypes.sys.mjs" - ); - let { lib, option } = args; - let libc = ctypes.open(lib); - let prctl = libc.declare( - "prctl", - ctypes.default_abi, - ctypes.int, - ctypes.int, // option - ctypes.unsigned_long, // arg2 - ctypes.unsigned_long, // arg3 - ctypes.unsigned_long, // arg4 - ctypes.unsigned_long // arg5 - ); - let rv = prctl(option, 0, 0, 0, 0); - if (rv == -1) { - rv = ctypes.errno; - } - libc.close(); - return rv; -} - -// Calls the native open/close syscalls. -function callOpen(args) { - const { ctypes } = ChromeUtils.importESModule( - "resource://gre/modules/ctypes.sys.mjs" - ); - let { lib, path, flags } = args; - let libc = ctypes.open(lib); - let open = libc.declare( - "open", - ctypes.default_abi, - ctypes.int, - ctypes.char.ptr, - ctypes.int - ); - let close = libc.declare("close", ctypes.default_abi, ctypes.int, ctypes.int); - let fd = open(path, flags); - close(fd); - libc.close(); - return fd; -} - -// Verify faccessat2 -function callFaccessat2(args) { - const { ctypes } = ChromeUtils.importESModule( - "resource://gre/modules/ctypes.sys.mjs" - ); - let { lib, dirfd, path, mode, flag } = args; - let libc = ctypes.open(lib); - let faccessat = libc.declare( - "faccessat", - ctypes.default_abi, - ctypes.int, - ctypes.int, // dirfd - ctypes.char.ptr, // path - ctypes.int, // mode - ctypes.int // flag - ); - let rv = faccessat(dirfd, path, mode, flag); - if (rv == -1) { - rv = ctypes.errno; - } - libc.close(); - return rv; -} - -// Returns the name of the native library needed for native syscalls -function getOSLib() { - switch (Services.appinfo.OS) { - case "WINNT": - return "kernel32.dll"; - case "Darwin": - return "libc.dylib"; - case "Linux": - return "libc.so.6"; - default: - Assert.ok(false, "Unknown OS"); - return 0; - } -} - -// Reading a header might be weird, but the alternatives to read a stable -// version number we can easily check against are not much more fun -async function getKernelVersion() { - let header = await IOUtils.readUTF8("/usr/include/linux/version.h"); - let hr = header.split("\n"); - for (let line in hr) { - let hrs = hr[line].split(" "); - if (hrs[0] === "#define" && hrs[1] === "LINUX_VERSION_CODE") { - return Number(hrs[2]); - } - } - throw Error("No LINUX_VERSION_CODE"); -} - -// This is how it is done in /usr/include/linux/version.h -function computeKernelVersion(major, minor, dot) { - return (major << 16) + (minor << 8) + dot; -} - -function getGlibcVersion() { - const { ctypes } = ChromeUtils.importESModule( - "resource://gre/modules/ctypes.sys.mjs" - ); - let libc = ctypes.open(getOSLib()); - let gnu_get_libc_version = libc.declare( - "gnu_get_libc_version", - ctypes.default_abi, - ctypes.char.ptr - ); - let rv = gnu_get_libc_version().readString(); - libc.close(); - let ar = rv.split("."); - // return a number made of MAJORMINOR - return Number(ar[0] + ar[1]); -} - -// Returns a harmless command to execute with execv -function getOSExecCmd() { - Assert.ok(!isWin()); - return "/bin/cat"; -} - -// Returns true if the current content sandbox level, passed in -// the |level| argument, supports syscall sandboxing. -function areContentSyscallsSandboxed(level) { - let syscallsSandboxMinLevel = 0; - - // Set syscallsSandboxMinLevel to the lowest level that has - // syscall sandboxing enabled. For now, this varies across - // Windows, Mac, Linux, other. - switch (Services.appinfo.OS) { - case "WINNT": - syscallsSandboxMinLevel = 1; - break; - case "Darwin": - syscallsSandboxMinLevel = 1; - break; - case "Linux": - syscallsSandboxMinLevel = 1; - break; - default: - Assert.ok(false, "Unknown OS"); - } - - return level >= syscallsSandboxMinLevel; -} - -// -// Drive tests for a single content process. -// -// Tests executing OS API calls in the content process. Limited to Mac -// and Linux calls for now. -// -add_task(async 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. - // eslint-disable-next-line mozilla/use-default-preference-values - try { - level = Services.prefs.getIntPref("security.sandbox.content.level"); - } catch (e) { - prefExists = false; - } - - ok(prefExists, "pref security.sandbox.content.level exists"); - if (!prefExists) { - return; - } - - info(`security.sandbox.content.level=${level}`); - Assert.greater(level, 0, "content sandbox is enabled."); - - let areSyscallsSandboxed = areContentSyscallsSandboxed(level); - - // Content sandbox enabled, but level doesn't include syscall sandboxing. - ok(areSyscallsSandboxed, "content syscall sandboxing is enabled."); - if (!areSyscallsSandboxed) { - info("content sandbox level too low for syscall tests, exiting\n"); - return; - } - - let browser = gBrowser.selectedBrowser; - let lib = getOSLib(); - - // use execv syscall - // (causes content process to be killed on Linux) - if (isMac()) { - // exec something harmless, this should fail - let cmd = getOSExecCmd(); - let rv = await SpecialPowers.spawn(browser, [{ lib, cmd }], callExec); - Assert.equal(rv, -1, `exec(${cmd}) is not permitted`); - } - - // use open syscall - if (isLinux() || isMac()) { - // open a file for writing in $HOME, this should fail - let path = fileInHomeDir().path; - let flags = lazy.LIBC.O_CREAT | lazy.LIBC.O_WRONLY; - let fd = await SpecialPowers.spawn( - browser, - [{ lib, path, flags }], - callOpen - ); - Assert.less(fd, 0, "opening a file for writing in home is not permitted"); - } - - // use open syscall - if (isLinux() || isMac()) { - // open a file for writing in the content temp dir, this should fail on - // macOS and Linux. The open handler in the content process closes the file - // for us - let path = fileInTempDir().path; - let flags = lazy.LIBC.O_CREAT | lazy.LIBC.O_WRONLY; - let fd = await SpecialPowers.spawn( - browser, - [{ lib, path, flags }], - callOpen - ); - Assert.strictEqual( - fd, - -1, - "opening a file for writing in content temp is not permitted" - ); - } - - // use fork syscall - if (isLinux() || isMac()) { - let rv = await SpecialPowers.spawn(browser, [{ lib }], callFork); - Assert.equal(rv, -1, "calling fork is not permitted"); - } - - // On macOS before 10.10 the |sysctl-name| predicate didn't exist for - // filtering |sysctl| access. Check the Darwin version before running the - // tests (Darwin 14.0.0 is macOS 10.10). This branch can be removed when we - // remove support for macOS 10.9. - if (isMac() && Services.sysinfo.getProperty("version") >= "14.0.0") { - let rv = await SpecialPowers.spawn( - browser, - [{ lib, name: "kern.boottime" }], - callSysctl - ); - Assert.equal(rv, -1, "calling sysctl('kern.boottime') is not permitted"); - - rv = await SpecialPowers.spawn( - browser, - [{ lib, name: "net.inet.ip.ttl" }], - callSysctl - ); - Assert.equal(rv, -1, "calling sysctl('net.inet.ip.ttl') is not permitted"); - - rv = await SpecialPowers.spawn( - browser, - [{ lib, name: "hw.ncpu" }], - callSysctl - ); - Assert.equal(rv, 0, "calling sysctl('hw.ncpu') is permitted"); - } - - if (isLinux()) { - // These constants are not portable. - - // verify we block PR_CAPBSET_READ with EINVAL - let option = lazy.LIBC.PR_CAPBSET_READ; - let rv = await SpecialPowers.spawn(browser, [{ lib, option }], callPrctl); - Assert.strictEqual( - rv, - lazy.LIBC.EINVAL, - "prctl(PR_CAPBSET_READ) is blocked" - ); - - const kernelVersion = await getKernelVersion(); - const glibcVersion = getGlibcVersion(); - // faccessat2 is only used with kernel 5.8+ by glibc 2.33+ - if (glibcVersion >= 233 && kernelVersion >= computeKernelVersion(5, 8, 0)) { - info("Linux v5.8+, glibc 2.33+, checking faccessat2"); - const dirfd = 0; - const path = "/"; - const mode = 0; - // the value 0x01 is just one we know should get rejected - let rv = await SpecialPowers.spawn( - browser, - [{ lib, dirfd, path, mode, flag: 0x01 }], - callFaccessat2 - ); - Assert.strictEqual( - rv, - lazy.LIBC.ENOSYS, - "faccessat2 (flag=0x01) was blocked with ENOSYS" - ); - - rv = await SpecialPowers.spawn( - browser, - [{ lib, dirfd, path, mode, flag: lazy.LIBC.AT_EACCESS }], - callFaccessat2 - ); - Assert.strictEqual( - rv, - lazy.LIBC.EACCES, - "faccessat2 (flag=0x200) was allowed, errno=EACCES" - ); - } else { - info( - "Unsupported kernel (" + - kernelVersion + - " )/glibc (" + - glibcVersion + - "), skipping faccessat2" - ); - } - } -}); diff --git a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_utils.js b/src/zen/tests/mochitests/sandbox/browser_content_sandbox_utils.js deleted file mode 100644 index c7158a32b..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_content_sandbox_utils.js +++ /dev/null @@ -1,502 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -const uuidGenerator = Services.uuid; - -/* - * Utility functions for the browser content sandbox tests. - */ - -function sanityChecks() { - // 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. - // eslint-disable-next-line mozilla/use-default-preference-values - try { - level = Services.prefs.getIntPref("security.sandbox.content.level"); - } catch (e) { - prefExists = false; - } - - ok(prefExists, "pref security.sandbox.content.level exists"); - if (!prefExists) { - return; - } - - info(`security.sandbox.content.level=${level}`); - Assert.greater(level, 0, "content sandbox is enabled."); - - let isFileIOSandboxed = isContentFileIOSandboxed(level); - - // 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"); - } -} - -function isXdgEnabled() { - try { - return Services.prefs.getBoolPref("widget.support-xdg-config"); - } catch (ex) { - // if the pref is not there it means we dont have XDG support - if (ex.name === "NS_ERROR_UNEXPECTED") { - return false; - } - throw ex; - } -} - -// Creates file at |path| and returns a promise that resolves with an object -// with .ok boolean to indicate true if the file was successfully created, -// otherwise false. Include imports so this can be safely serialized and run -// remotely by SpecialPowers.spawn. -// -// Report the exception's error code in .code as well. -function createFile(path) { - const { FileUtils } = ChromeUtils.importESModule( - "resource://gre/modules/FileUtils.sys.mjs" - ); - - try { - const fstream = Cc[ - "@mozilla.org/network/file-output-stream;1" - ].createInstance(Ci.nsIFileOutputStream); - - fstream.init( - new FileUtils.File(path), - -1, // readonly mode - -1, // default permissions - 0 - ); // behaviour flags - - const ostream = Cc["@mozilla.org/binaryoutputstream;1"].createInstance( - Ci.nsIBinaryOutputStream - ); - ostream.setOutputStream(fstream); - - const data = "TEST FILE DUMMY DATA"; - ostream.writeBytes(data, data.length); - - ostream.close(); - fstream.close(); - } catch (e) { - return { ok: false, code: e.result }; - } - - return { ok: true }; -} - -// Creates a symlink at |path| and returns a promise that resolves with an -// object with .ok boolean to indicate true if the symlink was successfully -// created, otherwise false. Include imports so this can be safely serialized -// and run remotely by SpecialPowers.spawn. -// -// Report the exception's error code in .code as well. -// Report errno in .code if syscall returns -1. -function createSymlink(path) { - const { ctypes } = ChromeUtils.importESModule( - "resource://gre/modules/ctypes.sys.mjs" - ); - - try { - // Trying to open "libc.so" on linux will fail with invalid elf header error - // because it would be a linker script. Using libc.so.6 avoids that. - const libc = ctypes.open( - Services.appinfo.OS === "Darwin" ? "libSystem.B.dylib" : "libc.so.6" - ); - - const symlink = libc.declare( - "symlink", - ctypes.default_abi, - ctypes.int, // return value - ctypes.char.ptr, // target - ctypes.char.ptr //linkpath - ); - - ctypes.errno = 0; - const rv = symlink("/etc", path); - const _errno = ctypes.errno; - if (rv < 0) { - return { ok: false, code: _errno }; - } - } catch (e) { - return { ok: false, code: e.result }; - } - - return { ok: true }; -} - -// Deletes file at |path| and returns a promise that resolves with an object -// with .ok boolean to indicate true if the file was successfully deleted, -// otherwise false. Include imports so this can be safely serialized and run -// remotely by SpecialPowers.spawn. -// -// Report the exception's error code in .code as well. -function deleteFile(path) { - const { FileUtils } = ChromeUtils.importESModule( - "resource://gre/modules/FileUtils.sys.mjs" - ); - - try { - const file = new FileUtils.File(path); - file.remove(false); - } catch (e) { - return { ok: false, code: e.result }; - } - - return { ok: true }; -} - -// Reads the directory at |path| and returns a promise that resolves when -// iteration over the directory finishes or encounters an error. The promise -// resolves with an object where .ok indicates success or failure and -// .numEntries is the number of directory entries found. -// -// Report the exception's error code in .code as well. -function readDir(path) { - const { FileUtils } = ChromeUtils.importESModule( - "resource://gre/modules/FileUtils.sys.mjs" - ); - - let numEntries = 0; - - try { - const file = new FileUtils.File(path); - const enumerator = file.directoryEntries; - - while (enumerator.hasMoreElements()) { - void enumerator.nextFile; - numEntries++; - } - } catch (e) { - return { ok: false, numEntries, code: e.result }; - } - - return { ok: true, numEntries }; -} - -// Reads the file at |path| and returns a promise that resolves when -// reading is completed. Returned object has boolean .ok to indicate -// success or failure. -// -// Report the exception's error code in .code as well. -function readFile(path) { - const { FileUtils } = ChromeUtils.importESModule( - "resource://gre/modules/FileUtils.sys.mjs" - ); - - try { - const file = new FileUtils.File(path); - - const fstream = Cc[ - "@mozilla.org/network/file-input-stream;1" - ].createInstance(Ci.nsIFileInputStream); - fstream.init(file, -1, -1, 0); - - const istream = Cc["@mozilla.org/binaryinputstream;1"].createInstance( - Ci.nsIBinaryInputStream - ); - istream.setInputStream(fstream); - - const available = istream.available(); - void istream.readBytes(available); - } catch (e) { - return { ok: false, code: e.result }; - } - - return { ok: true }; -} - -// Does a stat of |path| and returns a promise that resolves if the -// stat is successful. Returned object has boolean .ok to indicate -// success or failure. -// -// Report the exception's error code in .code as well. -function statPath(path) { - const { FileUtils } = ChromeUtils.importESModule( - "resource://gre/modules/FileUtils.sys.mjs" - ); - - try { - const file = new FileUtils.File(path); - void file.lastModifiedTime; - } catch (e) { - return { ok: false, code: e.result }; - } - - return { ok: true }; -} - -// 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; -} - -// Returns the lowest sandbox level where blanket reading of the profile -// directory from the content process should be blocked by the sandbox. -function minProfileReadSandboxLevel() { - switch (Services.appinfo.OS) { - case "WINNT": - return 3; - case "Darwin": - return 2; - case "Linux": - return 3; - default: - Assert.ok(false, "Unknown OS"); - return 0; - } -} - -// Returns the lowest sandbox level where blanket reading of the home -// directory from the content process should be blocked by the sandbox. -function minHomeReadSandboxLevel() { - switch (Services.appinfo.OS) { - case "WINNT": - return 3; - case "Darwin": - return 3; - case "Linux": - return 3; - default: - Assert.ok(false, "Unknown OS"); - return 0; - } -} - -function isMac() { - return Services.appinfo.OS == "Darwin"; -} -function isWin() { - return Services.appinfo.OS == "WINNT"; -} -function isLinux() { - return Services.appinfo.OS == "Linux"; -} - -function isNightly() { - let version = SpecialPowers.Services.appinfo.version; - return version.endsWith("a1"); -} - -function uuid() { - return uuidGenerator.generateUUID().toString(); -} - -// Returns a file object for a new file in the home dir ($HOME/). -function fileInHomeDir() { - // get home directory, make sure it exists - let homeDir = Services.dirsvc.get("Home", Ci.nsIFile); - Assert.ok(homeDir.exists(), "Home dir exists"); - Assert.ok(homeDir.isDirectory(), "Home dir is a directory"); - - // build a file object for a new file named $HOME/ - let homeFile = homeDir.clone(); - homeFile.appendRelativePath(uuid()); - Assert.ok(!homeFile.exists(), homeFile.path + " does not exist"); - return homeFile; -} - -// Returns a file object for a new file in the content temp dir (.../). -function fileInTempDir() { - let contentTempKey = "TmpD"; - - // get the content temp dir, make sure it exists - let ctmp = Services.dirsvc.get(contentTempKey, Ci.nsIFile); - Assert.ok(ctmp.exists(), "Temp dir exists"); - Assert.ok(ctmp.isDirectory(), "Temp dir is a directory"); - - // build a file object for a new file in content temp - let tempFile = ctmp.clone(); - tempFile.appendRelativePath(uuid()); - Assert.ok(!tempFile.exists(), tempFile.path + " does not exist"); - return tempFile; -} - -function GetProfileDir() { - // get profile directory - let profileDir = Services.dirsvc.get("ProfD", Ci.nsIFile); - return profileDir; -} - -function GetHomeDir() { - // get home directory - let homeDir = Services.dirsvc.get("Home", Ci.nsIFile); - return homeDir; -} - -function GetHomeSubdir(subdir) { - return GetSubdir(GetHomeDir(), subdir); -} - -function GetHomeSubdirFile(subdir) { - return GetSubdirFile(GetHomeSubdir(subdir)); -} - -function GetSubdir(dir, subdir) { - let newSubdir = dir.clone(); - newSubdir.appendRelativePath(subdir); - return newSubdir; -} - -function GetSubdirFile(dir) { - let newFile = dir.clone(); - newFile.appendRelativePath(uuid()); - return newFile; -} - -function GetPerUserExtensionDir() { - return Services.dirsvc.get("XREUSysExt", Ci.nsIFile); -} - -// Returns a file object for the file or directory named |name| in the -// profile directory. -function GetProfileEntry(name) { - let entry = GetProfileDir(); - entry.append(name); - return entry; -} - -function GetDir(path) { - info(`GetDir(${path})`); - let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); - dir.initWithPath(path); - Assert.ok(dir.isDirectory(), `${path} is a directory`); - return dir; -} - -function GetDirFromEnvVariable(varName) { - return GetDir(Services.env.get(varName)); -} - -function GetFile(path) { - let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); - file.initWithPath(path); - return file; -} - -function GetBrowserType(type) { - let browserType = undefined; - - if (!GetBrowserType[type]) { - if (type === "web") { - GetBrowserType[type] = gBrowser.selectedBrowser; - } else { - // open a tab in a `type` content process - gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank", { - preferredRemoteType: type, - allowInheritPrincipal: true, - }); - // get the browser for the `type` process tab - GetBrowserType[type] = gBrowser.getBrowserForTab(gBrowser.selectedTab); - } - } - - browserType = GetBrowserType[type]; - Assert.strictEqual( - browserType.remoteType, - type, - `GetBrowserType(${type}) returns a ${type} process` - ); - return browserType; -} - -function GetWebBrowser() { - return GetBrowserType("web"); -} - -function isFileContentProcessEnabled() { - // Ensure that the file content process is enabled. - let fileContentProcessEnabled = Services.prefs.getBoolPref( - "browser.tabs.remote.separateFileUriProcess" - ); - ok(fileContentProcessEnabled, "separate file content process is enabled"); - return fileContentProcessEnabled; -} - -function GetFileBrowser() { - if (!isFileContentProcessEnabled()) { - return undefined; - } - return GetBrowserType("file"); -} - -function GetSandboxLevel() { - // Current level - return Services.prefs.getIntPref("security.sandbox.content.level"); -} - -async function runTestsList(tests) { - let level = GetSandboxLevel(); - - // remove tests not enabled by the current sandbox level - tests = tests.filter(test => test.minLevel <= level); - - for (let test of tests) { - let okString = test.ok ? "allowed" : "blocked"; - let processType = test.browser.remoteType; - - // ensure the file/dir exists before we ask a content process to stat - // it so we know a failure is not due to a nonexistent file/dir - if (test.func === statPath) { - ok(test.file.exists(), `${test.file.path} exists`); - } - - let result = await SpecialPowers.spawn( - test.browser, - [test.file.path], - test.func - ); - - Assert.equal( - result.ok, - test.ok, - `reading ${test.desc} from a ${processType} process ` + - `is ${okString} (${test.file.path})` - ); - - // if the directory is not expected to be readable, - // ensure the listing has zero entries - if (test.func === readDir && !test.ok) { - Assert.equal( - result.numEntries, - 0, - `directory list is empty (${test.file.path})` - ); - } - - if (test.cleanup != undefined) { - await test.cleanup(test.file.path); - } - } -} diff --git a/src/zen/tests/mochitests/sandbox/browser_profiler.toml b/src/zen/tests/mochitests/sandbox/browser_profiler.toml deleted file mode 100644 index de46910e3..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_profiler.toml +++ /dev/null @@ -1,21 +0,0 @@ -[DEFAULT] -skip-if = [ - "ccov", - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && asan", # bug 1784517 for sandbox, bug 1885381 for profiler - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && tsan", # bug 1784517 for sandbox, bug 1885381 for profiler -] -tags = "contentsandbox" - -# This is here to make sure we will not have prelaunched processes, which will -# mess with sandbox profiling interaction: we will miss launch-related markers -# and this makes the test intermittently fail on TV jobs -prefs = [ - "dom.ipc.processPrelaunch.fission.number=0" -] - -environment = "MOZ_SANDBOX_LOGGING_FOR_TESTS=1" - -["browser_sandbox_profiler.js"] -run-if = [ - "os == 'linux'", -] diff --git a/src/zen/tests/mochitests/sandbox/browser_sandbox_profiler.js b/src/zen/tests/mochitests/sandbox/browser_sandbox_profiler.js deleted file mode 100644 index c20310b51..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_sandbox_profiler.js +++ /dev/null @@ -1,153 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -const { ProfilerTestUtils } = ChromeUtils.importESModule( - "resource://testing-common/ProfilerTestUtils.sys.mjs" -); - -async function addTab() { - const tab = BrowserTestUtils.addTab(gBrowser, "https://example.com/browser", { - forceNewProcess: true, - }); - const browser = gBrowser.getBrowserForTab(tab); - await BrowserTestUtils.browserLoaded(browser); - return tab; -} - -const sandboxSettingsEnabled = { - entries: 8 * 1024 * 1024, // 8M entries = 64MB - interval: 1, // ms - features: ["stackwalk", "sandbox"], - threads: ["SandboxProfilerEmitter"], -}; - -const sandboxSettingsDisabled = { - entries: 8 * 1024 * 1024, // 8M entries = 64MB - interval: 1, // ms - features: ["stackwalk"], - threads: ["SandboxProfilerEmitter"], -}; - -const kNewProcesses = 2; - -async function waitForMaybeSandboxProfilerData( - threadName, - name1, - withStacks, - enabled -) { - let tabs = []; - for (let i = 0; i < kNewProcesses; ++i) { - tabs.push(await addTab()); - } - - let profile; - let intercepted = undefined; - try { - await TestUtils.waitForCondition( - async () => { - profile = await Services.profiler.getProfileDataAsync(); - intercepted = profile.processes - .flatMap(ps => { - let sandboxThreads = ps.threads.filter( - th => th.name === threadName - ); - return sandboxThreads.flatMap(th => { - let markersData = th.markers.data; - return markersData.flatMap(d => { - let [, , , , , o] = d; - return o; - }); - }); - }) - .filter(x => "name1" in x && name1.includes(x.name1) >= 0); - return !!intercepted.length; - }, - `Wait for some samples from ${threadName}`, - /* interval*/ 100, - /* maxTries */ 25 - ); - Assert.greater( - intercepted.length, - 0, - `Should have collected some data from ${threadName}` - ); - } catch (ex) { - if (!enabled && ex.includes(`Wait for some samples from ${threadName}`)) { - Assert.equal( - intercepted.length, - 0, - `Should have NOT collected data from ${threadName}` - ); - } else { - throw ex; - } - } - - if (withStacks) { - let stacks = profile.processes.flatMap(ps => { - let sandboxThreads = ps.threads.filter(th => th.name === threadName); - return sandboxThreads.flatMap(th => { - let stackTableData = th.stackTable.data; - return stackTableData.flatMap(d => { - return [d]; - }); - }); - }); - if (enabled) { - Assert.greater(stacks.length, 0, "Should have some stack as well"); - } else { - Assert.equal(stacks.length, 0, "Should have NO stack as well"); - } - } - - for (let tab of tabs) { - await BrowserTestUtils.removeTab(tab); - } -} - -add_task(async () => { - await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled); - await waitForMaybeSandboxProfilerData( - "SandboxProfilerEmitterSyscalls", - ["id", "init"], - /* withStacks */ true, - /* enabled */ true - ); - await Services.profiler.StopProfiler(); -}); - -add_task(async () => { - await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled); - await waitForMaybeSandboxProfilerData( - "SandboxProfilerEmitterLogs", - ["log"], - /* withStacks */ false, - /* enabled */ true - ); - await Services.profiler.StopProfiler(); -}); - -add_task(async () => { - await ProfilerTestUtils.startProfiler(sandboxSettingsDisabled); - await waitForMaybeSandboxProfilerData( - "SandboxProfilerEmitterSyscalls", - ["id", "init"], - /* withStacks */ true, - /* enabled */ false - ); - await Services.profiler.StopProfiler(); -}); - -add_task(async () => { - await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled); - await waitForMaybeSandboxProfilerData( - "SandboxProfilerEmitterLogs", - ["log"], - /* withStacks */ false, - /* enabled */ false - ); - await Services.profiler.StopProfiler(); -}); diff --git a/src/zen/tests/mochitests/sandbox/browser_sandbox_test.js b/src/zen/tests/mochitests/sandbox/browser_sandbox_test.js deleted file mode 100644 index 58c37989c..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_sandbox_test.js +++ /dev/null @@ -1,78 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -"use strict"; - -function test() { - waitForExplicitFinish(); - - // Types of processes to test, taken from GeckoProcessTypes.h - // GPU process might not run depending on the platform, so we need it to be - // the last one of the list to allow the remainingTests logic below to work - // as expected. - // - // For UtilityProcess, allow constructing a string made of the process type - // and the sandbox variant we want to test, e.g., - // utility:0 for GENERIC_UTILITY - // utility:1 for AppleMedia/WMF on macOS/Windows - var processTypes = ["tab", "socket", "rdd", "gmplugin", "utility:0", "gpu"]; - - const platform = SpecialPowers.Services.appinfo.OS; - if (platform === "WINNT" || platform === "Darwin") { - processTypes.push("utility:1"); - } - - // A callback called after each test-result. - let sandboxTestResult = (subject, topic, data) => { - let { testid, passed, message } = JSON.parse(data); - ok( - passed, - "Test " + testid + (passed ? " passed: " : " failed: ") + message - ); - }; - Services.obs.addObserver(sandboxTestResult, "sandbox-test-result"); - - var remainingTests = processTypes.length; - - // A callback that is notified when a child process is done running tests. - let sandboxTestDone = () => { - remainingTests = remainingTests - 1; - if (remainingTests == 0) { - // Clean up test file - if (homeTestFile.exists()) { - ok(homeTestFile.isFile(), "homeTestFile should be a file"); - if (homeTestFile.isFile()) { - homeTestFile.remove(false); - } - } - - Services.obs.removeObserver(sandboxTestResult, "sandbox-test-result"); - Services.obs.removeObserver(sandboxTestDone, "sandbox-test-done"); - - // Notify SandboxTest component that it should terminate the connection - // with the child processes. - comp.finishTests(); - // Notify mochitest that all process tests are complete. - finish(); - } - }; - Services.obs.addObserver(sandboxTestDone, "sandbox-test-done"); - - var comp = Cc["@mozilla.org/sandbox/sandbox-test;1"].getService( - Ci.mozISandboxTest - ); - - let homeTestFile; - try { - homeTestFile = Services.dirsvc.get("Home", Ci.nsIFile); - homeTestFile.append(".mozilla_gpu_sandbox_read_test"); - if (!homeTestFile.exists()) { - homeTestFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600); - } - } catch (e) { - ok(false, "Failed to create home test file: " + e); - } - - comp.startTests(processTypes); -} diff --git a/src/zen/tests/mochitests/sandbox/browser_snap.toml b/src/zen/tests/mochitests/sandbox/browser_snap.toml deleted file mode 100644 index 19a4a1004..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_snap.toml +++ /dev/null @@ -1,20 +0,0 @@ -# Any copyright is dedicated to the Public Domain. -# http://creativecommons.org/publicdomain/zero/1.0/ -[DEFAULT] -skip-if = [ - "ccov", - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && asan", # bug 1784517 - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && tsan", # bug 1784517 -] -tags = "contentsandbox" -support-files = [ - "browser_content_sandbox_utils.js", - "browser_content_sandbox_fs_tests.js", -] -test-directories = "/tmp/.snap_firefox_current_real/" -environment = "SNAP=/tmp/.snap_firefox_current_real/" - -["browser_content_sandbox_fs_snap.js"] -run-if = [ - "os == 'linux'", -] diff --git a/src/zen/tests/mochitests/sandbox/browser_xdg_default.toml b/src/zen/tests/mochitests/sandbox/browser_xdg_default.toml deleted file mode 100644 index f03f4c06f..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_xdg_default.toml +++ /dev/null @@ -1,26 +0,0 @@ -# Any copyright is dedicated to the Public Domain. -# http://creativecommons.org/publicdomain/zero/1.0/ -[DEFAULT] -skip-if = [ - "ccov", - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && asan", # bug 1784517 - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && tsan", # bug 1784517 -] -tags = "contentsandbox" -support-files = [ - "browser_content_sandbox_utils.js", - "browser_content_sandbox_fs_tests.js", -] -test-directories = [ - "/tmp/.xdg_default_test", - "/tmp/.xdg_default_test/.config/mozilla/firefox/xdg_default_profile", -] -environment = [ - "HOME=/tmp/.xdg_default_test", -] -profile-path = "/tmp/.xdg_default_test/.config/mozilla/firefox/xdg_default_profile" - -["browser_content_sandbox_fs_xdg_default.js"] -run-if = [ - "os == 'linux'" -] diff --git a/src/zen/tests/mochitests/sandbox/browser_xdg_mozLegacyHome.toml b/src/zen/tests/mochitests/sandbox/browser_xdg_mozLegacyHome.toml deleted file mode 100644 index 7f7b680a8..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_xdg_mozLegacyHome.toml +++ /dev/null @@ -1,29 +0,0 @@ -# Any copyright is dedicated to the Public Domain. -# http://creativecommons.org/publicdomain/zero/1.0/ -[DEFAULT] -skip-if = [ - "ccov", - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && asan", # bug 1784517 - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && tsan", # bug 1784517 -] -tags = "contentsandbox" -support-files = [ - "browser_content_sandbox_utils.js", - "browser_content_sandbox_fs_tests.js", -] -test-directories = [ - "/tmp/.xdg_mozLegacyHome_test/.config", - "/tmp/.xdg_config_home_test", - "/tmp/.xdg_mozLegacyHome_test/.mozilla/firefox/xdg_mozLegacyHome_profile", -] -environment = [ - "XDG_CONFIG_HOME=/tmp/.xdg_config_home_test", - "HOME=/tmp/.xdg_mozLegacyHome_test", - "MOZ_LEGACY_HOME=1", -] -profile-path = "/tmp/.xdg_mozLegacyHome_test/.mozilla/firefox/xdg_mozLegacyHome_profile" - -["browser_content_sandbox_fs_xdg_mozLegacyHome.js"] -run-if = [ - "os == 'linux'" -] diff --git a/src/zen/tests/mochitests/sandbox/browser_xdg_xdgConfigHome.toml b/src/zen/tests/mochitests/sandbox/browser_xdg_xdgConfigHome.toml deleted file mode 100644 index b32d0c25d..000000000 --- a/src/zen/tests/mochitests/sandbox/browser_xdg_xdgConfigHome.toml +++ /dev/null @@ -1,27 +0,0 @@ -# Any copyright is dedicated to the Public Domain. -# http://creativecommons.org/publicdomain/zero/1.0/ -[DEFAULT] -skip-if = [ - "ccov", - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && asan", # bug 1784517 - "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11' && tsan", # bug 1784517 -] -tags = "contentsandbox" -support-files = [ - "browser_content_sandbox_utils.js", - "browser_content_sandbox_fs_tests.js", -] -test-directories = [ - "/tmp/.xdg_config_home_test", - "/tmp/.xdg_config_home_test/mozilla/firefox/xdg_config_home_profile", -] -environment = [ - "XDG_CONFIG_HOME=/tmp/.xdg_config_home_test", - "MOZ_LEGACY_HOME=0", -] -profile-path = "/tmp/.xdg_config_home_test/mozilla/firefox/xdg_config_home_profile" - -["browser_content_sandbox_fs_xdg_xdgConfigHome.js"] -run-if = [ - "os == 'linux'", -] diff --git a/src/zen/tests/mochitests/sandbox/bug1393259.html b/src/zen/tests/mochitests/sandbox/bug1393259.html deleted file mode 100644 index b1e3cca99..000000000 --- a/src/zen/tests/mochitests/sandbox/bug1393259.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - -
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz -
- - - diff --git a/src/zen/tests/mochitests/sandbox/mac_register_font.py b/src/zen/tests/mochitests/sandbox/mac_register_font.py deleted file mode 100755 index 549becf56..000000000 --- a/src/zen/tests/mochitests/sandbox/mac_register_font.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/python -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -""" -mac_register_font.py - -Mac-specific utility command to register a font file with the OS. -""" - -import argparse -import sys - -import Cocoa -import CoreText - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - help="print verbose registration failures", - default=False, - ) - parser.add_argument( - "file", nargs="*", help="font file to register or unregister", default=[] - ) - parser.add_argument( - "-u", - "--unregister", - action="store_true", - help="unregister the provided fonts", - default=False, - ) - parser.add_argument( - "-p", - "--persist-user", - action="store_true", - help="permanently register the font", - default=False, - ) - - args = parser.parse_args() - - if args.persist_user: - scope = CoreText.kCTFontManagerScopeUser - scopeDesc = "user" - else: - scope = CoreText.kCTFontManagerScopeSession - scopeDesc = "session" - - failureCount = 0 - for fontPath in args.file: - fontURL = Cocoa.NSURL.fileURLWithPath_(fontPath) - (result, error) = register_or_unregister_font(fontURL, args.unregister, scope) - if result: - print( - "%sregistered font %s with %s scope" - % (("un" if args.unregister else ""), fontPath, scopeDesc) - ) - else: - print( - "Failed to %sregister font %s with %s scope" - % (("un" if args.unregister else ""), fontPath, scopeDesc) - ) - if args.verbose: - print(error) - failureCount += 1 - - sys.exit(failureCount) - - -def register_or_unregister_font(fontURL, unregister, scope): - return ( - CoreText.CTFontManagerUnregisterFontsForURL(fontURL, scope, None) - if unregister - else CoreText.CTFontManagerRegisterFontsForURL(fontURL, scope, None) - ) - - -if __name__ == "__main__": - main() diff --git a/surfer.json b/surfer.json index 479ccbe91..bcc52e5b1 100644 --- a/surfer.json +++ b/surfer.json @@ -5,8 +5,8 @@ "binaryName": "zen", "version": { "product": "firefox", - "version": "151.0.3", - "candidate": "151.0.3", + "version": "151.0.4", + "candidate": "151.0.4", "candidateBuild": 1 }, "buildOptions": { @@ -20,7 +20,7 @@ "brandShortName": "Zen", "brandFullName": "Zen Browser", "release": { - "displayVersion": "1.20.2b", + "displayVersion": "1.21b", "github": { "repo": "zen-browser/desktop" }, @@ -40,7 +40,7 @@ "brandShortName": "Twilight", "brandFullName": "Zen Twilight", "release": { - "displayVersion": "1.21t", + "displayVersion": "1.22t", "github": { "repo": "zen-browser/desktop" } @@ -54,4 +54,4 @@ "licenseType": "MPL-2.0" }, "updateHostname": "updates.zen-browser.app" -} +} \ No newline at end of file