Commit d3a64e11 authored by Jonas Termansen's avatar Jonas Termansen

Fix chmod(2), chown(2), and utimens(2) opening the path for writing.

The change 9d29e96c "Fix open(2) allowing
opening directories invalidly and check O_TRUNC errors." broke the chmod(2),
chown(2), and utimens(2) system calls on directories, because they can no
longer be opened for writing.

This changes fixes the regression by opening such paths for reading. There
is currently no filesystem permission checks for those system calls. However,
those system calls should check the permissions at the time of the operation
rather than relying on the file having been opened for writing previously.
parent 58374214
......@@ -256,11 +256,13 @@ int Descriptor::statvfs(ioctx_t* ctx, struct statvfs* stvfs)
int Descriptor::chmod(ioctx_t* ctx, mode_t mode)
{
// TODO: Regardless of dflags, check if the user/group can chmod.
return vnode->chmod(ctx, mode);
}
int Descriptor::chown(ioctx_t* ctx, uid_t owner, gid_t group)
{
// TODO: Regardless of dflags, check if the user/group can chown.
return vnode->chown(ctx, owner, group);
}
......@@ -597,6 +599,7 @@ int Descriptor::utimens(ioctx_t* ctx, const struct timespec* user_times)
if ( !valid_utimens_timespec(times[0]) ||
!valid_utimens_timespec(times[1]) )
return errno = EINVAL;
// TODO: Regardless of dflags, check if the user/group can utimens.
return vnode->utimens(ctx, times);
}
......
......@@ -464,7 +464,7 @@ int sys_fchownat(int dirfd, const char* path, uid_t owner, gid_t group, int flag
ioctx_t ctx; SetupUserIOCtx(&ctx);
Ref<Descriptor> from = PrepareLookup(pathcopy, dirfd);
if ( !from ) { delete[] pathcopy; return -1; }
int open_flags = O_WRITE | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0);
int open_flags = O_READ | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0);
Ref<Descriptor> desc = from->open(&ctx, pathcopy, open_flags);
from.Reset();
delete[] pathcopy;
......@@ -512,7 +512,7 @@ int sys_fchmodat(int dirfd, const char* path, mode_t mode, int flags)
ioctx_t ctx; SetupUserIOCtx(&ctx);
Ref<Descriptor> from = PrepareLookup(pathcopy, dirfd);
if ( !from ) { delete[] pathcopy; return -1; }
int open_flags = O_WRITE | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0);
int open_flags = O_READ | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0);
Ref<Descriptor> desc = from->open(&ctx, pathcopy, open_flags);
from.Reset();
delete[] pathcopy;
......@@ -541,7 +541,7 @@ int sys_utimensat(int dirfd, const char* path,
ioctx_t ctx; SetupUserIOCtx(&ctx);
Ref<Descriptor> from = PrepareLookup(pathcopy, dirfd);
if ( !from ) { delete[] pathcopy; return -1; }
int open_flags = O_WRITE | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0);
int open_flags = O_READ | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0);
Ref<Descriptor> desc = from->open(&ctx, pathcopy, open_flags);
from.Reset();
delete[] pathcopy;
......
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