add *chmod, and *chown syscalls

This commit is contained in:
Florian Fischer
2024-01-19 14:56:29 +01:00
parent 9ee6421e1b
commit 61024ac3f3
9 changed files with 230 additions and 9 deletions
+4 -4
View File
@@ -30,8 +30,8 @@ If the column is empty it means that it's not implemented yet.
2 | 12 | sys_chdir | process/process.c | const char * | - | - | - | - |
2 | 13 | sys_time | klib/time.c | int * | - | - | - | - |
| 14 | sys_mknod | | const char * | int | dev_t | - | - |
| 15 | sys_chmod | | const char * | mode_t | - | - | - |
| 16 | sys_lchown | | const char * | uid_t | gid_t | - | - |
1 | 15 | sys_chmod | fs/attr.c | const char * | mode_t | - | - | - |
| 16 | sys_lchown | fs/attr.c | const char * | uid_t | gid_t | - | - |
2 | 18 | sys_stat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
2 | 19 | sys_lseek | fs/read_write.c | unsigned int | off_t | unsigned int | - | - |
2 | 20 | sys_getpid | process/scheduler.c | - | - | - | - | - |
@@ -101,7 +101,7 @@ If the column is empty it means that it's not implemented yet.
| 92 | sys_truncate | | const char * | unsigned long | - | - | - |
| 93 | sys_ftruncate | | unsigned int | unsigned long | - | - | - |
| 94 | sys_fchmod | | unsigned int | mode_t | - | - | - |
| 95 | sys_fchown | | unsigned int | uid_t | gid_t | - | - |
1 | 95 | sys_fchown | fs/attr.c | unsigned int | uid_t | gid_t | - | - |
| 96 | sys_getpriority | | int | int | - | - | - |
| 97 | sys_setpriority | | int | int | int | - | - |
| 99 | sys_statfs | | const char * | struct statfs * | - | - | - |
@@ -186,7 +186,7 @@ If the column is empty it means that it's not implemented yet.
| 179 | sys_rt_sigsuspend | | sigset_t * | size_t | - | - | - |
| 180 | sys_pread | | unsigned int | char * | size_t | loff_t | - |
| 181 | sys_pwrite | | unsigned int | const char * | size_t | loff_t | - |
| 182 | sys_chown | | const char * | uid_t | gid_t | - | - |
1 | 182 | sys_chown | vfs/attr.c | const char * | uid_t | gid_t | - | - |
1 | 183 | sys_getcwd | process/process.c | char * | unsigned long | - | - | - |
| 184 | sys_capget | | cap_user_header_t | cap_user_data_t | - | - | - |
| 185 | sys_capset | | cap_user_header_t | const cap_user_data_t | - | - | - |
+2
View File
@@ -33,6 +33,8 @@ add_library(
${CMAKE_SOURCE_DIR}/libc/src/sys/utsname.c
${CMAKE_SOURCE_DIR}/libc/src/sys/mman.c
${CMAKE_SOURCE_DIR}/libc/src/sys/ioctl.c
${CMAKE_SOURCE_DIR}/libc/src/unistd/chmod.c
${CMAKE_SOURCE_DIR}/libc/src/unistd/chown.c
${CMAKE_SOURCE_DIR}/libc/src/unistd/creat.c
${CMAKE_SOURCE_DIR}/libc/src/unistd/getppid.c
${CMAKE_SOURCE_DIR}/libc/src/unistd/getpid.c
+38
View File
@@ -288,3 +288,41 @@ int dup(int fd);
/// previous request would have generated a SIGALRM signal. Otherwise, alarm()
/// shall return 0.
unsigned alarm(int seconds);
/// @brief Change the file's mode bits.
/// @param pathname The pathname of the file to change mode.
/// @param mode The mode bits to set.
/// @return On success, 0 is returned.
/// On error, -1 is returned, and errno is set appropriately.
int chmod(const char *pathname, mode_t mode);
/// @brief Change the file's mode bits.
/// @param fd The fd pointing to the opened file.
/// @param mode The mode bits to set.
/// @return On success, 0 is returned.
/// On error, -1 is returned, and errno is set appropriately.
int fchmod(int fd, mode_t mode);
/// @brief Change the owner and group of a file.
/// @param pathname The pathname of the file to change.
/// @param owner The new owner to set.
/// @param owner The new group to set.
/// @return On success, 0 is returned.
/// On error, -1 is returned, and errno is set appropriately.
int chown(const char *pathname, uid_t owner, gid_t group);
/// @brief Change the owner and group of a file.
/// @param fd The fd pointing to the opened file.
/// @param owner The new owner to set.
/// @param owner The new group to set.
/// @return On success, 0 is returned.
/// On error, -1 is returned, and errno is set appropriately.
int fchown(int fd, uid_t owner, gid_t group);
/// @brief Change the owner and group of a file.
/// @param pathname The pathname of the file to change.
/// @param owner The new owner to set.
/// @param owner The new group to set.
/// @return On success, 0 is returned.
/// On error, -1 is returned, and errno is set appropriately.
int lchown(const char *pathname, uid_t owner, gid_t group);
+12
View File
@@ -0,0 +1,12 @@
/// @file chmod.c
/// @brief
/// @copyright (c) 2024 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/unistd.h"
#include "sys/errno.h"
#include "system/syscall_types.h"
_syscall2(int, chmod, const char *, pathname, mode_t, mode)
_syscall2(int, fchmod, int, fd, mode_t, mode)
+14
View File
@@ -0,0 +1,14 @@
/// @file chown.c
/// @brief
/// @copyright (c) 2024 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/unistd.h"
#include "sys/errno.h"
#include "system/syscall_types.h"
_syscall3(int, chown, const char *, pathname, uid_t, owner, gid_t, group)
_syscall3(int, lchown, const char *, pathname, uid_t, owner, gid_t, group)
_syscall3(int, fchown, int, fd, uid_t, owner, gid_t, group)
+1
View File
@@ -38,6 +38,7 @@ set(KERNEL_SOURCES
${CMAKE_SOURCE_DIR}/mentos/src/drivers/ps2.c
${CMAKE_SOURCE_DIR}/mentos/src/drivers/keyboard/keyboard.c
${CMAKE_SOURCE_DIR}/mentos/src/drivers/keyboard/keymap.c
${CMAKE_SOURCE_DIR}/mentos/src/fs/attr.c
${CMAKE_SOURCE_DIR}/mentos/src/fs/vfs.c
${CMAKE_SOURCE_DIR}/mentos/src/fs/read_write.c
${CMAKE_SOURCE_DIR}/mentos/src/fs/open.c
+16
View File
@@ -0,0 +1,16 @@
/// @file attr.h
/// @brief change file attributes
/// @copyright (c) 2024 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "stddef.h"
int sys_chown(const char* path, uid_t owner, gid_t group);
int sys_lchown(const char* path, uid_t owner, gid_t group);
int sys_fchown(int fd, uid_t owner, gid_t group);
int sys_chmod(const char* path, mode_t mode);
int sys_fchmod(int fd, mode_t mode);
+137
View File
@@ -0,0 +1,137 @@
/// @file attr.c
/// @brief change file attributes
/// @copyright (c) 2014-2024 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "libgen.h"
#include "process/scheduler.h"
#include "fcntl.h"
#include "fs/vfs.h"
#include "io/debug.h"
#include "limits.h"
#include "process/process.h"
#include "stdio.h"
#include "string.h"
#include "sys/errno.h"
#include "system/printk.h"
#include "system/syscall.h"
static int __setattr(const char *path, struct iattr* attr, bool_t follow_links) {
// Allocate a variable for the path.
char absolute_path[PATH_MAX];
if (!realpath(path, absolute_path, sizeof(absolute_path))) {
pr_err("sys_chown(%s): Cannot get the absolute path.", path);
return -ENOENT;
}
super_block_t *sb = vfs_get_superblock(absolute_path);
if (sb == NULL) {
pr_err("do_chown(%s): Cannot find the superblock!\n", absolute_path);
return -ENOENT;
}
vfs_file_t *sb_root = sb->root;
if (sb_root == NULL) {
pr_err("do_chown(%s): Cannot find the superblock root!\n", absolute_path);
return -ENOENT;
}
// TODO: resolve links
// Check if the function is implemented.
if (sb_root->sys_operations->setattr_f == NULL) {
pr_err("setattr(%s): Function not supported in current filesystem.", absolute_path);
return -ENOSYS;
}
return sb_root->sys_operations->setattr_f(absolute_path, attr);
}
static inline void __iattr_set_owner_or_group(struct iattr *attr, uid_t owner, gid_t group) {
if (owner != -1) {
attr->ia_valid |= ATTR_UID;
attr->ia_uid = owner;
}
if (group != -1) {
attr->ia_valid |= ATTR_GID;
attr->ia_gid = group;
}
}
int sys_chown(const char* path, uid_t owner, gid_t group) {
struct iattr attr = {0};
__iattr_set_owner_or_group(&attr, owner, group);
return __setattr(path, &attr, true);
}
int sys_lchown(const char* path, uid_t owner, gid_t group) {
struct iattr attr = {0};
__iattr_set_owner_or_group(&attr, owner, group);
return __setattr(path, &attr, false);
}
int sys_fchown(int fd, uid_t owner, gid_t group) {
task_struct *task = scheduler_get_current_process();
// Check the current FD.
if (fd < 0 || fd >= task->max_fd) {
return -EBADF;
}
// Get the file.
vfs_file_t *file = task->fd_list[fd].file_struct;
if (file == NULL) {
return -EBADF;
}
if (!(task->uid == 0) || (task->uid == file->uid)) {
return -EPERM;
}
if (owner != -1) {
file->uid = owner;
}
if (group != -1) {
file->gid = group;
}
if (file->fs_operations->setattr_f == NULL) {
pr_err("No setattr function found for the current filesystem.\n");
return -ENOSYS;
}
struct iattr attr = {0};
__iattr_set_owner_or_group(&attr, owner, group);
return file->fs_operations->setattr_f(file, &attr);
}
int sys_chmod(const char* path, mode_t mode) {
struct iattr attr = IATTR_CHMOD(mode);
return __setattr(path, &attr, true);
}
int sys_fchmod(int fd, mode_t mode) {
task_struct *task = scheduler_get_current_process();
// Check the current FD.
if (fd < 0 || fd >= task->max_fd) {
return -EBADF;
}
// Get the file.
vfs_file_t *file = task->fd_list[fd].file_struct;
if (file == NULL) {
return -EBADF;
}
if (!(task->uid == 0) || (task->uid == file->uid)) {
return -EPERM;
}
file->mask &= 0xFFFFFFFF & mode;
if (file->fs_operations->setattr_f == NULL) {
pr_err("No setattr function found for the current filesystem.\n");
return -ENOSYS;
}
struct iattr attr = IATTR_CHMOD(mode);
return file->fs_operations->setattr_f(file, &attr);
}
+6 -5
View File
@@ -13,6 +13,7 @@
#include "descriptor_tables/isr.h"
#include "devices/fpu.h"
#include "fs/attr.h"
#include "fs/vfs.h"
#include "fs/ioctl.h"
#include "hardware/timer.h"
@@ -70,8 +71,8 @@ void syscall_init(void)
sys_call_table[__NR_chdir] = (SystemCall)sys_chdir;
sys_call_table[__NR_time] = (SystemCall)sys_time;
sys_call_table[__NR_mknod] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_chmod] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_lchown] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_chmod] = (SystemCall)sys_chmod;
sys_call_table[__NR_lchown] = (SystemCall)sys_lchown;
sys_call_table[__NR_stat] = (SystemCall)sys_stat;
sys_call_table[__NR_lseek] = (SystemCall)sys_lseek;
sys_call_table[__NR_getpid] = (SystemCall)sys_getpid;
@@ -140,8 +141,8 @@ void syscall_init(void)
sys_call_table[__NR_munmap] = (SystemCall)sys_munmap;
sys_call_table[__NR_truncate] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_ftruncate] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_fchmod] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_fchown] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_fchmod] = (SystemCall)sys_fchmod;
sys_call_table[__NR_fchown] = (SystemCall)sys_fchown;
sys_call_table[__NR_getpriority] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_setpriority] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_statfs] = (SystemCall)sys_ni_syscall;
@@ -226,7 +227,7 @@ void syscall_init(void)
sys_call_table[__NR_rt_sigsuspend] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_pread] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_pwrite] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_chown] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_chown] = (SystemCall)sys_chown;
sys_call_table[__NR_getcwd] = (SystemCall)sys_getcwd;
sys_call_table[__NR_capget] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_capset] = (SystemCall)sys_ni_syscall;