hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit c4454dbbac80581b4dee4eb8b67b4bbb8bd49240
parent 38b4cec691ecaae989da0280e7c89f856f906acd
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon,  5 Apr 2021 11:38:14 -0400

unix: add setuid, euid, gid, egid

Diffstat:
Mrt/+linux/syscalls.ha | 10++++++++++
Mscripts/gen-stdlib | 7+++++++
Mstdlib.mk | 26++++++++++++++++++++++++++
Aunix/setuid.ha | 41+++++++++++++++++++++++++++++++++++++++++
4 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha @@ -549,3 +549,13 @@ export fn recvmsg(fd: int, msg: *const msghdr, flags: int) (int | errno) = { export fn umask(mode: mode_t) (mode_t | errno) = { return wrap_return(syscall1(SYS_umask, mode: u64))?: mode_t; }; + +export fn setresuid(uid: uid_t, euid: uid_t, suid: uid_t) (void | errno) = { + wrap_return(syscall3(SYS_setresuid, uid: u64, euid: u64, suid: u64))?; + return; +}; + +export fn setresgid(gid: gid_t, egid: gid_t, sgid: gid_t) (void | errno) = { + wrap_return(syscall3(SYS_setresgid, gid: u64, egid: u64, sgid: u64))?; + return; +}; diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -570,6 +570,12 @@ unicode() { gen_ssa unicode } +unix() { + gen_srcs unix \ + setuid.ha + gen_ssa unix +} + unix_passwd() { gen_srcs unix::passwd \ passwd.ha @@ -629,6 +635,7 @@ temp time types unicode +unix unix_passwd uuid" stdlib() { diff --git a/stdlib.mk b/stdlib.mk @@ -204,6 +204,9 @@ hare_stdlib_deps+=$(stdlib_types) stdlib_unicode=$(HARECACHE)/unicode/unicode.o hare_stdlib_deps+=$(stdlib_unicode) +stdlib_unix=$(HARECACHE)/unix/unix.o +hare_stdlib_deps+=$(stdlib_unix) + stdlib_unix_passwd=$(HARECACHE)/unix/passwd/unix_passwd.o hare_stdlib_deps+=$(stdlib_unix_passwd) @@ -757,6 +760,16 @@ $(HARECACHE)/unicode/unicode.ssa: $(stdlib_unicode_srcs) $(stdlib_rt) @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunicode \ -t$(HARECACHE)/unicode/unicode.td $(stdlib_unicode_srcs) +# unix +stdlib_unix_srcs= \ + $(STDLIB)/unix/setuid.ha + +$(HARECACHE)/unix/unix.ssa: $(stdlib_unix_srcs) $(stdlib_rt) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/unix + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix \ + -t$(HARECACHE)/unix/unix.td $(stdlib_unix_srcs) + # unix::passwd stdlib_unix_passwd_srcs= \ $(STDLIB)/unix/passwd/passwd.ha @@ -984,6 +997,9 @@ hare_testlib_deps+=$(testlib_types) testlib_unicode=$(TESTCACHE)/unicode/unicode.o hare_testlib_deps+=$(testlib_unicode) +testlib_unix=$(TESTCACHE)/unix/unix.o +hare_testlib_deps+=$(testlib_unix) + testlib_unix_passwd=$(TESTCACHE)/unix/passwd/unix_passwd.o hare_testlib_deps+=$(testlib_unix_passwd) @@ -1550,6 +1566,16 @@ $(TESTCACHE)/unicode/unicode.ssa: $(testlib_unicode_srcs) $(testlib_rt) @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunicode \ -t$(TESTCACHE)/unicode/unicode.td $(testlib_unicode_srcs) +# unix +testlib_unix_srcs= \ + $(STDLIB)/unix/setuid.ha + +$(TESTCACHE)/unix/unix.ssa: $(testlib_unix_srcs) $(testlib_rt) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/unix + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix \ + -t$(TESTCACHE)/unix/unix.td $(testlib_unix_srcs) + # unix::passwd testlib_unix_passwd_srcs= \ $(STDLIB)/unix/passwd/passwd.ha diff --git a/unix/setuid.ha b/unix/setuid.ha @@ -0,0 +1,41 @@ +use rt; + +// Sets the caller's user ID to the specified value. This generally requires +// elevated permissions from the calling process. +// +// If the system returns an error, this function will abort the program. Failing +// to handle errors from setuid is a grave security issue in your program, and +// therefore we require this function to succeed. If you need to handle the +// error case gracefully, call the appropriate syscall wrapper in [rt] yourself, +// and take extreme care to handle errors correctly. +export fn setuid(uid: uint) void = rt::setresuid(uid, -1u, -1u) as void; + +// Sets the caller's effective user ID to the specified value. This generally +// requires elevated permissions from the calling process. +// +// If the system returns an error, this function will abort the program. Failing +// to handle errors from seteuid is a grave security issue in your program, and +// therefore we require this function to succeed. If you need to handle the +// error case gracefully, call the appropriate syscall wrapper in [rt] yourself, +// and take extreme care to handle errors correctly. +export fn seteuid(uid: uint) void = rt::setresuid(-1u, uid, -1u) as void; + +// Sets the caller's group ID to the specified value. This generally requires +// elevated permissions from the calling process. +// +// If the system returns an error, this function will abort the program. Failing +// to handle errors from setuid is a grave security issue in your program, and +// therefore we require this function to succeed. If you need to handle the +// error case gracefully, call the appropriate syscall wrapper in [rt] yourself, +// and take extreme care to handle errors correctly. +export fn setgid(gid: uint) void = rt::setresgid(gid, -1u, -1u) as void; + +// Sets the caller's effective group ID to the specified value. This generally +// requires elevated permissions from the calling process. +// +// If the system returns an error, this function will abort the program. Failing +// to handle errors from setegid is a grave security issue in your program, and +// therefore we require this function to succeed. If you need to handle the +// error case gracefully, call the appropriate syscall wrapper in [rt] yourself, +// and take extreme care to handle errors correctly. +export fn setegid(gid: uint) void = rt::setresgid(-1u, gid, -1u) as void;