commit 5cdb439923a9f00cb0efc994dd55ab914194a2fa
parent 1749a9a0ebc46a4cfad00791fca871ce48af8873
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 8 Feb 2021 15:31:09 -0500
os::exec: check for X_OK when testing executable
Diffstat:
5 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/os/exec/+linux.ha b/os/exec/+linux.ha
@@ -31,6 +31,12 @@ fn errno_to_os(err: rt::errno) os_error = {
};
fn open(path: str) (platform | os_error) = {
+ match (rt::access(path, rt::X_OK)) {
+ err: rt::errno => errno_to_os(err),
+ b: bool => if (!b) {
+ return errno_to_os(rt::EACCES);
+ },
+ };
return match (rt::open(path: *const char, rt::O_RDONLY, 0u)) {
fd: int => fd,
err: rt::errno => errno_to_os(err),
diff --git a/rt/+linux/syscallno+aarch64.ha b/rt/+linux/syscallno+aarch64.ha
@@ -289,3 +289,4 @@ export def SYS_fsmount: u64 = 432u64;
export def SYS_fspick: u64 = 433u64;
export def SYS_pidfd_open: u64 = 434u64;
export def SYS_clone3: u64 = 435u64;
+export def SYS_faccessat2: u64 = 439u64;
diff --git a/rt/+linux/syscallno+x86_64.ha b/rt/+linux/syscallno+x86_64.ha
@@ -343,3 +343,4 @@ export def SYS_fsopen: u64 = 430u64;
export def SYS_fsconfig: u64 = 431u64;
export def SYS_fsmount: u64 = 432u64;
export def SYS_fspick: u64 = 433u64;
+export def SYS_faccessat2: u64 = 439u64;
diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha
@@ -131,3 +131,25 @@ export fn lseek(fd: int, off: i64, whence: uint) (i64 | errno) = {
n: u64 => n: i64,
};
};
+
+export fn faccessat(
+ dirfd: int,
+ path: *const char,
+ mode: int,
+ flags: int,
+) (bool | errno) = {
+ return match (wrap_return(syscall4(SYS_faccessat2, dirfd: u64,
+ path: uintptr: u64, mode: u64, flags: u64))) {
+ err: errno => switch (err) {
+ EACCES => false,
+ * => err,
+ },
+ n: u64 => {
+ assert(n == 0u64);
+ true;
+ },
+ };
+};
+
+export fn access(path: *const char, mode: int) (bool | errno) =
+ faccessat(AT_FDCWD, path, mode, 0);
diff --git a/rt/+linux/types.ha b/rt/+linux/types.ha
@@ -170,3 +170,8 @@ export def PROT_WRITE: uint = 2u;
export def PROT_EXEC: uint = 4u;
export def PROT_GROWSDOWN: uint = 0x01000000u;
export def PROT_GROWSUP: uint = 0x02000000u;
+
+export def F_OK: int = 0;
+export def R_OK: int = 4;
+export def W_OK: int = 2;
+export def X_OK: int = 1;