From: Yu Watanabe Date: Thu, 3 May 2018 07:40:02 +0000 (+0900) Subject: util: make signal_from_string() accept RTMIN, RTMAX, and RTMAX-n X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=1e1ce9732643a6aba350e5f22d9d8a2f56226d37;p=elogind.git util: make signal_from_string() accept RTMIN, RTMAX, and RTMAX-n Before this, `signal_from_string()` accepts simple signal name or RTMIN+n. This makes the function also accept RTMIN, RTMAX, and RTMAX-n. Note that RTMIN+0 is equivalent to RTMIN, and RTMAX-0 is to RTMAX. This also fixes the integer overflow reported by oss-fuzz #8064. https://oss-fuzz.com/v2/testcase-detail/5648573352902656 --- diff --git a/src/basic/signal-util.c b/src/basic/signal-util.c index ce1c00bf3..bf4816fd6 100644 --- a/src/basic/signal-util.c +++ b/src/basic/signal-util.c @@ -231,23 +231,59 @@ const char *signal_to_string(int signo) { } int signal_from_string(const char *s) { - int signo; - int offset = 0; - unsigned u; + const char *p; + int signo, r; + /* Check that the input is a signal name. */ signo = __signal_from_string(s); if (signo > 0) return signo; - if (startswith(s, "RTMIN+")) { - s += 6; - offset = SIGRTMIN; - } - if (safe_atou(s, &u) >= 0) { - signo = (int) u + offset; + if (safe_atoi(s, &signo) >= 0) { if (SIGNAL_VALID(signo)) return signo; + else + return -ERANGE; + } + + /* Check that the input is RTMIN or + * RTMIN+n (0 <= n <= SIGRTMAX-SIGRTMIN). */ + p = startswith(s, "RTMIN"); + if (p) { + if (*p == '\0') + return SIGRTMIN; + if (*p != '+') + return -EINVAL; + + r = safe_atoi(p, &signo); + if (r < 0) + return r; + + if (signo < 0 || signo > SIGRTMAX - SIGRTMIN) + return -ERANGE; + + return signo + SIGRTMIN; } + + /* Check that the input is RTMAX or + * RTMAX-n (0 <= n <= SIGRTMAX-SIGRTMIN). */ + p = startswith(s, "RTMAX"); + if (p) { + if (*p == '\0') + return SIGRTMAX; + if (*p != '-') + return -EINVAL; + + r = safe_atoi(p, &signo); + if (r < 0) + return r; + + if (signo > 0 || signo < SIGRTMIN - SIGRTMAX) + return -ERANGE; + + return signo + SIGRTMAX; + } + return -EINVAL; }