author | Jed Davis <jld@mozilla.com> |
Tue, 08 Aug 2017 18:02:31 -0600 (2017-08-09) | |
changeset 373707 | c0838ed418422fa3ae21a6471bc33716dfc704f6 |
parent 373706 | 9499e1097909f47eb42c3e50c836eec8d37d6fb0 |
child 373708 | 7bafc0f1dbe498827fcad7089885f09444adc3ec |
push id | 32308 |
push user | archaeopteryx@coole-files.de |
push date | Thu, 10 Aug 2017 15:20:33 +0000 (2017-08-10) |
treeherder | mozilla-central@5322c03f4c85 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | gcp |
bugs | 1386279, 1382246 |
milestone | 57.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
security/sandbox/linux/broker/SandboxBroker.cpp | file | annotate | diff | comparison | revisions | |
security/sandbox/linux/gtest/TestBroker.cpp | file | annotate | diff | comparison | revisions |
--- a/security/sandbox/linux/broker/SandboxBroker.cpp +++ b/security/sandbox/linux/broker/SandboxBroker.cpp @@ -338,17 +338,17 @@ AllowOperation(int aReqFlags, int aPerms needed |= SandboxBroker::MAY_CREATE; } return (aPerms & needed) == needed; } static bool AllowAccess(int aReqFlags, int aPerms) { - if (aReqFlags & ~(R_OK|W_OK|F_OK)) { + if (aReqFlags & ~(R_OK|W_OK|X_OK|F_OK)) { return false; } int needed = 0; if (aReqFlags & R_OK) { needed |= SandboxBroker::MAY_READ; } if (aReqFlags & W_OK) { needed |= SandboxBroker::MAY_WRITE; @@ -657,27 +657,17 @@ SandboxBroker::ThreadMain(void) } } else { AuditDenial(req.mOp, req.mFlags, perms, pathBuf); } break; case SANDBOX_FILE_ACCESS: if (permissive || AllowAccess(req.mFlags, perms)) { - // This can't use access() itself because that uses the ruid - // and not the euid. In theory faccessat() with AT_EACCESS - // would work, but Linux doesn't actually implement the - // flags != 0 case; glibc has a hack which doesn't even work - // in this case so it'll ignore the flag, and Bionic just - // passes through the syscall and always ignores the flags. - // - // Instead, because we've already checked the requested - // r/w/x bits against the policy, just return success if the - // file exists and hope that's close enough. - if (stat(pathBuf, (struct stat*)&respBuf) == 0) { + if (access(pathBuf, req.mFlags) == 0) { resp.mError = 0; } else { resp.mError = -errno; } } else { AuditDenial(req.mOp, req.mFlags, perms, pathBuf); } break;
--- a/security/sandbox/linux/gtest/TestBroker.cpp +++ b/security/sandbox/linux/gtest/TestBroker.cpp @@ -128,16 +128,18 @@ SandboxBrokerTest::GetPolicy() const policy->AddPath(MAY_READ | MAY_WRITE, "/dev/null", AddAlways); policy->AddPath(MAY_READ, "/dev/zero", AddAlways); policy->AddPath(MAY_READ, "/var/empty/qwertyuiop", AddAlways); policy->AddPath(MAY_ACCESS, "/proc/self", AddAlways); // Warning: Linux-specific. policy->AddPath(MAY_READ | MAY_WRITE, "/tmp", AddAlways); policy->AddPath(MAY_READ | MAY_WRITE | MAY_CREATE, "/tmp/blublu", AddAlways); policy->AddPath(MAY_READ | MAY_WRITE | MAY_CREATE, "/tmp/blublublu", AddAlways); + // This should be non-writable by the user running the test: + policy->AddPath(MAY_READ | MAY_WRITE, "/etc", AddAlways); return Move(policy); } TEST_F(SandboxBrokerTest, OpenForRead) { int fd; @@ -201,16 +203,24 @@ TEST_F(SandboxBrokerTest, Access) EXPECT_EQ(-ENOENT, Access("/var/empty/qwertyuiop", R_OK)); EXPECT_EQ(-EACCES, Access("/var/empty/qwertyuiop", W_OK)); EXPECT_EQ(0, Access("/proc/self", F_OK)); EXPECT_EQ(-EACCES, Access("/proc/self", R_OK)); EXPECT_EQ(-EACCES, Access("/proc/self/stat", F_OK)); + + EXPECT_EQ(0, Access("/tmp", X_OK)); + EXPECT_EQ(0, Access("/tmp", R_OK|X_OK)); + EXPECT_EQ(0, Access("/tmp", R_OK|W_OK|X_OK)); + EXPECT_EQ(0, Access("/proc/self", X_OK)); + + EXPECT_EQ(0, Access("/etc", R_OK|X_OK)); + EXPECT_EQ(-EACCES, Access("/etc", W_OK)); } TEST_F(SandboxBrokerTest, Stat) { statstruct realStat, brokeredStat; ASSERT_EQ(0, statsyscall("/dev/null", &realStat)) << "Shouldn't ever fail!"; EXPECT_EQ(0, Stat("/dev/null", &brokeredStat)); EXPECT_EQ(realStat.st_ino, brokeredStat.st_ino); @@ -252,20 +262,17 @@ TEST_F(SandboxBrokerTest, Chmod) { PrePostTestCleanup(); int fd = Open("/tmp/blublu", O_WRONLY | O_CREAT); ASSERT_GE(fd, 0) << "Opening /tmp/blublu for writing failed."; close(fd); // Set read only. SandboxBroker enforces 0600 mode flags. ASSERT_EQ(0, Chmod("/tmp/blublu", S_IRUSR)); - // SandboxBroker doesn't use real access(), it just checks against - // the policy. So it can't see the change in permisions here. - // This won't work: - // EXPECT_EQ(-EACCES, Access("/tmp/blublu", W_OK)); + EXPECT_EQ(-EACCES, Access("/tmp/blublu", W_OK)); statstruct realStat; EXPECT_EQ(0, statsyscall("/tmp/blublu", &realStat)); EXPECT_EQ((mode_t)S_IRUSR, realStat.st_mode & 0777); ASSERT_EQ(0, Chmod("/tmp/blublu", S_IRUSR | S_IWUSR)); EXPECT_EQ(0, statsyscall("/tmp/blublu", &realStat)); EXPECT_EQ((mode_t)(S_IRUSR | S_IWUSR), realStat.st_mode & 0777); EXPECT_EQ(0, unlink("/tmp/blublu"));