зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1786885 - Add ChromeUtils::GetLibcConstants r=nika
ChromeUtils::GetLibcConstants() is a replacement for nsIOSFileConstantsService providing OS.Consts.LIBC. The constants from OS.Consts.Win have been inlined into subprocess_shared_win.js, since it was already defining several other constants and it was the only consumer. Differential Revision: https://phabricator.services.mozilla.com/D180358
This commit is contained in:
Родитель
804da488b4
Коммит
3efc235517
|
@ -61,6 +61,18 @@
|
|||
#include "nsIException.h"
|
||||
#include "VsyncSource.h"
|
||||
|
||||
#ifdef XP_UNIX
|
||||
# include <errno.h>
|
||||
# include <unistd.h>
|
||||
# include <fcntl.h>
|
||||
# include <poll.h>
|
||||
# include <sys/wait.h>
|
||||
|
||||
# ifdef XP_LINUX
|
||||
# include <sys/prctl.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
/* static */
|
||||
|
@ -973,6 +985,41 @@ void ChromeUtils::DefineESModuleGetters(const GlobalObject& global,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef XP_UNIX
|
||||
/* static */
|
||||
void ChromeUtils::GetLibcConstants(const GlobalObject&,
|
||||
LibcConstants& aConsts) {
|
||||
aConsts.mEINTR.Construct(EINTR);
|
||||
aConsts.mEACCES.Construct(EACCES);
|
||||
aConsts.mEAGAIN.Construct(EAGAIN);
|
||||
aConsts.mEINVAL.Construct(EINVAL);
|
||||
aConsts.mENOSYS.Construct(ENOSYS);
|
||||
|
||||
aConsts.mF_SETFD.Construct(F_SETFD);
|
||||
aConsts.mF_SETFL.Construct(F_SETFL);
|
||||
|
||||
aConsts.mFD_CLOEXEC.Construct(FD_CLOEXEC);
|
||||
|
||||
aConsts.mAT_EACCESS.Construct(AT_EACCESS);
|
||||
|
||||
aConsts.mO_CREAT.Construct(O_CREAT);
|
||||
aConsts.mO_NONBLOCK.Construct(O_NONBLOCK);
|
||||
aConsts.mO_WRONLY.Construct(O_WRONLY);
|
||||
|
||||
aConsts.mPOLLERR.Construct(POLLERR);
|
||||
aConsts.mPOLLHUP.Construct(POLLHUP);
|
||||
aConsts.mPOLLIN.Construct(POLLIN);
|
||||
aConsts.mPOLLNVAL.Construct(POLLNVAL);
|
||||
aConsts.mPOLLOUT.Construct(POLLOUT);
|
||||
|
||||
aConsts.mWNOHANG.Construct(WNOHANG);
|
||||
|
||||
# ifdef XP_LINUX
|
||||
aConsts.mPR_CAPBSET_READ.Construct(PR_CAPBSET_READ);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* static */
|
||||
void ChromeUtils::OriginAttributesToSuffix(
|
||||
dom::GlobalObject& aGlobal, const dom::OriginAttributesDictionary& aAttrs,
|
||||
|
|
|
@ -226,6 +226,10 @@ class ChromeUtils {
|
|||
JS::Handle<JSObject*> modules,
|
||||
ErrorResult& aRv);
|
||||
|
||||
#ifdef XP_UNIX
|
||||
static void GetLibcConstants(const GlobalObject&, LibcConstants& aConsts);
|
||||
#endif
|
||||
|
||||
static void GetCallerLocation(const GlobalObject& global,
|
||||
nsIPrincipal* principal,
|
||||
JS::MutableHandle<JSObject*> aRetval);
|
||||
|
|
|
@ -289,6 +289,14 @@ namespace ChromeUtils {
|
|||
[Throws]
|
||||
undefined defineLazyGetter(object aTarget, any aName, object aLambda);
|
||||
|
||||
|
||||
#ifdef XP_UNIX
|
||||
/**
|
||||
* Return platform-specific libc constants, such as errno values.
|
||||
*/
|
||||
LibcConstants getLibcConstants();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IF YOU ADD NEW METHODS HERE, MAKE SURE THEY ARE THREAD-SAFE.
|
||||
*/
|
||||
|
@ -1036,3 +1044,36 @@ enum JSRFPTarget {
|
|||
"RoundWindowSize",
|
||||
"SiteSpecificZoom",
|
||||
};
|
||||
|
||||
#ifdef XP_UNIX
|
||||
dictionary LibcConstants {
|
||||
long EINTR;
|
||||
long EACCES;
|
||||
long EAGAIN;
|
||||
long EINVAL;
|
||||
long ENOSYS;
|
||||
|
||||
long F_SETFD;
|
||||
long F_SETFL;
|
||||
|
||||
long FD_CLOEXEC;
|
||||
|
||||
long AT_EACCESS;
|
||||
|
||||
long O_CREAT;
|
||||
long O_NONBLOCK;
|
||||
long O_WRONLY;
|
||||
|
||||
long POLLIN;
|
||||
long POLLOUT;
|
||||
long POLLERR;
|
||||
long POLLHUP;
|
||||
long POLLNVAL;
|
||||
|
||||
long WNOHANG;
|
||||
|
||||
#ifdef XP_LINUX
|
||||
long PR_CAPBSET_READ;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -9,33 +9,10 @@ Services.scriptloader.loadSubScript(
|
|||
this
|
||||
);
|
||||
|
||||
const ERRNO = {
|
||||
EACCES: 13,
|
||||
EINVAL: 22,
|
||||
get ENOSYS() {
|
||||
const os = Services.appinfo.OS;
|
||||
const lazy = {};
|
||||
|
||||
if (["Linux", "Android"].includes(os)) {
|
||||
// https://github.com/torvalds/linux/blob/9a48d604672220545d209e9996c2a1edbb5637f6/include/uapi/asm-generic/errno.h#L18
|
||||
return 38;
|
||||
} else if (
|
||||
["Darwin", "DragonFly", "FreeBSD", "OpenBSD", "NetBSD"].includes(os)
|
||||
) {
|
||||
/*
|
||||
* Darwin: https://opensource.apple.com/source/xnu/xnu-201/bsd/sys/errno.h.auto.html
|
||||
* DragonFly: https://github.com/DragonFlyBSD/DragonFlyBSD/blob/5e488df32cb01056a5b714a522e51c69ab7b4612/sys/sys/errno.h#L172
|
||||
* FreeBSD: https://github.com/freebsd/freebsd-src/blob/7232e6dcc89b978825b30a537bca2e7d3a9b71bb/sys/sys/errno.h#L157
|
||||
* OpenBSD: https://github.com/openbsd/src/blob/025fffe4c6e0113862ce4e1927e67517a2841502/sys/sys/errno.h#L151
|
||||
* NetBSD: https://github.com/NetBSD/src/blob/ff24f695f5f53540b23b6bb4fa5c0b9d79b369e4/sys/sys/errno.h#L137
|
||||
*/
|
||||
return 78;
|
||||
} else if (os === "WINNT") {
|
||||
// https://learn.microsoft.com/en-us/cpp/c-runtime-library/errno-constants?view=msvc-170
|
||||
return 40;
|
||||
}
|
||||
throw new Error("Unsupported OS");
|
||||
},
|
||||
};
|
||||
/* getLibcConstants is only present on *nix */
|
||||
XPCOMUtils.defineLazyGetter(lazy, "LIBC", () => ChromeUtils.getLibcConstants());
|
||||
|
||||
/*
|
||||
* This test is for executing system calls in content processes to validate
|
||||
|
@ -167,20 +144,6 @@ function callFaccessat2(args) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
// open syscall flags
|
||||
function openWriteCreateFlags() {
|
||||
Assert.ok(isMac() || isLinux());
|
||||
if (isMac()) {
|
||||
let O_WRONLY = 0x001;
|
||||
let O_CREAT = 0x200;
|
||||
return O_WRONLY | O_CREAT;
|
||||
}
|
||||
// Linux
|
||||
let O_WRONLY = 0x01;
|
||||
let O_CREAT = 0x40;
|
||||
return O_WRONLY | O_CREAT;
|
||||
}
|
||||
|
||||
// Returns the name of the native library needed for native syscalls
|
||||
function getOSLib() {
|
||||
switch (Services.appinfo.OS) {
|
||||
|
@ -324,7 +287,7 @@ add_task(async function () {
|
|||
if (isLinux() || isMac()) {
|
||||
// open a file for writing in $HOME, this should fail
|
||||
let path = fileInHomeDir().path;
|
||||
let flags = openWriteCreateFlags();
|
||||
let flags = lazy.LIBC.O_CREAT | lazy.LIBC.O_WRONLY;
|
||||
let fd = await SpecialPowers.spawn(
|
||||
browser,
|
||||
[{ lib, path, flags }],
|
||||
|
@ -339,7 +302,7 @@ add_task(async function () {
|
|||
// macOS and work on Linux. The open handler in the content process closes
|
||||
// the file for us
|
||||
let path = fileInTempDir().path;
|
||||
let flags = openWriteCreateFlags();
|
||||
let flags = lazy.LIBC.O_CREAT | lazy.LIBC.O_WRONLY;
|
||||
let fd = await SpecialPowers.spawn(
|
||||
browser,
|
||||
[{ lib, path, flags }],
|
||||
|
@ -390,13 +353,11 @@ add_task(async function () {
|
|||
|
||||
if (isLinux()) {
|
||||
// These constants are not portable.
|
||||
const AT_EACCESS = 512;
|
||||
const PR_CAPBSET_READ = 23;
|
||||
|
||||
// verify we block PR_CAPBSET_READ with EINVAL
|
||||
let option = PR_CAPBSET_READ;
|
||||
let option = lazy.LIBC.PR_CAPBSET_READ;
|
||||
let rv = await SpecialPowers.spawn(browser, [{ lib, option }], callPrctl);
|
||||
ok(rv === ERRNO.EINVAL, "prctl(PR_CAPBSET_READ) is blocked");
|
||||
ok(rv === lazy.LIBC.EINVAL, "prctl(PR_CAPBSET_READ) is blocked");
|
||||
|
||||
const kernelVersion = await getKernelVersion();
|
||||
const glibcVersion = getGlibcVersion();
|
||||
|
@ -412,15 +373,18 @@ add_task(async function () {
|
|||
[{ lib, dirfd, path, mode, flag: 0x01 }],
|
||||
callFaccessat2
|
||||
);
|
||||
ok(rv === ERRNO.ENOSYS, "faccessat2 (flag=0x01) was blocked with ENOSYS");
|
||||
ok(
|
||||
rv === lazy.LIBC.ENOSYS,
|
||||
"faccessat2 (flag=0x01) was blocked with ENOSYS"
|
||||
);
|
||||
|
||||
rv = await SpecialPowers.spawn(
|
||||
browser,
|
||||
[{ lib, dirfd, path, mode, flag: AT_EACCESS }],
|
||||
[{ lib, dirfd, path, mode, flag: lazy.LIBC.AT_EACCESS }],
|
||||
callFaccessat2
|
||||
);
|
||||
ok(
|
||||
rv === ERRNO.EACCES,
|
||||
rv === lazy.LIBC.EACCES,
|
||||
"faccessat2 (flag=0x200) was allowed, errno=EACCES"
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -5,13 +5,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
if (typeof Components !== "undefined") {
|
||||
/* global OS */
|
||||
Cc["@mozilla.org/net/osfileconstantsservice;1"]
|
||||
.getService(Ci.nsIOSFileConstantsService)
|
||||
.init();
|
||||
}
|
||||
|
||||
/* exported LIBC, libc */
|
||||
|
||||
// ctypes is either already available in the chrome worker scope, or defined
|
||||
|
@ -21,7 +14,7 @@ if (typeof Components !== "undefined") {
|
|||
// This file is loaded into the same scope as subprocess_shared.js.
|
||||
/* import-globals-from subprocess_shared.js */
|
||||
|
||||
var LIBC = OS.Constants.libc;
|
||||
var LIBC = ChromeUtils.getLibcConstants();
|
||||
|
||||
const LIBC_CHOICES = ["libc.so", "libSystem.B.dylib", "a.out"];
|
||||
|
||||
|
|
|
@ -5,14 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
if (typeof Components !== "undefined") {
|
||||
/* global OS */
|
||||
Cc["@mozilla.org/net/osfileconstantsservice;1"]
|
||||
.getService(Ci.nsIOSFileConstantsService)
|
||||
.init();
|
||||
}
|
||||
|
||||
/* exported LIBC, Win, createPipe, libc, win32 */
|
||||
/* exported createPipe, libc, win32 */
|
||||
|
||||
// ctypes is either already available in the chrome worker scope, or defined
|
||||
// in scope via loadSubScript.
|
||||
|
@ -21,10 +14,6 @@ if (typeof Components !== "undefined") {
|
|||
// This file is loaded into the same scope as subprocess_shared.js.
|
||||
/* import-globals-from subprocess_shared.js */
|
||||
|
||||
const LIBC = OS.Constants.libc;
|
||||
|
||||
const Win = OS.Constants.Win;
|
||||
|
||||
const LIBC_CHOICES = ["kernel32.dll"];
|
||||
|
||||
var win32 = {
|
||||
|
@ -99,8 +88,13 @@ Object.assign(win32, {
|
|||
ERROR_BROKEN_PIPE: 109,
|
||||
ERROR_INSUFFICIENT_BUFFER: 122,
|
||||
|
||||
FILE_ATTRIBUTE_NORMAL: 0x00000080,
|
||||
FILE_FLAG_OVERLAPPED: 0x40000000,
|
||||
|
||||
GENERIC_WRITE: 0x40000000,
|
||||
|
||||
OPEN_EXISTING: 0x00000003,
|
||||
|
||||
PIPE_TYPE_BYTE: 0x00,
|
||||
|
||||
PIPE_ACCESS_INBOUND: 0x01,
|
||||
|
@ -450,7 +444,7 @@ win32.Handle = function (handle) {
|
|||
|
||||
win32.createPipe = function (secAttr, readFlags = 0, writeFlags = 0, size = 0) {
|
||||
readFlags |= win32.PIPE_ACCESS_INBOUND;
|
||||
writeFlags |= Win.FILE_ATTRIBUTE_NORMAL;
|
||||
writeFlags |= win32.FILE_ATTRIBUTE_NORMAL;
|
||||
|
||||
if (size == 0) {
|
||||
size = 4096;
|
||||
|
@ -471,7 +465,7 @@ win32.createPipe = function (secAttr, readFlags = 0, writeFlags = 0, size = 0) {
|
|||
);
|
||||
|
||||
let isInvalid = handle =>
|
||||
String(handle) == String(win32.HANDLE(Win.INVALID_HANDLE_VALUE));
|
||||
String(handle) == String(win32.INVALID_HANDLE_VALUE);
|
||||
|
||||
if (isInvalid(readHandle)) {
|
||||
return [];
|
||||
|
@ -479,10 +473,10 @@ win32.createPipe = function (secAttr, readFlags = 0, writeFlags = 0, size = 0) {
|
|||
|
||||
let writeHandle = libc.CreateFileW(
|
||||
pipeName,
|
||||
Win.GENERIC_WRITE,
|
||||
win32.GENERIC_WRITE,
|
||||
0,
|
||||
secAttr.address(),
|
||||
Win.OPEN_EXISTING,
|
||||
win32.OPEN_EXISTING,
|
||||
writeFlags,
|
||||
null
|
||||
);
|
||||
|
|
Загрузка…
Ссылка в новой задаче