chiark / gitweb /
util: make signal_from_string() accept RTMIN, RTMAX, and RTMAX-n
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 3 May 2018 07:40:02 +0000 (16:40 +0900)
committerSven Eden <yamakuzure@gmx.net>
Fri, 24 Aug 2018 14:47:08 +0000 (16:47 +0200)
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

src/basic/signal-util.c

index ce1c00bf35e6edf13edfc5f296d1312743ecccbb..bf4816fd6d938f599a5d316a7bd849a662b42cd2 100644 (file)
@@ -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;
 }