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

The change 9d29e96c3b "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.
This commit is contained in:
Jonas 'Sortie' Termansen 2018-09-01 16:37:17 +02:00
parent 5837421478
commit d3a64e1163
2 changed files with 6 additions and 3 deletions

View File

@ -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);
}

View File

@ -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;