| 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.
 | 
| 
 |