From 5da44fc8812c9e6e74d0a4768ce1ea82ccbf3579 Mon Sep 17 00:00:00 2001 From: Tulio A M Mendes Date: Tue, 26 May 2026 02:06:58 -0300 Subject: [PATCH] security: add SETREUID/SETREGID syscalls for complete UID infrastructure (Fase 4) --- include/syscall.h | 118 ++++++++++++++-------------- newlib/libgloss/adros/posix_stubs.c | 112 +++++++++++++------------- src/kernel/syscall.c | 54 +++++++++++++ user/ulibc/src/unistd.c | 8 ++ 4 files changed, 177 insertions(+), 115 deletions(-) diff --git a/include/syscall.h b/include/syscall.h index f2348965..69a2676e 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -126,64 +126,66 @@ enum { SYSCALL_GETEGID = 89, SYSCALL_SETEUID = 90, SYSCALL_SETEGID = 91, - SYSCALL_SETITIMER = 92, - SYSCALL_GETITIMER = 93, - SYSCALL_WAITID = 94, - SYSCALL_SIGQUEUE = 95, - SYSCALL_POSIX_SPAWN = 96, - SYSCALL_MQ_OPEN = 97, - SYSCALL_MQ_CLOSE = 98, - SYSCALL_MQ_SEND = 99, - SYSCALL_MQ_RECEIVE = 100, - SYSCALL_MQ_UNLINK = 101, - SYSCALL_SEM_OPEN = 102, - SYSCALL_SEM_CLOSE = 103, - SYSCALL_SEM_WAIT = 104, - SYSCALL_SEM_POST = 105, - SYSCALL_SEM_UNLINK = 106, - SYSCALL_SEM_GETVALUE = 107, - SYSCALL_GETADDRINFO = 108, - SYSCALL_DLOPEN = 109, - SYSCALL_DLSYM = 110, - SYSCALL_DLCLOSE = 111, - - SYSCALL_EPOLL_CREATE = 112, - SYSCALL_EPOLL_CTL = 113, - SYSCALL_EPOLL_WAIT = 114, - - SYSCALL_INOTIFY_INIT = 115, - SYSCALL_INOTIFY_ADD_WATCH = 116, - SYSCALL_INOTIFY_RM_WATCH = 117, - - SYSCALL_SENDMSG = 118, - SYSCALL_RECVMSG = 119, - - SYSCALL_PIVOT_ROOT = 120, - - SYSCALL_AIO_READ = 121, - SYSCALL_AIO_WRITE = 122, - SYSCALL_AIO_ERROR = 123, - SYSCALL_AIO_RETURN = 124, - SYSCALL_AIO_SUSPEND = 125, - - SYSCALL_MOUNT = 126, - - SYSCALL_GETTIMEOFDAY = 127, - SYSCALL_MPROTECT = 128, - SYSCALL_GETRLIMIT = 129, - SYSCALL_SETRLIMIT = 130, - SYSCALL_SETSOCKOPT = 131, - SYSCALL_GETSOCKOPT = 132, - SYSCALL_SHUTDOWN = 133, - SYSCALL_GETPEERNAME = 134, - SYSCALL_GETSOCKNAME = 135, - SYSCALL_UNAME = 136, - SYSCALL_GETRUSAGE = 137, - SYSCALL_UMOUNT2 = 138, - SYSCALL_WAIT4 = 139, - SYSCALL_MADVISE = 140, - SYSCALL_EXECVEAT = 141, - SYSCALL_REBOOT = 142, + SYSCALL_SETREUID = 92, + SYSCALL_SETREGID = 93, + SYSCALL_SETITIMER = 94, + SYSCALL_GETITIMER = 95, + SYSCALL_WAITID = 96, + SYSCALL_SIGQUEUE = 97, + SYSCALL_POSIX_SPAWN = 98, + SYSCALL_MQ_OPEN = 99, + SYSCALL_MQ_CLOSE = 100, + SYSCALL_MQ_SEND = 101, + SYSCALL_MQ_RECEIVE = 102, + SYSCALL_MQ_UNLINK = 103, + SYSCALL_SEM_OPEN = 104, + SYSCALL_SEM_CLOSE = 105, + SYSCALL_SEM_WAIT = 106, + SYSCALL_SEM_POST = 107, + SYSCALL_SEM_UNLINK = 108, + SYSCALL_SEM_GETVALUE = 109, + SYSCALL_GETADDRINFO = 110, + SYSCALL_DLOPEN = 111, + SYSCALL_DLSYM = 112, + SYSCALL_DLCLOSE = 113, + + SYSCALL_EPOLL_CREATE = 114, + SYSCALL_EPOLL_CTL = 115, + SYSCALL_EPOLL_WAIT = 116, + + SYSCALL_INOTIFY_INIT = 117, + SYSCALL_INOTIFY_ADD_WATCH = 118, + SYSCALL_INOTIFY_RM_WATCH = 119, + + SYSCALL_SENDMSG = 120, + SYSCALL_RECVMSG = 121, + + SYSCALL_PIVOT_ROOT = 122, + + SYSCALL_AIO_READ = 123, + SYSCALL_AIO_WRITE = 124, + SYSCALL_AIO_ERROR = 125, + SYSCALL_AIO_RETURN = 126, + SYSCALL_AIO_SUSPEND = 127, + + SYSCALL_MOUNT = 128, + + SYSCALL_GETTIMEOFDAY = 129, + SYSCALL_MPROTECT = 130, + SYSCALL_GETRLIMIT = 131, + SYSCALL_SETRLIMIT = 132, + SYSCALL_SETSOCKOPT = 133, + SYSCALL_GETSOCKOPT = 134, + SYSCALL_SHUTDOWN = 135, + SYSCALL_GETPEERNAME = 136, + SYSCALL_GETSOCKNAME = 137, + SYSCALL_UNAME = 138, + SYSCALL_GETRUSAGE = 139, + SYSCALL_UMOUNT2 = 140, + SYSCALL_WAIT4 = 141, + SYSCALL_MADVISE = 142, + SYSCALL_EXECVEAT = 143, + SYSCALL_REBOOT = 144, }; #endif diff --git a/newlib/libgloss/adros/posix_stubs.c b/newlib/libgloss/adros/posix_stubs.c index 108e8260..0b747381 100644 --- a/newlib/libgloss/adros/posix_stubs.c +++ b/newlib/libgloss/adros/posix_stubs.c @@ -134,56 +134,59 @@ #define SYS_GETEGID 89 #define SYS_SETEUID 90 #define SYS_SETEGID 91 -#define SYS_SETITIMER 92 -#define SYS_GETITIMER 93 -#define SYS_WAITID 94 -#define SYS_SIGQUEUE 95 -#define SYS_POSIX_SPAWN 96 -#define SYS_MQ_OPEN 97 -#define SYS_MQ_CLOSE 98 -#define SYS_MQ_SEND 99 -#define SYS_MQ_RECEIVE 100 -#define SYS_MQ_UNLINK 101 -#define SYS_SEM_OPEN 102 -#define SYS_SEM_CLOSE 103 -#define SYS_SEM_WAIT 104 -#define SYS_SEM_POST 105 -#define SYS_SEM_UNLINK 106 -#define SYS_SEM_GETVALUE 107 -#define SYS_GETADDRINFO 108 -#define SYS_DLOPEN 109 -#define SYS_DLSYM 110 -#define SYS_DLCLOSE 111 -#define SYS_EPOLL_CREATE 112 -#define SYS_EPOLL_CTL 113 -#define SYS_EPOLL_WAIT 114 -#define SYS_INOTIFY_INIT 115 -#define SYS_INOTIFY_ADD_WATCH 116 -#define SYS_INOTIFY_RM_WATCH 117 -#define SYS_SENDMSG 118 -#define SYS_RECVMSG 119 -#define SYS_PIVOT_ROOT 120 -#define SYS_AIO_READ 121 -#define SYS_AIO_WRITE 122 -#define SYS_AIO_ERROR 123 -#define SYS_AIO_RETURN 124 -#define SYS_AIO_SUSPEND 125 -#define SYS_MOUNT 126 -#define SYS_GETTIMEOFDAY 127 -#define SYS_MPROTECT 128 -#define SYS_GETRLIMIT 129 -#define SYS_SETRLIMIT 130 -#define SYS_SETSOCKOPT 131 -#define SYS_GETSOCKOPT 132 -#define SYS_SHUTDOWN 133 -#define SYS_GETPEERNAME 134 -#define SYS_GETSOCKNAME 135 -#define SYS_UNAME 136 -#define SYS_GETRUSAGE 137 -#define SYS_UMOUNT2 138 -#define SYS_WAIT4 139 -#define SYS_MADVISE 140 -#define SYS_EXECVEAT 141 +#define SYS_SETREUID 92 +#define SYS_SETREGID 93 +#define SYS_SETITIMER 94 +#define SYS_GETITIMER 95 +#define SYS_WAITID 96 +#define SYS_SIGQUEUE 97 +#define SYS_POSIX_SPAWN 98 +#define SYS_MQ_OPEN 99 +#define SYS_MQ_CLOSE 100 +#define SYS_MQ_SEND 101 +#define SYS_MQ_RECEIVE 102 +#define SYS_MQ_UNLINK 103 +#define SYS_SEM_OPEN 104 +#define SYS_SEM_CLOSE 105 +#define SYS_SEM_WAIT 106 +#define SYS_SEM_POST 107 +#define SYS_SEM_UNLINK 108 +#define SYS_SEM_GETVALUE 109 +#define SYS_GETADDRINFO 110 +#define SYS_DLOPEN 111 +#define SYS_DLSYM 112 +#define SYS_DLCLOSE 113 +#define SYS_EPOLL_CREATE 114 +#define SYS_EPOLL_CTL 115 +#define SYS_EPOLL_WAIT 116 +#define SYS_INOTIFY_INIT 117 +#define SYS_INOTIFY_ADD_WATCH 118 +#define SYS_INOTIFY_RM_WATCH 119 +#define SYS_SENDMSG 120 +#define SYS_RECVMSG 121 +#define SYS_PIVOT_ROOT 122 +#define SYS_AIO_READ 123 +#define SYS_AIO_WRITE 124 +#define SYS_AIO_ERROR 125 +#define SYS_AIO_RETURN 126 +#define SYS_AIO_SUSPEND 127 +#define SYS_MOUNT 128 +#define SYS_GETTIMEOFDAY 129 +#define SYS_MPROTECT 130 +#define SYS_GETRLIMIT 131 +#define SYS_SETRLIMIT 132 +#define SYS_SETSOCKOPT 133 +#define SYS_GETSOCKOPT 134 +#define SYS_SHUTDOWN 135 +#define SYS_GETPEERNAME 136 +#define SYS_GETSOCKNAME 137 +#define SYS_UNAME 138 +#define SYS_GETRUSAGE 139 +#define SYS_UMOUNT2 140 +#define SYS_WAIT4 141 +#define SYS_MADVISE 142 +#define SYS_EXECVEAT 143 +#define SYS_REBOOT 144 /* ---- Raw syscall helpers ---- */ @@ -350,16 +353,11 @@ int setuid(uid_t uid) { return _check(_sc1(SYS_SETUID, (int)uid)); } int setgid(gid_t gid) { return _check(_sc1(SYS_SETGID, (int)gid)); } int setreuid(uid_t ruid, uid_t euid) { - /* AdrOS has setuid/seteuid but no setreuid — approximate */ - if (ruid != (uid_t)-1) { int r = _check(_sc1(SYS_SETUID, (int)ruid)); if (r < 0) return r; } - if (euid != (uid_t)-1) { int r = _check(_sc1(SYS_SETEUID, (int)euid)); if (r < 0) return r; } - return 0; + return _check(_sc2(SYS_SETREUID, (int)ruid, (int)euid)); } int setregid(gid_t rgid, gid_t egid) { - if (rgid != (gid_t)-1) { int r = _check(_sc1(SYS_SETGID, (int)rgid)); if (r < 0) return r; } - if (egid != (gid_t)-1) { int r = _check(_sc1(SYS_SETEGID, (int)egid)); if (r < 0) return r; } - return 0; + return _check(_sc2(SYS_SETREGID, (int)rgid, (int)egid)); } mode_t umask(mode_t mask) { diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 334dc10a..28ca6169 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -4043,6 +4043,60 @@ void syscall_handler(struct registers* regs) { return; } + if (syscall_no == SYSCALL_SETREUID) { + if (!current_process) { sc_ret(regs) = (uint32_t)-EINVAL; return; } + uint32_t ruid = sc_arg0(regs); + uint32_t euid = sc_arg1(regs); + /* POSIX: If ruid != -1, caller must have CAP_SETUID or ruid must match real/saved */ + if (ruid != (uint32_t)-1) { + if (current_process->euid != 0 && + ruid != current_process->uid && ruid != current_process->suid) { + sc_ret(regs) = (uint32_t)-EPERM; + return; + } + } + /* POSIX: If euid != -1, caller must have CAP_SETUID or euid must match real/saved */ + if (euid != (uint32_t)-1) { + if (current_process->euid != 0 && + euid != current_process->uid && euid != current_process->suid) { + sc_ret(regs) = (uint32_t)-EPERM; + return; + } + } + if (ruid != (uint32_t)-1) current_process->uid = ruid; + if (euid != (uint32_t)-1) current_process->euid = euid; + if (euid != (uint32_t)-1) current_process->suid = euid; + sc_ret(regs) = 0; + return; + } + + if (syscall_no == SYSCALL_SETREGID) { + if (!current_process) { sc_ret(regs) = (uint32_t)-EINVAL; return; } + uint32_t rgid = sc_arg0(regs); + uint32_t egid = sc_arg1(regs); + /* POSIX: If rgid != -1, caller must have CAP_SETGID or rgid must match real/saved */ + if (rgid != (uint32_t)-1) { + if (current_process->euid != 0 && + rgid != current_process->gid && rgid != current_process->sgid) { + sc_ret(regs) = (uint32_t)-EPERM; + return; + } + } + /* POSIX: If egid != -1, caller must have CAP_SETGID or egid must match real/saved */ + if (egid != (uint32_t)-1) { + if (current_process->euid != 0 && + egid != current_process->gid && egid != current_process->sgid) { + sc_ret(regs) = (uint32_t)-EPERM; + return; + } + } + if (rgid != (uint32_t)-1) current_process->gid = rgid; + if (egid != (uint32_t)-1) current_process->egid = egid; + if (egid != (uint32_t)-1) current_process->sgid = egid; + sc_ret(regs) = 0; + return; + } + if (syscall_no == SYSCALL_FLOCK) { int fd = (int)sc_arg0(regs); int operation = (int)sc_arg1(regs); diff --git a/user/ulibc/src/unistd.c b/user/ulibc/src/unistd.c index 669694ea..89c7e3ba 100644 --- a/user/ulibc/src/unistd.c +++ b/user/ulibc/src/unistd.c @@ -180,6 +180,14 @@ int setegid(int egid) { return __syscall_ret(_syscall1(SYS_SETEGID, egid)); } +int setreuid(uid_t ruid, uid_t euid) { + return __syscall_ret(_syscall2(SYS_SETREUID, ruid, euid)); +} + +int setregid(gid_t rgid, gid_t egid) { + return __syscall_ret(_syscall2(SYS_SETREGID, rgid, egid)); +} + int truncate(const char* path, off_t length) { return __syscall_ret(_syscall2(SYS_TRUNCATE, (int)path, (int)length)); } -- 2.43.0