Commit 6874b75d authored by binji's avatar binji Committed by Commit bot

[NaCl SDK] nacl_io: Add umask

The default umask() implemented by libnacl returns 0777, which if actually
used, would create files with 0 mode.

BUG=none
R=sbc@chromium.org

Review URL: https://codereview.chromium.org/643543004

Cr-Commit-Position: refs/heads/master@{#299921}
parent 7ec19e14
......@@ -324,7 +324,7 @@ Error DevFs::Init(const FsInitArgs& args) {
if (error)
return error;
root_.reset(new DirNode(this));
root_.reset(new DirNode(this, S_IRALL | S_IXALL));
ScopedNode new_node;
INITIALIZE_DEV_NODE("/null", NullNode);
......@@ -348,7 +348,7 @@ Error DevFs::Init(const FsInitArgs& args) {
// Add a directory for "fs" nodes; they represent all currently-mounted
// filesystems. We can ioctl these nodes to make changes or provide input to
// a mounted filesystem.
INITIALIZE_DEV_NODE("/fs", DirNode);
INITIALIZE_DEV_NODE_1("/fs", DirNode, S_IRALL | S_IWALL | S_IXALL);
fs_dir_ = new_node;
return 0;
......
......@@ -22,13 +22,12 @@ namespace {
const ino_t kParentDirIno = -1;
}
DirNode::DirNode(Filesystem* filesystem)
DirNode::DirNode(Filesystem* filesystem, mode_t mode)
: Node(filesystem),
cache_(stat_.st_ino, kParentDirIno),
cache_built_(false) {
SetType(S_IFDIR);
// Directories are raadable, writable and executable by default.
stat_.st_mode |= S_IRALL | S_IWALL | S_IXALL;
SetMode(mode);
}
DirNode::~DirNode() {
......
......@@ -24,7 +24,7 @@ typedef sdk_util::ScopedRef<DirNode> ScopedDirNode;
class DirNode : public Node {
protected:
explicit DirNode(Filesystem* fs);
explicit DirNode(Filesystem* fs, mode_t mode);
virtual ~DirNode();
public:
......
......@@ -254,12 +254,10 @@ Error HttpFs::FindOrCreateDir(const Path& path, ScopedNode* out_node) {
}
// If the node does not exist, create it.
node.reset(new DirNode(this));
node.reset(new DirNode(this, S_IRALL | S_IXALL));
Error error = node->Init(0);
if (error)
return error;
// Directorys in http filesystems are never writable.
node->SetMode(node->GetMode() & ~S_IWALL);
// If not the root node, find the parent node and add it to the parent
if (!path.IsRoot()) {
......
......@@ -427,6 +427,11 @@ int ki_futimens(int fd, const struct timespec times[2]) {
return s_state.kp->futimens(fd, times);
}
mode_t ki_umask(mode_t mask) {
ON_NOSYS_RETURN(0);
return s_state.kp->umask(mask);
}
int ki_poll(struct pollfd* fds, nfds_t nfds, int timeout) {
return s_state.kp->poll(fds, nfds, timeout);
}
......
......@@ -123,6 +123,7 @@ int ki_fchown(int fd, uid_t owner, gid_t group);
int ki_lchown(const char* path, uid_t owner, gid_t group);
int ki_utime(const char* filename, const struct utimbuf* times);
int ki_futimens(int fd, const struct timespec times[2]);
mode_t ki_umask(mode_t mask);
int ki_poll(struct pollfd* fds, nfds_t nfds, int timeout);
int ki_select(int nfds,
......
......@@ -25,7 +25,7 @@
namespace nacl_io {
KernelObject::KernelObject() {
KernelObject::KernelObject() : umask_(0) {
cwd_ = "/";
}
......@@ -155,6 +155,17 @@ Error KernelObject::SetCWD(const std::string& path) {
return 0;
}
mode_t KernelObject::GetUmask() {
return umask_;
}
mode_t KernelObject::SetUmask(mode_t newmask) {
AUTO_LOCK(umask_lock_);
mode_t oldmask = umask_;
umask_ = newmask & 0777;
return oldmask;
}
Error KernelObject::GetFDFlags(int fd, int* out_flags) {
AUTO_LOCK(handle_lock_);
if (fd < 0 || fd >= static_cast<int>(handle_map_.size()))
......
......@@ -94,11 +94,16 @@ class KernelObject {
std::string GetCWD();
Error SetCWD(const std::string& path);
mode_t GetUmask();
// Also returns current umask (like POSIX's umask(2))
mode_t SetUmask(mode_t);
// Returns parts of the absolute path for the given relative path
Path GetAbsParts(const std::string& path);
private:
std::string cwd_;
mode_t umask_;
std::vector<int> free_fds_;
HandleMap_t handle_map_;
FsMap_t filesystems_;
......@@ -111,6 +116,8 @@ class KernelObject {
// Lock to protect cwd_.
sdk_util::SimpleLock cwd_lock_;
// Lock to protect umask_.
sdk_util::SimpleLock umask_lock_;
DISALLOW_COPY_AND_ASSIGN(KernelObject);
};
......
......@@ -209,8 +209,9 @@ int KernelProxy::open_resource(const char* path) {
int KernelProxy::open(const char* path, int open_flags, mode_t mode) {
ScopedFilesystem fs;
ScopedNode node;
mode_t mask = ~GetUmask();
Error error = AcquireFsAndNode(path, open_flags, mode, &fs, &node);
Error error = AcquireFsAndNode(path, open_flags, mode & mask, &fs, &node);
if (error) {
errno = error;
return -1;
......@@ -371,7 +372,7 @@ int KernelProxy::mkdir(const char* path, mode_t mode) {
return -1;
}
error = fs->Mkdir(rel, mode);
error = fs->Mkdir(rel, mode & ~GetUmask());
if (error) {
errno = error;
return -1;
......@@ -1182,6 +1183,10 @@ int KernelProxy::sigaction(int signum,
return -1;
}
mode_t KernelProxy::umask(mode_t mask) {
return SetUmask(mask);
}
#ifdef PROVIDES_SOCKET_API
int KernelProxy::select(int nfds,
......
......@@ -157,6 +157,7 @@ class KernelProxy : protected KernelObject {
virtual int sigaction(int signum,
const struct sigaction* action,
struct sigaction* oaction);
virtual mode_t umask(mode_t);
#ifdef PROVIDES_SOCKET_API
virtual int select(int nfds,
......
......@@ -137,6 +137,7 @@
"syscalls/termios/tcsetattr.c",
"syscalls/symlink.c",
"syscalls/truncate.c",
"syscalls/umask.c",
"syscalls/umount.c",
"syscalls/uname.c",
"syscalls/utime.c",
......
......@@ -29,7 +29,7 @@ Error MemFs::Init(const FsInitArgs& args) {
if (error)
return error;
root_.reset(new DirNode(this));
root_.reset(new DirNode(this, S_IRALL | S_IWALL | S_IXALL));
error = root_->Init(0);
if (error) {
root_.reset(NULL);
......@@ -146,7 +146,7 @@ Error MemFs::Mkdir(const Path& path, int mode) {
// Allocate a node, with a RefCount of 1. If added to the parent
// it will get ref counted again. In either case, release the
// recount we have on exit.
node.reset(new DirNode(this));
node.reset(new DirNode(this, mode));
error = node->Init(0);
if (error)
return error;
......
/* Copyright (c) 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
#include "nacl_io/kernel_intercept.h"
#include "nacl_io/kernel_wrap.h"
mode_t umask(mode_t mask) {
return ki_umask(mask);
}
......@@ -636,6 +636,26 @@ TEST_F(KernelProxyTest, Utime) {
EXPECT_GE(buf.st_mtimensec, tm.tv_usec * 1000);
}
TEST_F(KernelProxyTest, Umask) {
mode_t oldmask = ki_umask(0222);
EXPECT_EQ(0, oldmask);
int fd = ki_open("/foo", O_CREAT | O_RDONLY, 0666);
ASSERT_GT(fd, -1);
ki_close(fd);
EXPECT_EQ(0, ki_mkdir("/dir", 0777));
struct stat buf;
EXPECT_EQ(0, ki_stat("/foo", &buf));
EXPECT_EQ(0444, buf.st_mode & ~S_IFMT);
EXPECT_EQ(0, ki_stat("/dir", &buf));
EXPECT_EQ(0555, buf.st_mode & ~S_IFMT);
EXPECT_EQ(0222, ki_umask(0));
}
namespace {
StringMap_t g_string_map;
......
......@@ -62,7 +62,9 @@ class MemFsNodeForTesting : public MemFsNode {
class DirNodeForTesting : public DirNode {
public:
DirNodeForTesting() : DirNode(NULL) { s_alloc_num++; }
DirNodeForTesting() : DirNode(NULL, S_IRALL | S_IWALL | S_IXALL) {
s_alloc_num++;
}
~DirNodeForTesting() { s_alloc_num--; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment