Bug 1382260 - Patch 2 - [Mac] Allow reading of font files from the content sandbox. r=Alex_Gaynor

MozReview-Commit-ID: 9W5aqQweFmd

--HG--
extra : rebase_source : 9aa778bc08bee206e7f3340eac32ca2f46a4f81b
This commit is contained in:
Haik Aftandilian 2017-08-18 16:12:07 -07:00
parent c90d8c6594
commit 3fbdb1b349
3 changed files with 109 additions and 2 deletions

View File

@ -342,6 +342,19 @@ static const char contentSandboxRules[] = R"(
(require-any
(vnode-type REGULAR-FILE)
(vnode-type DIRECTORY))))
; bug 1382260
; We may need to load fonts from outside of the standard
; font directories whitelisted above. This is typically caused
; by a font manager. For now, whitelist any file with a
; font extension. Limit this to the common font types:
; files ending in .otf, .ttf, .ttc, .otc, and .dfont.
(allow file-read*
(regex #"\.[oO][tT][fF]$" ; otf
#"\.[tT][tT][fF]$" ; ttf
#"\.[tT][tT][cC]$" ; ttc
#"\.[oO][tT][cC]$" ; otc
#"\.[dD][fF][oO][nN][tT]$")) ; dfont
)";
}

View File

@ -9,6 +9,8 @@ var prefs = Cc["@mozilla.org/preferences-service;1"]
Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/" +
"security/sandbox/test/browser_content_sandbox_utils.js", this);
const FONT_EXTENSIONS = [ "otf", "ttf", "ttc", "otc", "dfont" ];
/*
* This test exercises file I/O from web and file content processes using
* OS.File methods to validate that calls that are meant to be blocked by
@ -21,7 +23,7 @@ Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/" +
function createFile(path) {
Components.utils.import("resource://gre/modules/osfile.jsm");
let encoder = new TextEncoder();
let array = encoder.encode("WRITING FROM CONTENT PROCESS");
let array = encoder.encode("TEST FILE DUMMY DATA");
return OS.File.writeAtomic(path, array).then(function(value) {
return true;
}, function(reason) {
@ -29,7 +31,6 @@ function createFile(path) {
});
}
// Creates a symlink at |path| and returns a promise that resolves with true
// if the symlink was successfully created, otherwise false. Include imports
// so this can be safely serialized and run remotely by ContentTask.spawn.
@ -246,6 +247,46 @@ async function createTempFile() {
}
}
// Build a list of nonexistent font file paths (lower and upper case) with
// all the font extensions we want the sandbox to allow read access to.
// Generate paths within base directory |baseDir|.
function getFontTestPaths(baseDir) {
baseDir = baseDir + "/";
let basename = uuid();
let testPaths = [];
for (let ext of FONT_EXTENSIONS) {
// lower case filename
let lcFilename = baseDir + (basename + "lc." + ext).toLowerCase();
testPaths.push(lcFilename);
// upper case filename
let ucFilename = baseDir + (basename + "UC." + ext).toUpperCase();
testPaths.push(ucFilename);
}
return testPaths;
}
// Build a list of nonexistent invalid font file paths. Specifically,
// paths that include the valid font extensions but should fail to load.
// For example, if a font extension happens to be a substring of the filename
// but isn't the extension. Generate paths within base directory |baseDir|.
function getBadFontTestPaths(baseDir) {
baseDir = baseDir + "/";
let basename = uuid();
let testPaths = [];
for (let ext of FONT_EXTENSIONS) {
let filename = baseDir + basename + "." + ext + ".txt";
testPaths.push(filename);
filename = baseDir + basename + "." + ext + ext + ".txt";
testPaths.push(filename);
}
return testPaths;
}
// Test reading files and dirs from web and file content processes.
async function testFileAccess() {
// for tests that run in a web content process
@ -276,6 +317,53 @@ async function testFileAccess() {
// that will be read from either a web or file process.
let tests = [];
// Test that Mac content processes can read files with font extensions
// and fail to read files that include the font extension as a
// non-extension substring.
if (isMac()) {
// Use the same directory for valid/invalid font path tests to ensure
// the font isn't allowed because the directory is already allowed.
let fontTestDir = "/private/tmp";
let fontTestPaths = getFontTestPaths(fontTestDir);
let badFontTestPaths = getBadFontTestPaths(fontTestDir);
// before we start creating dummy font files,
// register a cleanup func to remove them
registerCleanupFunction(async function() {
for (let fontPath of fontTestPaths.concat(badFontTestPaths)) {
await OS.File.remove(fontPath, {ignoreAbsent: true});
}
});
// create each dummy font file and add a test for it
for (let fontPath of fontTestPaths) {
let result = await createFile(fontPath);
Assert.ok(result, `${fontPath} created`);
let fontFile = GetFile(fontPath);
tests.push({
desc: "font file", // description
ok: true, // expected to succeed?
browser: webBrowser, // browser to run test in
file: fontFile, // nsIFile object
minLevel: minHomeReadSandboxLevel(), // min level to enable test
});
}
for (let fontPath of badFontTestPaths) {
let result = await createFile(fontPath);
Assert.ok(result, `${fontPath} created`);
let fontFile = GetFile(fontPath);
tests.push({
desc: "invalid font file", // description
ok: false, // expected to succeed?
browser: webBrowser, // browser to run test in
file: fontFile, // nsIFile object
minLevel: minHomeReadSandboxLevel(), // min level to enable test
});
}
}
// The Linux test runners create the temporary profile in the same
// system temp dir we give write access to, so this gives a false
// positive.

View File

@ -89,3 +89,9 @@ function GetDir(path) {
function GetDirFromEnvVariable(varName) {
return GetDir(environment.get(varName));
}
function GetFile(path) {
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(path);
return (file);
}