]> granicus.if.org Git - strace/commitdiff
get_os_release: tolerate malformed kernel release strings
authorDmitry V. Levin <ldv@altlinux.org>
Sat, 22 Jun 2019 21:25:15 +0000 (21:25 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sat, 22 Jun 2019 21:25:15 +0000 (21:25 +0000)
* strace.c (get_os_release): Handle malformed kernel release strings
gracefully.

Resolves: https://github.com/strace/strace/issues/101

strace.c

index 318b1409eeaa47c8d7f2fe5ac849ffed79ce9a2c..f7dfdaa504e919e54e4d05c0b052e0deb6a7b960 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -1507,35 +1507,29 @@ test_ptrace_seize(void)
        }
 }
 
-static unsigned
+static unsigned int
 get_os_release(void)
 {
-       unsigned rel;
-       const char *p;
        struct utsname u;
        if (uname(&u) < 0)
                perror_msg_and_die("uname");
-       /* u.release has this form: "3.2.9[-some-garbage]" */
-       rel = 0;
-       p = u.release;
-       for (;;) {
-               if (!(*p >= '0' && *p <= '9'))
-                       error_msg_and_die("Bad OS release string: '%s'", u.release);
-               /* Note: this open-codes KERNEL_VERSION(): */
-               rel = (rel << 8) | atoi(p);
-               if (rel >= KERNEL_VERSION(1, 0, 0))
-                       break;
-               while (*p >= '0' && *p <= '9')
-                       p++;
-               if (*p != '.') {
-                       if (rel >= KERNEL_VERSION(0, 1, 0)) {
-                               /* "X.Y-something" means "X.Y.0" */
-                               rel <<= 8;
-                               break;
-                       }
-                       error_msg_and_die("Bad OS release string: '%s'", u.release);
+       /*
+        * u.release string consists of at most three parts
+        * and normally has this form: "3.2.9[-some-garbage]",
+        * "X.Y-something" means "X.Y.0".
+        */
+       const char *p = u.release;
+       unsigned int rel = 0;
+       for (unsigned int parts = 0; parts < 3; ++parts) {
+               unsigned int n = 0;
+               for (; (*p >= '0') && (*p <= '9'); ++p) {
+                       n *= 10;
+                       n += *p - '0';
                }
-               p++;
+               rel <<= 8;
+               rel |= n;
+               if (*p == '.')
+                       ++p;
        }
        return rel;
 }