diff --git a/src/drivers/generic/extfs/probe.c b/src/drivers/generic/extfs/probe.c index 931add18..898fe9f5 100644 --- a/src/drivers/generic/extfs/probe.c +++ b/src/drivers/generic/extfs/probe.c @@ -166,8 +166,8 @@ vnode* ext_make_vnode(ext_cache* cache, uint32_t ino, mount* mnt) vn->desc = (dev_desc)handle; vn->vtype = vtype; vn->blkSize = 1; - vn->owner_uid = inode->uid; - vn->group_uid = inode->gid; + vn->uid = inode->uid; + vn->gid = inode->gid; vn->filesize = (uint64_t)inode->size | (ext_sb_supports_64bit_filesize ? (uint64_t)inode->dir_acl << 32 : 0); vn->times.access = inode->access_time; vn->times.birth = inode->creation_time; diff --git a/src/drivers/generic/initrd/main.c b/src/drivers/generic/initrd/main.c index 9bacf96b..a94981d0 100644 --- a/src/drivers/generic/initrd/main.c +++ b/src/drivers/generic/initrd/main.c @@ -260,8 +260,8 @@ initrd_inode* create_inode_boot(const ustar_hdr* hdr) ino->vnode->desc = (uintptr_t)ino; ino->vnode->filesize = ino->filesize; ino->vnode->blkSize = 1; - ino->vnode->owner_uid = 0; - ino->vnode->group_uid = 0; + ino->vnode->uid = 0; + ino->vnode->gid = 0; ino->vnode->inode = ino->ino; ino->vnode->perm = ino->perm; ino->vnode->times.change = oct2bin(hdr->last_mod, strnlen(hdr->last_mod, 12)); diff --git a/src/oboskrnl/arch/x86_64/gdbstub/vFile.c b/src/oboskrnl/arch/x86_64/gdbstub/vFile.c index 44b0907f..e5b4adf2 100644 --- a/src/oboskrnl/arch/x86_64/gdbstub/vFile.c +++ b/src/oboskrnl/arch/x86_64/gdbstub/vFile.c @@ -197,8 +197,8 @@ static obos_status common_stat(vnode* vn, struct gdb_stat* out) out->st_dev = 0; out->st_ino = vn->inode; out->st_nlink = vn->refs; - out->st_uid = vn->owner_uid; - out->st_gid = vn->group_uid; + out->st_uid = vn->uid; + out->st_gid = vn->gid; out->st_rdev = 0; out->st_size = vn->filesize; out->st_blksize = vn->blkSize; diff --git a/src/oboskrnl/driver_interface/drv_sys.c b/src/oboskrnl/driver_interface/drv_sys.c index 06c41145..7fa55e7c 100644 --- a/src/oboskrnl/driver_interface/drv_sys.c +++ b/src/oboskrnl/driver_interface/drv_sys.c @@ -24,7 +24,7 @@ handle Sys_LoadDriver(const void* file, size_t szFile, obos_status* ustatus) { - if (Core_GetCurrentThread()->proc->currentUID != ROOT_UID) + if (Core_GetCurrentThread()->proc->euid != ROOT_UID) { if (ustatus) *ustatus = OBOS_STATUS_ACCESS_DENIED; return HANDLE_INVALID; @@ -62,7 +62,7 @@ handle Sys_LoadDriver(const void* file, size_t szFile, obos_status* ustatus) } #define perm_check_impl(ret) do {\ - if (Core_GetCurrentThread()->proc->currentUID != ROOT_UID)\ + if (Core_GetCurrentThread()->proc->euid != ROOT_UID)\ return (ret);\ } while(0) #define perm_check() perm_check_impl(OBOS_STATUS_ACCESS_DENIED) diff --git a/src/oboskrnl/execve.c b/src/oboskrnl/execve.c index d9aac177..620ad9bd 100644 --- a/src/oboskrnl/execve.c +++ b/src/oboskrnl/execve.c @@ -144,8 +144,8 @@ obos_status Sys_ExecVE(const char* upath, char* const* argv, char* const* envp) void* kbuf = Mm_VirtualMemoryAlloc(&Mm_KernelContext, nullptr, szBuf, OBOS_PROTECTION_READ_ONLY, 0, &file, nullptr); bool set_uid = file.vn->perm.set_uid; bool set_gid = file.vn->perm.set_gid; - uid target_uid = set_uid ? file.vn->owner_uid : Core_GetCurrentThread()->proc->currentUID; - gid target_gid = set_gid ? file.vn->group_uid : Core_GetCurrentThread()->proc->currentGID; + uid target_euid = set_uid ? file.vn->uid : Core_GetCurrentThread()->proc->euid; + gid target_egid = set_gid ? file.vn->gid : Core_GetCurrentThread()->proc->egid; Vfs_FdClose(&file); char** kargv = allocate_user_vector_as_kernel(ctx, argv, &argc, &status); @@ -309,8 +309,10 @@ obos_status Sys_ExecVE(const char* upath, char* const* argv, char* const* envp) aux.at_secure = set_gid || set_uid; - Core_GetCurrentThread()->proc->currentUID = target_uid; - Core_GetCurrentThread()->proc->currentGID = target_gid; + Core_GetCurrentThread()->proc->euid = target_euid; + Core_GetCurrentThread()->proc->egid = target_egid; + Core_GetCurrentThread()->proc->sgid = -1; + Core_GetCurrentThread()->proc->sgid = -1; OBOSS_HandControlTo(ctx, &aux); } diff --git a/src/oboskrnl/scheduler/process.h b/src/oboskrnl/scheduler/process.h index 324a1b9c..ac697526 100644 --- a/src/oboskrnl/scheduler/process.h +++ b/src/oboskrnl/scheduler/process.h @@ -37,8 +37,8 @@ typedef struct process struct process_group* pgrp; - uid currentUID; - gid currentGID; + uid euid, ruid, suid; + gid egid, rgid, sgid; uint32_t exitCode; bool dead; diff --git a/src/oboskrnl/scheduler/sched_sys.c b/src/oboskrnl/scheduler/sched_sys.c index a527ec93..15421adb 100644 --- a/src/oboskrnl/scheduler/sched_sys.c +++ b/src/oboskrnl/scheduler/sched_sys.c @@ -663,29 +663,121 @@ obos_status Sys_WaitProcess(handle proc, int* wstatus, int options, uint32_t* pi return status; } +uid Sys_GetUid() +{ return Core_GetCurrentThread()->proc->ruid; } +gid Sys_GetGid() +{ return Core_GetCurrentThread()->proc->rgid; } -obos_status Sys_SetUid(uid to) +static bool check_unpriv_uid(uid uid) { - process* proc = Core_GetCurrentThread()->proc; - if (proc->currentUID != 0) - return OBOS_STATUS_ACCESS_DENIED; - proc->currentUID = to; + return (uid != Core_GetCurrentThread()->proc->ruid) && + (uid != Core_GetCurrentThread()->proc->euid) && + (uid != Core_GetCurrentThread()->proc->suid); +} +static bool check_unpriv_gid(gid gid) +{ + return (gid != Core_GetCurrentThread()->proc->rgid) && + (gid != Core_GetCurrentThread()->proc->egid) && + (gid != Core_GetCurrentThread()->proc->sgid); +} + +obos_status Sys_SetRESUid(uid ruid, uid euid, uid suid) +{ + if (Core_GetCurrentThread()->proc->euid != 0) + { + if ((ruid != -1) && !check_unpriv_uid(ruid)) + return OBOS_STATUS_ACCESS_DENIED; + if ((euid != -1) && !check_unpriv_uid(euid)) + return OBOS_STATUS_ACCESS_DENIED; + if ((suid != -1) && !check_unpriv_uid(suid)) + return OBOS_STATUS_ACCESS_DENIED; + if (ruid != -1) + Core_GetCurrentThread()->proc->ruid = ruid; + if (euid != -1) + Core_GetCurrentThread()->proc->euid = euid; + if (suid != -1) + Core_GetCurrentThread()->proc->suid = suid; + } + else + { + if (ruid != -1) Core_GetCurrentThread()->proc->ruid = ruid; + if (euid != -1) Core_GetCurrentThread()->proc->euid = euid; + if (suid != -1) Core_GetCurrentThread()->proc->suid = suid; + } return OBOS_STATUS_SUCCESS; } -obos_status Sys_SetGid(gid to) +obos_status Sys_SetRESGid(gid rgid, gid egid, gid sgid) { - process* proc = Core_GetCurrentThread()->proc; - if (proc->currentUID != 0) - return OBOS_STATUS_ACCESS_DENIED; - proc->currentGID = to; + if (Core_GetCurrentThread()->proc->euid != 0) + { + if ((rgid != -1) && !check_unpriv_gid(rgid)) + return OBOS_STATUS_ACCESS_DENIED; + if ((egid != -1) && !check_unpriv_gid(egid)) + return OBOS_STATUS_ACCESS_DENIED; + if ((sgid != -1) && !check_unpriv_gid(sgid)) + return OBOS_STATUS_ACCESS_DENIED; + if (rgid != -1) + Core_GetCurrentThread()->proc->rgid = rgid; + if (egid != -1) + Core_GetCurrentThread()->proc->egid = egid; + if (sgid != -1) + Core_GetCurrentThread()->proc->sgid = sgid; + } + else + { + if (rgid != -1) Core_GetCurrentThread()->proc->rgid = rgid; + if (egid != -1) Core_GetCurrentThread()->proc->egid = egid; + if (sgid != -1) Core_GetCurrentThread()->proc->sgid = sgid; + } return OBOS_STATUS_SUCCESS; } -uid Sys_GetUid() -{ return Core_GetCurrentThread()->proc->currentUID; } -gid Sys_GetGid() -{ return Core_GetCurrentThread()->proc->currentGID; } +obos_status Sys_GetRESUid(uid* ruid, uid* euid, uid* suid) +{ + if (ruid) + memcpy_k_to_usr(ruid, &Core_GetCurrentThread()->proc->ruid, sizeof(uid)); + if (euid) + memcpy_k_to_usr(euid, &Core_GetCurrentThread()->proc->euid, sizeof(uid)); + if (suid) + memcpy_k_to_usr(suid, &Core_GetCurrentThread()->proc->suid, sizeof(uid)); + return OBOS_STATUS_SUCCESS; +} + +obos_status Sys_GetRESGid(gid* rgid, gid* egid, gid* sgid) +{ + if (rgid) + memcpy_k_to_usr(rgid, &Core_GetCurrentThread()->proc->rgid, sizeof(gid)); + if (egid) + memcpy_k_to_usr(egid, &Core_GetCurrentThread()->proc->egid, sizeof(gid)); + if (sgid) + memcpy_k_to_usr(sgid, &Core_GetCurrentThread()->proc->sgid, sizeof(gid)); + return OBOS_STATUS_SUCCESS; +} + +obos_status Sys_SetUid(uid uid) +{ + if (Core_GetCurrentThread()->proc->euid == 0) + { + Core_GetCurrentThread()->proc->ruid = uid; + Core_GetCurrentThread()->proc->euid = uid; + Core_GetCurrentThread()->proc->suid = uid; + return OBOS_STATUS_SUCCESS; + } + return OBOS_STATUS_ACCESS_DENIED; +} + +obos_status Sys_SetGid(gid gid) +{ + if (Core_GetCurrentThread()->proc->euid == 0) + { + Core_GetCurrentThread()->proc->rgid = gid; + Core_GetCurrentThread()->proc->egid = gid; + Core_GetCurrentThread()->proc->sgid = gid; + return OBOS_STATUS_SUCCESS; + } + return OBOS_STATUS_ACCESS_DENIED; +} obos_status Sys_SetProcessGroup(handle process, uint32_t pgid) { diff --git a/src/oboskrnl/scheduler/sched_sys.h b/src/oboskrnl/scheduler/sched_sys.h index d0381dc5..673658b2 100644 --- a/src/oboskrnl/scheduler/sched_sys.h +++ b/src/oboskrnl/scheduler/sched_sys.h @@ -66,10 +66,14 @@ handle Sys_ProcessGetChildHandle(); // If HANDLE_ANY to make it choose an arbitrary child process. obos_status Sys_WaitProcess(handle proc, int* status, int options, uint32_t* ret_pid); -obos_status Sys_SetUid(uid to); -obos_status Sys_SetGid(gid to); uid Sys_GetUid(); gid Sys_GetGid(); +obos_status Sys_SetRESUid(uid ruid, uid euid, uid suid); +obos_status Sys_SetRESGid(gid rgid, gid egid, gid sgid); +obos_status Sys_GetRESUid(uid* ruid, uid* euid, uid* suid); +obos_status Sys_GetRESGid(gid* rgid, gid* egid, gid* sgid); +obos_status Sys_SetUid(uid uid); +obos_status Sys_SetGid(gid gid); obos_status Sys_SetProcessGroup(handle proc, uint32_t pgid); obos_status Sys_GetProcessGroup(handle proc, uint32_t* pgid); \ No newline at end of file diff --git a/src/oboskrnl/syscall.c b/src/oboskrnl/syscall.c index a990fc6d..2902ed99 100644 --- a/src/oboskrnl/syscall.c +++ b/src/oboskrnl/syscall.c @@ -458,6 +458,10 @@ uintptr_t OBOS_SyscallTable[SYSCALL_END-SYSCALL_BEGIN] = { (uintptr_t)Sys_RenameAt, (uintptr_t)Sys_UTimeNSAt, (uintptr_t)Sys_ThreadGetStack, + (uintptr_t)Sys_SetRESUid, + (uintptr_t)Sys_SetRESGid, + (uintptr_t)Sys_GetRESUid, + (uintptr_t)Sys_GetRESGid, }; // Arch syscall table is defined per-arch diff --git a/src/oboskrnl/vfs/create.c b/src/oboskrnl/vfs/create.c index 6ca818a2..772cab74 100644 --- a/src/oboskrnl/vfs/create.c +++ b/src/oboskrnl/vfs/create.c @@ -25,20 +25,20 @@ static bool has_write_perm(vnode* parent) { - uid current_uid = Core_GetCurrentThread()->proc->currentUID; - uid current_gid = Core_GetCurrentThread()->proc->currentGID; + uid current_uid = Core_GetCurrentThread()->proc->euid; + uid current_gid = Core_GetCurrentThread()->proc->egid; if (parent->flags & VFLAGS_MOUNTPOINT) { drv_fs_info info = {}; parent->un.mounted->fs_driver->driver->header.ftable.stat_fs_info(parent->un.mounted->device, &info); - if (parent->owner_uid == current_uid || parent->group_uid == current_gid) + if (parent->uid == current_uid || parent->gid == current_gid) return ~info.flags & FS_FLAGS_RDONLY; else return false; } - if (parent->owner_uid == current_uid) + if (parent->uid == current_uid) return parent->perm.owner_write; - else if (parent->group_uid == current_gid) + else if (parent->gid == current_gid) return parent->perm.group_write; else return parent->perm.other_write; @@ -94,8 +94,8 @@ obos_status Vfs_CreateNode(dirent* parent, const char* name, uint32_t vtype, fil return OBOS_STATUS_INVALID_ARGUMENT; } vnode* vn = Vfs_Calloc(1, sizeof(vnode)); - vn->group_uid = Core_GetCurrentThread()->proc->currentGID; - vn->owner_uid = Core_GetCurrentThread()->proc->currentUID; + vn->gid = Core_GetCurrentThread()->proc->egid; + vn->uid = Core_GetCurrentThread()->proc->euid; vn->perm = mode; vn->flags = 0; vn->vtype = vtype; diff --git a/src/oboskrnl/vfs/dirent.c b/src/oboskrnl/vfs/dirent.c index 4c110ce8..3d28c8c7 100644 --- a/src/oboskrnl/vfs/dirent.c +++ b/src/oboskrnl/vfs/dirent.c @@ -461,8 +461,8 @@ vnode* Drv_AllocateVNode(driver_id* drv, dev_desc desc, size_t filesize, vdev** vn->inode = devfs_inode++; vn->perm = default_fileperm; vn->vtype = type; - vn->group_uid = ROOT_GID; - vn->owner_uid = ROOT_UID; + vn->gid = ROOT_GID; + vn->uid = ROOT_UID; vn->times.access = get_current_time(); vn->times.birth = vn->times.access; vn->times.change = vn->times.access; @@ -650,12 +650,12 @@ char* VfsH_DirentPath(dirent* ent, dirent* relative_to) static bool check_chdir_perms(dirent* ent) { - uid uid = Core_GetCurrentThread()->proc->currentUID; - gid gid = Core_GetCurrentThread()->proc->currentGID; + uid uid = Core_GetCurrentThread()->proc->euid; + gid gid = Core_GetCurrentThread()->proc->egid; - if (uid == ent->vnode->owner_uid) + if (uid == ent->vnode->uid) return ent->vnode->perm.owner_exec; - else if (gid == ent->vnode->group_uid) + else if (gid == ent->vnode->gid) return ent->vnode->perm.group_exec; else return ent->vnode->perm.other_exec; diff --git a/src/oboskrnl/vfs/dummy_devices.c b/src/oboskrnl/vfs/dummy_devices.c index 0275881d..a4e043d5 100644 --- a/src/oboskrnl/vfs/dummy_devices.c +++ b/src/oboskrnl/vfs/dummy_devices.c @@ -417,8 +417,8 @@ static void init_desc(dev_desc desc) dirent* ent = Vfs_Calloc(1, sizeof(dirent)); vnode* vn = Vfs_Calloc(1, sizeof(vnode)); - vn->owner_uid = 0; - vn->group_uid = 0; + vn->uid = 0; + vn->gid = 0; vn->desc = desc; get_max_blk_count(desc, &vn->filesize); diff --git a/src/oboskrnl/vfs/fd.c b/src/oboskrnl/vfs/fd.c index 33f98597..74789443 100644 --- a/src/oboskrnl/vfs/fd.c +++ b/src/oboskrnl/vfs/fd.c @@ -94,7 +94,7 @@ OBOS_EXPORT obos_status Vfs_FdOpenVnode(fd* const desc, void* vn, uint32_t oflag desc->flags |= FD_FLAGS_OPEN; desc->flags |= FD_FLAGS_READ; desc->flags |= FD_FLAGS_WRITE; - if (desc->vn->owner_uid == Core_GetCurrentThread()->proc->currentUID || Core_GetCurrentThread()->proc->currentUID == 0) + if (desc->vn->uid == Core_GetCurrentThread()->proc->euid || Core_GetCurrentThread()->proc->euid == 0) { // We have owner perms. struct vnode* const vn = desc->vn; @@ -105,7 +105,7 @@ OBOS_EXPORT obos_status Vfs_FdOpenVnode(fd* const desc, void* vn, uint32_t oflag if (oflags & FD_OFLAGS_EXECUTE && !vn->perm.owner_exec) return OBOS_STATUS_ACCESS_DENIED; } - else if (desc->vn->group_uid == Core_GetCurrentThread()->proc->currentGID) + else if (desc->vn->gid == Core_GetCurrentThread()->proc->egid) { // We have group perms. struct vnode* const vn = desc->vn; diff --git a/src/oboskrnl/vfs/fd_sys.c b/src/oboskrnl/vfs/fd_sys.c index 4e13d3b7..f3a3f1eb 100644 --- a/src/oboskrnl/vfs/fd_sys.c +++ b/src/oboskrnl/vfs/fd_sys.c @@ -680,8 +680,8 @@ obos_status Sys_Stat(int fsfdt, handle desc, const char* upath, int flags, struc st.st_atim.tv_nsec = 0; st.st_ctim.tv_nsec = 0; st.st_mtim.tv_nsec = 0; - st.st_gid = to_stat->group_uid; - st.st_uid = to_stat->owner_uid; + st.st_gid = to_stat->gid; + st.st_uid = to_stat->uid; st.st_ino = to_stat->inode; if (to_stat->flags & VFLAGS_EVENT_DEV && ~to_stat->flags & VFLAGS_DRIVER_DEAD) goto done; @@ -1326,8 +1326,8 @@ obos_status Sys_CreateNamedPipe(handle dirfd, const char* upath, int mode, size_ fifo_name = path; } - gid current_gid = Core_GetCurrentThread()->proc->currentGID; - uid current_uid = Core_GetCurrentThread()->proc->currentUID; + gid current_gid = Core_GetCurrentThread()->proc->egid; + uid current_uid = Core_GetCurrentThread()->proc->euid; status = Vfs_CreateNamedPipe(perm, current_gid, current_uid, parent, fifo_name, pipesize); Free(OBOS_KernelAllocator, path, sz_path); @@ -2910,7 +2910,7 @@ obos_status Sys_FChmodAt(handle dirfd, const char* upathname, int mode, int flag have_target: - if (target->owner_uid != Sys_GetUid() && Sys_GetUid() != ROOT_UID) + if (target->uid != Sys_GetUid() && Sys_GetUid() != ROOT_UID) { status = OBOS_STATUS_ACCESS_DENIED; goto fail; @@ -3030,7 +3030,7 @@ obos_status Sys_FChownAt(handle dirfd, const char *upathname, uid owner, gid gro have_target: OBOS_ENSURE(target); - if (target->owner_uid != Sys_GetUid() && Sys_GetUid() != ROOT_UID) + if (target->uid != Sys_GetUid() && Sys_GetUid() != ROOT_UID) { status = OBOS_STATUS_ACCESS_DENIED; goto fail; @@ -3048,9 +3048,9 @@ obos_status Sys_FChownAt(handle dirfd, const char *upathname, uid owner, gid gro goto fail; if (owner != -1) - target->owner_uid = owner; + target->uid = owner; if (group != -1) - target->group_uid = group; + target->gid = group; fail: Free(OBOS_KernelAllocator, pathname, sz_path); diff --git a/src/oboskrnl/vfs/pipe.c b/src/oboskrnl/vfs/pipe.c index c901e4cf..dad9b4c5 100644 --- a/src/oboskrnl/vfs/pipe.c +++ b/src/oboskrnl/vfs/pipe.c @@ -442,8 +442,8 @@ obos_status Vfs_CreateNamedPipe(file_perm perm, gid group_uid, uid owner_uid, di dirent* ent = Vfs_Calloc(1, sizeof(dirent)); vnode* vn = Vfs_Calloc(1, sizeof(vnode)); desc->vn = vn; - vn->owner_uid = owner_uid; - vn->group_uid = group_uid; + vn->uid = owner_uid; + vn->gid = group_uid; vn->desc = (uintptr_t)desc; vn->perm = perm; vn->vtype = VNODE_TYPE_FIFO; diff --git a/src/oboskrnl/vfs/vnode.h b/src/oboskrnl/vfs/vnode.h index d0475e83..ec91ee5e 100644 --- a/src/oboskrnl/vfs/vnode.h +++ b/src/oboskrnl/vfs/vnode.h @@ -90,8 +90,8 @@ typedef struct vnode size_t refs; file_perm perm; size_t filesize; // filesize. - uid owner_uid; // the owner's UID. - gid group_uid; // the group's GID. + uid uid; // the owner's UID. + gid gid; // the group's GID. dev_desc desc; // the cached device descriptor. fd_list opened; size_t nMappedRegions;