Kernel/LibC: Implement all chmod family functions using fchmodat
This commit is contained in:
parent
04ae53b6df
commit
4aa466b948
|
@ -113,8 +113,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<long> sys_pread(int fd, void* buffer, size_t count, off_t offset);
|
||||
|
||||
BAN::ErrorOr<long> sys_chmod(const char* path, mode_t mode);
|
||||
BAN::ErrorOr<long> sys_fchmod(int fildes, mode_t mode);
|
||||
BAN::ErrorOr<long> sys_fchmodat(int fd, const char* path, mode_t mode, int flag);
|
||||
BAN::ErrorOr<long> sys_chown(const char* path, uid_t uid, gid_t gid);
|
||||
|
||||
BAN::ErrorOr<long> sys_socket(int domain, int type, int protocol);
|
||||
|
|
|
@ -1026,28 +1026,37 @@ namespace Kernel
|
|||
return TRY(inode->read(offset, { (uint8_t*)buffer, count }));
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_chmod(const char* path, mode_t mode)
|
||||
BAN::ErrorOr<long> Process::sys_fchmodat(int fd, const char* path, mode_t mode, int flag)
|
||||
{
|
||||
if (mode & S_IFMASK)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
LockGuard _(m_process_lock);
|
||||
TRY(validate_string_access(path));
|
||||
|
||||
auto absolute_path = TRY(absolute_path_of(path));
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_WRONLY));
|
||||
TRY(file.inode->chmod(mode));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_fchmod(int fildes, mode_t mode)
|
||||
{
|
||||
if (mode & S_IFMASK)
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
if (flag == AT_SYMLINK_NOFOLLOW)
|
||||
flag = O_NOFOLLOW;
|
||||
|
||||
LockGuard _(m_process_lock);
|
||||
auto inode = TRY(m_open_file_descriptors.inode_of(fildes));
|
||||
if (path)
|
||||
TRY(validate_string_access(path));
|
||||
|
||||
VirtualFileSystem::File parent_file;
|
||||
if (path && path[0] == '/')
|
||||
parent_file = VirtualFileSystem::get().root_file();
|
||||
else if (fd == AT_FDCWD)
|
||||
parent_file = TRY(m_working_directory.clone());
|
||||
else
|
||||
parent_file = TRY(m_open_file_descriptors.file_of(fd));
|
||||
|
||||
auto inode = path
|
||||
? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flag)).inode
|
||||
: parent_file.inode;
|
||||
|
||||
if (!m_credentials.is_superuser() && inode->uid() != m_credentials.euid())
|
||||
{
|
||||
dwarnln("cannot chmod uid {} vs {}", inode->uid(), m_credentials.euid());
|
||||
return BAN::Error::from_errno(EPERM);
|
||||
}
|
||||
|
||||
TRY(inode->chmod(mode));
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -51,8 +51,7 @@ __BEGIN_DECLS
|
|||
O(SYS_MUNMAP, munmap) \
|
||||
O(SYS_TTY_CTRL, tty_ctrl) \
|
||||
O(SYS_POWEROFF, poweroff) \
|
||||
O(SYS_CHMOD, chmod) \
|
||||
O(SYS_FCHMOD, fchmod) \
|
||||
O(SYS_FCHMODAT, fchmodat) \
|
||||
O(SYS_CREATE_DIR, create_dir) \
|
||||
O(SYS_UNLINK, unlink) \
|
||||
O(SYS_READLINKAT, readlinkat) \
|
||||
|
|
|
@ -9,12 +9,17 @@ mode_t __umask = 0;
|
|||
|
||||
int chmod(const char* path, mode_t mode)
|
||||
{
|
||||
return syscall(SYS_CHMOD, path, mode);
|
||||
return fchmodat(AT_FDCWD, path, mode, 0);
|
||||
}
|
||||
|
||||
int fchmod(int fildes, mode_t mode)
|
||||
{
|
||||
return syscall(SYS_FCHMOD, fildes, mode);
|
||||
return fchmodat(fildes, nullptr, mode, 0);
|
||||
}
|
||||
|
||||
int fchmodat(int fildes, const char* path, mode_t mode, int flag)
|
||||
{
|
||||
return syscall(SYS_FCHMODAT, fildes, path, mode, flag);
|
||||
}
|
||||
|
||||
int fstat(int fildes, struct stat* buf)
|
||||
|
|
Loading…
Reference in New Issue