[binutils-gdb] libctf: don't dereference out-of-bounds locations in the qualifier hashtab

Nick Alcock nix@sourceware.org
Thu Mar 25 16:34:08 GMT 2021


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0bd65ce30a869559251a34da105fbe45df5a85b3

commit 0bd65ce30a869559251a34da105fbe45df5a85b3
Author: Nick Alcock <nick.alcock@oracle.com>
Date:   Thu Mar 25 16:32:46 2021 +0000

    libctf: don't dereference out-of-bounds locations in the qualifier hashtab
    
    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.

Diff:
---
 libctf/ChangeLog    |  6 ++++++
 libctf/ctf-lookup.c | 10 +++++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index 32268f87f5f..c5d52f29d69 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -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.
diff --git a/libctf/ctf-lookup.c b/libctf/ctf-lookup.c
index 9d1e6d8a4a2..fe66bc4c00c 100644
--- a/libctf/ctf-lookup.c
+++ b/libctf/ctf-lookup.c
@@ -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);
 }


More information about the Binutils-cvs mailing list