aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2021-09-27 20:31:21 +0100
committerNick Alcock <nick.alcock@oracle.com>2021-09-27 20:31:26 +0100
commit6ab5b6d0f3adc36303d2cc5308a92cf95e2801f9 (patch)
tree93320a807a43abf51f1ea4fb91f1a15a7908ae95
parente695879142a8e8b9f7e220a7919f38ad3ee614e6 (diff)
downloadgdb-6ab5b6d0f3adc36303d2cc5308a92cf95e2801f9.zip
gdb-6ab5b6d0f3adc36303d2cc5308a92cf95e2801f9.tar.gz
gdb-6ab5b6d0f3adc36303d2cc5308a92cf95e2801f9.tar.bz2
libctf, lookup: fix bounds of pptrtab lookup
An off-by-one bug in the check for pptrtab lookup meant that we could access the pptrtab past its bounds (*well* past its bounds), particularly if we called ctf_lookup_by_name in a child dict with "*foo" where "foo" is a type that exists in the parent but not the child and no previous lookups by name have been carried out. (Note that "*foo" is not even a valid thing to call ctf_lookup_by_name with: foo * is. Nonetheless, users sometimes do call ctf_lookup_by_name with invalid content, and it should return ECTF_NOTYPE, not crash.) ctf_pptrtab_len, as its name suggests (and as other tests of it in ctf-lookup.c confirm), is one higher than the maximum valid permissible index, so the comparison is wrong. (Test added, which should fail pretty reliably in the presence of this bug on any machine with 4KiB pages.) libctf/ChangeLog 2021-09-27 Nick Alcock <nick.alcock@oracle.com> * ctf-lookup.c (ctf_lookup_by_name_internal): Fix pptrtab bounds. * testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.*: New test.
-rw-r--r--libctf/ChangeLog6
-rw-r--r--libctf/ctf-lookup.c4
-rw-r--r--libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.c68
-rw-r--r--libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.lk2
4 files changed, 78 insertions, 2 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index e66cf2a..5907e2f 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,5 +1,11 @@
2021-09-27 Nick Alcock <nick.alcock@oracle.com>
+ * ctf-lookup.c (ctf_lookup_by_name_internal): Fix pptrtab bounds.
+ * testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.*:
+ New test.
+
+2021-09-27 Nick Alcock <nick.alcock@oracle.com>
+
* testsuite/libctf-lookup/enum-symbol.c: Remove unused label.
* testsuite/libctf-lookup/conflicting-type-syms.c: Remove unused
variables.
diff --git a/libctf/ctf-lookup.c b/libctf/ctf-lookup.c
index fe66bc4..d1828f8 100644
--- a/libctf/ctf-lookup.c
+++ b/libctf/ctf-lookup.c
@@ -176,7 +176,7 @@ ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
int in_child = 0;
ntype = CTF_ERR;
- if (child && idx <= child->ctf_pptrtab_len)
+ if (child && idx < child->ctf_pptrtab_len)
{
ntype = child->ctf_pptrtab[idx];
if (ntype)
@@ -206,7 +206,7 @@ ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
idx = LCTF_TYPE_TO_INDEX (fp, ntype);
ntype = CTF_ERR;
- if (child && idx <= child->ctf_pptrtab_len)
+ if (child && idx < child->ctf_pptrtab_len)
{
ntype = child->ctf_pptrtab[idx];
if (ntype)
diff --git a/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.c b/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.c
new file mode 100644
index 0000000..ca42065
--- /dev/null
+++ b/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.c
@@ -0,0 +1,68 @@
+/* Make sure we can look up a pointer-to-type where the type is more than a page
+ into the parent and the child has never had a lookup before. */
+
+#include <ctf-api.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main (void)
+{
+ ctf_dict_t *pfp, *cfp;
+ ctf_encoding_t e = { CTF_INT_SIGNED, 0, sizeof (long) };
+ ctf_id_t ptype, ptrtype, type, foo;
+ size_t i;
+ int err;
+
+ if ((pfp = ctf_create (&err)) == NULL)
+ goto create_err;
+
+ if ((ptype = ctf_add_integer (pfp, CTF_ADD_NONROOT, "blah", &e)) == CTF_ERR)
+ goto create_parent;
+
+ for (i = 0; i < 4096; i++)
+ if ((foo = ctf_add_pointer (pfp, CTF_ADD_NONROOT, ptype)) == CTF_ERR)
+ goto create_parent;
+
+ if ((cfp = ctf_create (&err)) == NULL)
+ goto create_err;
+
+ if (ctf_import (cfp, pfp) < 0)
+ goto create_child;
+
+ if ((ptype = ctf_add_integer (pfp, CTF_ADD_ROOT, "foo", &e)) == CTF_ERR)
+ goto create_parent;
+
+ if ((ptrtype = ctf_add_pointer (pfp, CTF_ADD_ROOT, ptype)) == CTF_ERR)
+ goto create_parent;
+
+ if ((type = ctf_lookup_by_name (cfp, "*foo")) != CTF_ERR)
+ {
+ fprintf (stderr, "Type lookup unexpectedly succeeded: %s\n", ctf_errmsg (ctf_errno (cfp)));
+ exit (1);
+ }
+
+ if ((type = ctf_lookup_by_name (cfp, "foo *")) == CTF_ERR)
+ {
+ fprintf (stderr, "Type lookup error: %s\n", ctf_errmsg (ctf_errno (cfp)));
+ exit (1);
+ }
+
+ ctf_dict_close (cfp);
+ ctf_dict_close (pfp);
+
+ printf ("Type lookup succeeded.\n");
+
+ return 0;
+
+ create_err:
+ fprintf (stderr, "Creation failed: %s\n", ctf_errmsg (err));
+ exit (1);
+ create_parent:
+ fprintf (stderr, "Cannot create parent type: %s\n", ctf_errmsg (ctf_errno (pfp)));
+ exit (1);
+ create_child:
+ fprintf (stderr, "Cannot create child type: %s\n", ctf_errmsg (ctf_errno (cfp)));
+ exit (1);
+}
diff --git a/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.lk b/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.lk
new file mode 100644
index 0000000..4f23d14
--- /dev/null
+++ b/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.lk
@@ -0,0 +1,2 @@
+Type lookup succeeded.
+