libctf: don't dereference out-of-bounds locations in the qualifier hashtab
authorNick Alcock <nick.alcock@oracle.com>
Thu, 25 Mar 2021 16:32:46 +0000 (16:32 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Thu, 25 Mar 2021 16:32:49 +0000 (16:32 +0000)
isqualifier, which is used by ctf_lookup_by_name to figure out if a
given word in a type name is a qualifier, takes the address of a
possibly out-of-bounds location before checking its bounds.

In any reasonable compiler this will just lead to a harmless address
computation that is then discarded if out-of-bounds, but it's still
undefined behaviour and the sanitizer rightly complains.

libctf/ChangeLog
2021-03-25  Nick Alcock  <nick.alcock@oracle.com>

PR libctf/27628
* ctf-lookup.c (isqualifier): Don't dereference out-of-bounds
qhash values.

libctf/ChangeLog
libctf/ctf-lookup.c

index 32268f87f5fe3b96f578c157ec68237dbc02d0fb..c5d52f29d69834bad8ebb2714d5219ac13f7b469 100644 (file)
@@ -1,3 +1,9 @@
+2021-03-25  Nick Alcock  <nick.alcock@oracle.com>
+
+       PR libctf/27628
+       * ctf-lookup.c (isqualifier): Don't dereference out-of-bounds
+       qhash values.
+
 2021-03-25  Nick Alcock  <nick.alcock@oracle.com>
 
        * ctf-open-bfd.c (ctf_bfdopen_ctfsect): Initialize debugging.
index 9d1e6d8a4a2b23c9d0ad7eade665123f1e7a0f7f..fe66bc4c00ce30753a562782a5abe9b7ce42f2c7 100644 (file)
@@ -111,10 +111,14 @@ isqualifier (const char *s, size_t len)
   };
 
   int h = s[len - 1] + (int) len - 105;
-  const struct qual *qp = &qhash[h];
+  const struct qual *qp;
 
-  return (h >= 0 && (size_t) h < sizeof (qhash) / sizeof (qhash[0])
-         && (size_t) len == qp->q_len &&
+  if (h < 0 || (size_t) h >= sizeof (qhash) / sizeof (qhash[0]))
+    return 0;
+
+  qp = &qhash[h];
+
+  return ((size_t) len == qp->q_len &&
          strncmp (qp->q_name, s, qp->q_len) == 0);
 }