| Index: base/memory/shared_memory_posix.cc
|
| diff --git a/base/memory/shared_memory_posix.cc b/base/memory/shared_memory_posix.cc
|
| index 5d580d08c38c0294485e69a28082094fdcbd211d..2be787d75331d708f9f125ba995f6c42b3691325 100644
|
| --- a/base/memory/shared_memory_posix.cc
|
| +++ b/base/memory/shared_memory_posix.cc
|
| @@ -8,6 +8,7 @@
|
| #include <fcntl.h>
|
| #include <sys/mman.h>
|
| #include <sys/stat.h>
|
| +#include <sys/types.h>
|
| #include <unistd.h>
|
|
|
| #include "base/file_util.h"
|
| @@ -149,12 +150,47 @@ bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
|
| if (!FilePathForMemoryName(*options.name, &path))
|
| return false;
|
|
|
| - fp = file_util::OpenFile(path, "w+x");
|
| - if (fp == NULL && options.open_existing) {
|
| - // "w+" will truncate if it already exists.
|
| - fp = file_util::OpenFile(path, "a+");
|
| + // Make sure that the file is opened without any permission
|
| + // to other users on the system.
|
| + const mode_t kOwnerOnly = S_IRUSR | S_IWUSR;
|
| +
|
| + // First, try to create the file.
|
| + int fd = HANDLE_EINTR(
|
| + open(path.value().c_str(), O_RDWR | O_CREAT | O_EXCL, kOwnerOnly));
|
| + if (fd == -1 && options.open_existing) {
|
| + // If this doesn't work, try and open an existing file in append mode.
|
| + // Opening an existing file in a world writable directory has two main
|
| + // security implications:
|
| + // - Attackers could plant a file under their control, so ownership of
|
| + // the file is checked below.
|
| + // - Attackers could plant a symbolic link so that an unexpected file
|
| + // is opened, so O_NOFOLLOW is passed to open().
|
| + fd = HANDLE_EINTR(
|
| + open(path.value().c_str(), O_RDWR | O_APPEND | O_NOFOLLOW));
|
| +
|
| + // Check that the current user owns the file.
|
| + // If uid != euid, then a more complex permission model is used and this
|
| + // API is not appropriate.
|
| + const uid_t real_uid = getuid();
|
| + const uid_t effective_uid = geteuid();
|
| + struct stat sb;
|
| + if (fd >= 0 &&
|
| + (fstat(fd, &sb) != 0 || sb.st_uid != real_uid ||
|
| + sb.st_uid != effective_uid)) {
|
| + LOG(ERROR) <<
|
| + "Invalid owner when opening existing shared memory file.";
|
| + HANDLE_EINTR(close(fd));
|
| + return false;
|
| + }
|
| +
|
| + // An existing file was opened, so its size should not be fixed.
|
| fix_size = false;
|
| }
|
| + fp = NULL;
|
| + if (fd >= 0) {
|
| + // "a+" is always appropriate: if it's a new file, a+ is similar to w+.
|
| + fp = fdopen(fd, "a+");
|
| + }
|
| }
|
| if (fp && fix_size) {
|
| // Get current size.
|
|
|