forked from Bananymous/banan-os
Kernel/LibC: Implement all chown family function with fchownat
This commit is contained in:
parent
4aa466b948
commit
e431e90b20
|
@ -114,7 +114,7 @@ namespace Kernel
|
||||||
BAN::ErrorOr<long> sys_pread(int fd, void* buffer, size_t count, off_t offset);
|
BAN::ErrorOr<long> sys_pread(int fd, void* buffer, size_t count, off_t offset);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_fchmodat(int fd, const char* path, mode_t mode, int flag);
|
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_fchownat(int fd, const char* path, uid_t uid, gid_t gid, int flag);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_socket(int domain, int type, int protocol);
|
BAN::ErrorOr<long> sys_socket(int domain, int type, int protocol);
|
||||||
BAN::ErrorOr<long> sys_getsockname(int socket, sockaddr* address, socklen_t* address_len);
|
BAN::ErrorOr<long> sys_getsockname(int socket, sockaddr* address, socklen_t* address_len);
|
||||||
|
|
|
@ -1062,14 +1062,39 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_chown(const char* path, uid_t uid, gid_t gid)
|
BAN::ErrorOr<long> Process::sys_fchownat(int fd, const char* path, uid_t uid, gid_t gid, int flag)
|
||||||
{
|
{
|
||||||
LockGuard _(m_process_lock);
|
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||||
TRY(validate_string_access(path));
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
if (flag == AT_SYMLINK_NOFOLLOW)
|
||||||
|
flag = O_NOFOLLOW;
|
||||||
|
|
||||||
auto absolute_path = TRY(absolute_path_of(path));
|
LockGuard _(m_process_lock);
|
||||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_WRONLY));
|
if (path)
|
||||||
TRY(file.inode->chown(uid, gid));
|
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 (uid != -1 && !m_credentials.is_superuser())
|
||||||
|
return BAN::Error::from_errno(EPERM);
|
||||||
|
if (gid != -1 && !m_credentials.is_superuser() && (m_credentials.euid() != uid || !m_credentials.has_egid(gid)))
|
||||||
|
return BAN::Error::from_errno(EPERM);
|
||||||
|
|
||||||
|
if (uid == -1)
|
||||||
|
uid = inode->uid();
|
||||||
|
if (gid == -1)
|
||||||
|
gid = inode->gid();
|
||||||
|
TRY(inode->chown(uid, gid));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ __BEGIN_DECLS
|
||||||
O(SYS_READLINKAT, readlinkat) \
|
O(SYS_READLINKAT, readlinkat) \
|
||||||
O(SYS_MSYNC, msync) \
|
O(SYS_MSYNC, msync) \
|
||||||
O(SYS_PREAD, pread) \
|
O(SYS_PREAD, pread) \
|
||||||
O(SYS_CHOWN, chown) \
|
O(SYS_FCHOWNAT, fchownat) \
|
||||||
O(SYS_LOAD_KEYMAP, load_keymap) \
|
O(SYS_LOAD_KEYMAP, load_keymap) \
|
||||||
O(SYS_SOCKET, socket) \
|
O(SYS_SOCKET, socket) \
|
||||||
O(SYS_BIND, bind) \
|
O(SYS_BIND, bind) \
|
||||||
|
|
|
@ -315,7 +315,22 @@ int chdir(const char* path)
|
||||||
|
|
||||||
int chown(const char* path, uid_t owner, gid_t group)
|
int chown(const char* path, uid_t owner, gid_t group)
|
||||||
{
|
{
|
||||||
return syscall(SYS_CHOWN, path, owner, group);
|
return fchownat(AT_FDCWD, path, owner, group, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lchown(const char* path, uid_t owner, gid_t group)
|
||||||
|
{
|
||||||
|
return fchownat(AT_FDCWD, path, owner, group, AT_SYMLINK_NOFOLLOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fchown(int fildes, uid_t owner, gid_t group)
|
||||||
|
{
|
||||||
|
return fchownat(fildes, nullptr, owner, group, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fchownat(int fd, const char* path, uid_t owner, gid_t group, int flag)
|
||||||
|
{
|
||||||
|
return syscall(SYS_FCHOWNAT, fd, path, owner, group, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sync(void)
|
void sync(void)
|
||||||
|
|
Loading…
Reference in New Issue