aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2020-06-02 20:17:51 +0100
committerNick Alcock <nick.alcock@oracle.com>2020-07-22 17:57:22 +0100
commitafd78bd6f0a30ba57adaea870c05cbbb925cc769 (patch)
tree5aa833e003150dab85ed8b1c9a544bf1dce64691
parent2361f1c85913a0ff0955069bf3182011765a8ae8 (diff)
downloadbinutils-afd78bd6f0a30ba57adaea870c05cbbb925cc769.zip
binutils-afd78bd6f0a30ba57adaea870c05cbbb925cc769.tar.gz
binutils-afd78bd6f0a30ba57adaea870c05cbbb925cc769.tar.bz2
libctf, create: do not corrupt function types' arglists at insertion time
ctf_add_function assumes that function types' arglists are of type ctf_id_t. Since they are CTF IDs, they are 32 bits wide, a uint32_t: unfortunately ctf_id_t is a forward-compatible user-facing 64 bits wide, and should never ever reach the CTF storage level. All the CTF code other than ctf_add_function correctly assumes that function arglists outside dynamic containers are 32 bits wide, so the serialization machinery ends up cutting off half the arglist, corrupting all args but the first (a good sign is a bunch of args of ID 0, the unimplemented type, popping up). Fix this by copying the arglist into place item by item, casting it properly, at the same time as we validate the arg types. Fix the type of the dtu_argv in the dynamic container and drop the now-unnecessary cast in the serializer. libctf/ * ctf-impl.h (ctf_dtdef_t) <dtu_argv>: Fix type. * ctf-create.c (ctf_add_function): Check for unimplemented type and populate at the same time. Populate one-by-one, not via memcpy. (ctf_serialize): Remove unnecessary cast. * ctf-types.c (ctf_func_type_info): Likewise. (ctf_func_type_args): Likewise. Fix comment typo.
-rw-r--r--libctf/ChangeLog10
-rw-r--r--libctf/ctf-create.c23
-rw-r--r--libctf/ctf-impl.h2
-rw-r--r--libctf/ctf-types.c6
4 files changed, 27 insertions, 14 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index cca704a..39cf47d 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,5 +1,15 @@
2020-07-22 Nick Alcock <nick.alcock@oracle.com>
+ * ctf-impl.h (ctf_dtdef_t) <dtu_argv>: Fix type.
+ * ctf-create.c (ctf_add_function): Check for unimplemented type
+ and populate at the same time. Populate one-by-one, not via
+ memcpy.
+ (ctf_serialize): Remove unnecessary cast.
+ * ctf-types.c (ctf_func_type_info): Likewise.
+ (ctf_func_type_args): Likewise. Fix comment typo.
+
+2020-07-22 Nick Alcock <nick.alcock@oracle.com>
+
* ctf-create.c (ctf_add_reftype): Support refs to type zero.
(ctf_add_array): Support array contents of type zero.
(ctf_add_function): Support arguments and return types of
diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c
index 67a3f19..f91da6e 100644
--- a/libctf/ctf-create.c
+++ b/libctf/ctf-create.c
@@ -448,7 +448,7 @@ ctf_serialize (ctf_file_t *fp)
uint32_t argc;
for (argc = 0; argc < vlen; argc++)
- *argv++ = (uint32_t) dtd->dtd_u.dtu_argv[argc];
+ *argv++ = dtd->dtd_u.dtu_argv[argc];
if (vlen & 1)
*argv++ = 0; /* Pad to 4-byte boundary. */
@@ -1052,7 +1052,7 @@ ctf_add_function (ctf_file_t *fp, uint32_t flag,
ctf_dtdef_t *dtd;
ctf_id_t type;
uint32_t vlen;
- ctf_id_t *vdat = NULL;
+ uint32_t *vdat = NULL;
ctf_file_t *tmp = fp;
size_t i;
@@ -1068,19 +1068,23 @@ ctf_add_function (ctf_file_t *fp, uint32_t flag,
&& ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL)
return CTF_ERR; /* errno is set for us. */
- for (i = 0; i < ctc->ctc_argc; i++)
- {
- tmp = fp;
- if (argv[i] != 0 && ctf_lookup_by_id (&tmp, argv[i]) == NULL)
- return CTF_ERR; /* errno is set for us. */
- }
-
if (vlen > CTF_MAX_VLEN)
return (ctf_set_errno (fp, EOVERFLOW));
if (vlen != 0 && (vdat = malloc (sizeof (ctf_id_t) * vlen)) == NULL)
return (ctf_set_errno (fp, EAGAIN));
+ for (i = 0; i < ctc->ctc_argc; i++)
+ {
+ tmp = fp;
+ if (argv[i] != 0 && ctf_lookup_by_id (&tmp, argv[i]) == NULL)
+ {
+ free (vdat);
+ return CTF_ERR; /* errno is set for us. */
+ }
+ vdat[i] = (uint32_t) argv[i];
+ }
+
if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_FUNCTION,
&dtd)) == CTF_ERR)
{
@@ -1091,7 +1095,6 @@ ctf_add_function (ctf_file_t *fp, uint32_t flag,
dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
dtd->dtd_data.ctt_type = (uint32_t) ctc->ctc_return;
- memcpy (vdat, argv, sizeof (ctf_id_t) * ctc->ctc_argc);
if (ctc->ctc_flags & CTF_FUNC_VARARG)
vdat[vlen - 1] = 0; /* Add trailing zero to indicate varargs. */
dtd->dtd_u.dtu_argv = vdat;
diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h
index b20a4f0..fdd48f0 100644
--- a/libctf/ctf-impl.h
+++ b/libctf/ctf-impl.h
@@ -172,7 +172,7 @@ typedef struct ctf_dtdef
ctf_list_t dtu_members; /* struct, union, or enum */
ctf_arinfo_t dtu_arr; /* array */
ctf_encoding_t dtu_enc; /* integer or float */
- ctf_id_t *dtu_argv; /* function */
+ uint32_t *dtu_argv; /* function */
ctf_slice_t dtu_slice; /* slice */
} dtd_u;
} ctf_dtdef_t;
diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c
index cd91043..35253cb 100644
--- a/libctf/ctf-types.c
+++ b/libctf/ctf-types.c
@@ -1163,7 +1163,7 @@ ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
args = (uint32_t *) ((uintptr_t) tp + increment);
else
- args = (uint32_t *) dtd->dtd_u.dtu_argv;
+ args = dtd->dtd_u.dtu_argv;
if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
{
@@ -1174,7 +1174,7 @@ ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
return 0;
}
-/* Given a type ID relating to a function type,, return the arguments for the
+/* Given a type ID relating to a function type, return the arguments for the
function. */
int
@@ -1200,7 +1200,7 @@ ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv
if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
args = (uint32_t *) ((uintptr_t) tp + increment);
else
- args = (uint32_t *) dtd->dtd_u.dtu_argv;
+ args = dtd->dtd_u.dtu_argv;
for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
*argv++ = *args++;