commit fd24f6da73c219596b9167e8996a6e2f277f7d33
parent f48bb4f864e5dd33cc0a919f5e769b32ed86f159
Author: Jose Lombera <jose@lombera.dev>
Date: Sat, 18 Jun 2022 20:35:29 -0500
rt: signal: return error for invalid signal numbers
- Validate that signal number is >= 1.
- Return actual rt::errno for invalid signal numbers.
- Add tests to cover these changes.
Signed-off-by: Jose Lombera <jose@lombera.dev>
Diffstat:
5 files changed, 62 insertions(+), 12 deletions(-)
diff --git a/rt/+freebsd/signal.ha b/rt/+freebsd/signal.ha
@@ -11,8 +11,8 @@ export fn sigemptyset(set: *sigset) int = {
};
export fn sigaddset(set: *sigset, signum: int) (int | errno) = {
- if (signum > NSIG) {
- return EINVAL;
+ if (signum < 1 || signum > NSIG) {
+ return wrap_errno(EINVAL);
};
signum -= 1;
set.__bits[signum >> 5] |= (1 << signum): u32;
@@ -20,8 +20,8 @@ export fn sigaddset(set: *sigset, signum: int) (int | errno) = {
};
export fn sigdelset(set: *sigset, signum: int) (int | errno) = {
- if (signum > NSIG) {
- return EINVAL;
+ if (signum < 1 || signum > NSIG) {
+ return wrap_errno(EINVAL);
};
signum -= 1;
set.__bits[signum >> 5] &= ~(1 << signum: u32);
@@ -29,8 +29,8 @@ export fn sigdelset(set: *sigset, signum: int) (int | errno) = {
};
export fn sigismember(set: *sigset, signum: int) (int | errno) = {
- if (signum > NSIG) {
- return EINVAL;
+ if (signum < 1 || signum > NSIG) {
+ return wrap_errno(EINVAL);
};
signum -= 1;
if ((set.__bits[signum >> 5] & (1 << signum: u32)) != 0) {
diff --git a/rt/+linux/signal.ha b/rt/+linux/signal.ha
@@ -12,8 +12,8 @@ export fn sigemptyset(set: *sigset) int = {
};
export fn sigaddset(set: *sigset, signum: int) (int | errno) = {
- if (signum > NSIG) {
- return EINVAL;
+ if (signum < 1 || signum > NSIG) {
+ return wrap_errno(EINVAL);
};
signum -= 1;
set.__val[0] |= (1 << signum): u64;
@@ -21,8 +21,8 @@ export fn sigaddset(set: *sigset, signum: int) (int | errno) = {
};
export fn sigdelset(set: *sigset, signum: int) (int | errno) = {
- if (signum > NSIG) {
- return EINVAL;
+ if (signum < 1 || signum > NSIG) {
+ return wrap_errno(EINVAL);
};
signum -= 1;
set.__val[0] &= ~(1 << signum: u64);
@@ -30,8 +30,8 @@ export fn sigdelset(set: *sigset, signum: int) (int | errno) = {
};
export fn sigismember(set: *sigset, signum: int) (int | errno) = {
- if (signum > NSIG) {
- return EINVAL;
+ if (signum < 1 || signum > NSIG) {
+ return wrap_errno(EINVAL);
};
signum -= 1;
if ((set.__val[0] & (1 << signum: u64)) != 0) {
diff --git a/rt/+test/signal.ha b/rt/+test/signal.ha
@@ -0,0 +1,47 @@
+// License: MPL-2.0
+// (c) 2022 Jose Lombera <jose@lombera.dev>
+
+// Test sigset operations do not fail for valid signal numbers.
+@test fn sigset_valid_signum() void = {
+ let set = sigset { ... };
+ sigemptyset(&set);
+
+ assert(!(sigismember(&set, 1) is errno), "Unexpected error");
+ assert(!(sigismember(&set, 15) is errno), "Unexpected error");
+ assert(!(sigismember(&set, NSIG) is errno), "Unexpected error");
+
+ assert(!(sigaddset(&set, 1) is errno), "Unexpected error");
+ assert(!(sigaddset(&set, 15) is errno), "Unexpected error");
+ assert(!(sigaddset(&set, NSIG) is errno), "Unexpected error");
+
+ // It's ok to add a signal that is already present in the set.
+ assert(!(sigaddset(&set, 1) is errno), "Unexpected error");
+
+ assert(!(sigdelset(&set, 1) is errno), "Unexpected error");
+ assert(!(sigdelset(&set, 15) is errno), "Unexpected error");
+ assert(!(sigdelset(&set, NSIG) is errno), "Unexpected error");
+
+ // It's ok to delete a signal that is not present in the set.
+ assert(!(sigdelset(&set, 10) is errno), "Unexpected error");
+
+ // sigfillset() always succeeds.
+ assert(!(sigfillset(&set) is errno), "Unexpected error");
+};
+
+// Test sigset operations fail for invalid signal numbers.
+@test fn sigset_invalid_signum() void = {
+ let set = sigset { ... };
+ sigemptyset(&set);
+
+ assert(sigismember(&set, -1) is errno, "Expected error");
+ assert(sigismember(&set, 0) is errno, "Expected error");
+ assert(sigismember(&set, NSIG + 1) is errno, "Expected error");
+
+ assert(sigaddset(&set, -1) is errno, "Expected error");
+ assert(sigaddset(&set, 0) is errno, "Expected error");
+ assert(sigaddset(&set, NSIG + 1) is errno, "Expected error");
+
+ assert(sigdelset(&set, -1) is errno, "Expected error");
+ assert(sigdelset(&set, 0) is errno, "Expected error");
+ assert(sigdelset(&set, NSIG + 1) is errno, "Expected error");
+};
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -84,6 +84,7 @@ rt() {
'+test/+$(PLATFORM).ha' \
+test/cstring.ha \
+test/run.ha \
+ +test/signal.ha \
+test/ztos.ha
fi
gen_ssa -plinux rt
diff --git a/stdlib.mk b/stdlib.mk
@@ -2192,6 +2192,7 @@ testlib_rt_linux_srcs = \
$(STDLIB)/rt/+test/+$(PLATFORM).ha \
$(STDLIB)/rt/+test/cstring.ha \
$(STDLIB)/rt/+test/run.ha \
+ $(STDLIB)/rt/+test/signal.ha \
$(STDLIB)/rt/+test/ztos.ha
# rt (+freebsd)
@@ -2222,6 +2223,7 @@ testlib_rt_freebsd_srcs = \
$(STDLIB)/rt/+test/+$(PLATFORM).ha \
$(STDLIB)/rt/+test/cstring.ha \
$(STDLIB)/rt/+test/run.ha \
+ $(STDLIB)/rt/+test/signal.ha \
$(STDLIB)/rt/+test/ztos.ha
$(TESTCACHE)/rt/rt-linux.ssa: $(testlib_rt_linux_srcs) $(testlib_rt)