diff options
author | markus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-24 02:04:13 +0000 |
---|---|---|
committer | markus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-24 02:04:13 +0000 |
commit | 25d353862ce267a5746acac9e604ce6980f88660 (patch) | |
tree | 9c74d34c9efa944328bb37dd862ae05dbed7cefa /sandbox/linux | |
parent | 1ddc110cf3e4f6027c5ecd1fe1f52cefde79d9dd (diff) | |
download | chromium_src-25d353862ce267a5746acac9e604ce6980f88660.zip chromium_src-25d353862ce267a5746acac9e604ce6980f88660.tar.gz chromium_src-25d353862ce267a5746acac9e604ce6980f88660.tar.bz2 |
Treat calls to lstat() and lstat64() the same as calls to stat(). In practise,
this means the calls will still be denied. But we now return a correct return
code.
But more importantly, this change brings the source code in line with the code
of the stand-alone opensource sandbox. Wherever possible, we try to keep both
code bases identical.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/657040
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39837 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/linux')
-rw-r--r-- | sandbox/linux/seccomp/sandbox_impl.h | 6 | ||||
-rw-r--r-- | sandbox/linux/seccomp/stat.cc | 79 | ||||
-rw-r--r-- | sandbox/linux/seccomp/syscall_table.c | 4 |
3 files changed, 72 insertions, 17 deletions
diff --git a/sandbox/linux/seccomp/sandbox_impl.h b/sandbox/linux/seccomp/sandbox_impl.h index 2a7366f..79621d6 100644 --- a/sandbox/linux/seccomp/sandbox_impl.h +++ b/sandbox/linux/seccomp/sandbox_impl.h @@ -112,6 +112,12 @@ class Sandbox { STATIC int sandbox_ipc(unsigned, int, int, int, void*, long) asm("playground$sandbox_ipc"); #endif + STATIC int sandbox_lstat(const char* path, void* buf) + asm("playground$sandbox_lstat"); + #if defined(__NR_lstat64) + STATIC int sandbox_lstat64(const char *path, void* b) + asm("playground$sandbox_lstat64"); + #endif STATIC int sandbox_madvise(void*, size_t, int) asm("playground$sandbox_madvise"); STATIC void *sandbox_mmap(void* start, size_t length, int prot, int flags, diff --git a/sandbox/linux/seccomp/stat.cc b/sandbox/linux/seccomp/stat.cc index 7f958c6..2724144 100644 --- a/sandbox/linux/seccomp/stat.cc +++ b/sandbox/linux/seccomp/stat.cc @@ -30,6 +30,33 @@ int Sandbox::sandbox_stat(const char *path, void *buf) { return static_cast<int>(rc); } +int Sandbox::sandbox_lstat(const char *path, void *buf) { + Debug::syscall(__NR_lstat, "Executing handler"); + size_t len = strlen(path); + struct Request { + int sysnum; + long long cookie; + Stat stat_req; + char pathname[0]; + } __attribute__((packed)) *request; + char data[sizeof(struct Request) + len]; + request = reinterpret_cast<struct Request*>(data); + request->sysnum = __NR_lstat; + request->cookie = cookie(); + request->stat_req.sysnum = __NR_lstat; + request->stat_req.path_length = len; + request->stat_req.buf = buf; + memcpy(request->pathname, path, len); + + long rc; + SysCalls sys; + if (write(sys, processFdPub(), request, sizeof(data)) != (int)sizeof(data) || + read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { + die("Failed to forward lstat() request [sandbox]"); + } + return static_cast<int>(rc); +} + #if defined(__NR_stat64) int Sandbox::sandbox_stat64(const char *path, void *buf) { Debug::syscall(__NR_stat64, "Executing handler"); @@ -57,6 +84,33 @@ int Sandbox::sandbox_stat64(const char *path, void *buf) { } return static_cast<int>(rc); } + +int Sandbox::sandbox_lstat64(const char *path, void *buf) { + Debug::syscall(__NR_lstat64, "Executing handler"); + size_t len = strlen(path); + struct Request { + int sysnum; + long long cookie; + Stat stat_req; + char pathname[0]; + } __attribute__((packed)) *request; + char data[sizeof(struct Request) + len]; + request = reinterpret_cast<struct Request*>(data); + request->sysnum = __NR_lstat64; + request->cookie = cookie(); + request->stat_req.sysnum = __NR_lstat64; + request->stat_req.path_length = len; + request->stat_req.buf = buf; + memcpy(request->pathname, path, len); + + long rc; + SysCalls sys; + if (write(sys, processFdPub(), request, sizeof(data)) != (int)sizeof(data) || + read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) { + die("Failed to forward lstat64() request [sandbox]"); + } + return static_cast<int>(rc); +} #endif bool Sandbox::process_stat(int parentMapsFd, int sandboxFd, int threadFdPub, @@ -85,26 +139,17 @@ bool Sandbox::process_stat(int parentMapsFd, int sandboxFd, int threadFdPub, } return false; } - SecureMem::lockSystemCall(parentMapsFd, mem); - if (read(sys, sandboxFd, mem->pathname, stat_req.path_length) != + + // We implement a strict policy of denying all file accesses + char tmp[stat_req.path_length + 1]; + if (read(sys, sandboxFd, tmp, stat_req.path_length) != (ssize_t)stat_req.path_length) { goto read_parm_failed; } - mem->pathname[stat_req.path_length] = '\000'; - - // TODO(markus): Implement sandboxing policy - Debug::message(("Allowing access to \"" + std::string(mem->pathname) + - "\"").c_str()); - - // Tell trusted thread to stat the file. - SecureMem::sendSystemCall(threadFdPub, true, parentMapsFd, mem, - #if defined(__i386__) - stat_req.sysnum == __NR_stat64 ? __NR_stat64 : - #endif - __NR_stat, - mem->pathname - (char*)mem + (char*)mem->self, - stat_req.buf); - return true; + tmp[stat_req.path_length] = '\000'; + Debug::message(("Denying access to \"" + std::string(tmp) + "\"").c_str()); + SecureMem::abandonSystemCall(threadFd, -EACCES); + return false; } } // namespace diff --git a/sandbox/linux/seccomp/syscall_table.c b/sandbox/linux/seccomp/syscall_table.c index b306b63..731206a 100644 --- a/sandbox/linux/seccomp/syscall_table.c +++ b/sandbox/linux/seccomp/syscall_table.c @@ -73,6 +73,10 @@ const struct SyscallTable syscallTable[] __attribute__(( [ __NR__llseek ] = { UNRESTRICTED_SYSCALL, 0 }, #endif [ __NR_lseek ] = { UNRESTRICTED_SYSCALL, 0 }, + [ __NR_lstat ] = { (void*)&sandbox_lstat, process_stat }, + #if defined(__NR_lstat64) + [ __NR_lstat64 ] = { (void*)&sandbox_lstat64, process_stat }, + #endif [ __NR_madvise ] = { (void*)&sandbox_madvise, process_madvise }, #if defined(__NR_mmap2) [ __NR_mmap2 ] = |