diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2022-03-18 00:49:11 +0000 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2022-03-23 13:48:32 +0000 |
commit | 84f5c557a4883d336b238e4bf5264bb920e008d9 (patch) | |
tree | 839cf758597853b2d1bd9cd1f535ef11f6226660 /ld/testsuite/ld-ctf | |
parent | 203bfa2f6bd275df4089131bac0a17c278c37a1a (diff) | |
download | gdb-84f5c557a4883d336b238e4bf5264bb920e008d9.zip gdb-84f5c557a4883d336b238e4bf5264bb920e008d9.tar.gz gdb-84f5c557a4883d336b238e4bf5264bb920e008d9.tar.bz2 |
libctf, ld: diagnose corrupted CTF header cth_strlen
The last section in a CTF dict is the string table, at an offset
represented by the cth_stroff header field. Its length is recorded in
the next field, cth_strlen, and the two added together are taken as the
size of the CTF dict. Upon opening a dict, we check that none of the
header offsets exceed this size, and we check when uncompressing a
compressed dict that the result of the uncompression is the same length:
but CTF dicts need not be compressed, and short ones are not.
Uncompressed dicts just use the ctf_size without checking it. This
field is thankfully almost unused: it is mostly used when reserializing
a dict, which can't be done to dicts read off disk since they're
read-only.
However, when opening an uncompressed foreign-endian dict we have to
copy it out of the mmaped region it is stored in so we can endian-
swap it, and we use ctf_size when doing that. When the cth_strlen is
corrupt, this can overrun.
Fix this by checking the ctf_size in all uncompressed cases, just as we
already do in the compressed case. Add a new test.
This came to light because various corrupted-CTF raw-asm tests had an
incorrect cth_strlen: fix all of them so they produce the expected
error again.
libctf/
PR libctf/28933
* ctf-open.c (ctf_bufopen_internal): Always check uncompressed
CTF dict sizes against the section size in case the cth_strlen is
corrupt.
ld/
PR libctf/28933
* testsuite/ld-ctf/diag-strlen-invalid.*: New test,
derived from diag-cttname-invalid.s.
* testsuite/ld-ctf/diag-cttname-invalid.s: Fix incorrect cth_strlen.
* testsuite/ld-ctf/diag-cttname-null.s: Likewise.
* testsuite/ld-ctf/diag-cuname.s: Likewise.
* testsuite/ld-ctf/diag-parlabel.s: Likewise.
* testsuite/ld-ctf/diag-parname.s: Likewise.
Diffstat (limited to 'ld/testsuite/ld-ctf')
-rw-r--r-- | ld/testsuite/ld-ctf/diag-cttname-invalid.s | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-ctf/diag-cttname-null.s | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-ctf/diag-cuname.s | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-ctf/diag-parlabel.s | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-ctf/diag-parname.s | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-ctf/diag-strlen-invalid.d | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-ctf/diag-strlen-invalid.s | 44 |
7 files changed, 54 insertions, 5 deletions
diff --git a/ld/testsuite/ld-ctf/diag-cttname-invalid.s b/ld/testsuite/ld-ctf/diag-cttname-invalid.s index dbfdd21..f025254 100644 --- a/ld/testsuite/ld-ctf/diag-cttname-invalid.s +++ b/ld/testsuite/ld-ctf/diag-cttname-invalid.s @@ -15,7 +15,7 @@ .long 0x8 .long 0x10 .long 0x40 - .long 0x42 + .long 0x37 .long 0x1 .long 0x7 .long 0x7 diff --git a/ld/testsuite/ld-ctf/diag-cttname-null.s b/ld/testsuite/ld-ctf/diag-cttname-null.s index ad6ce60..f3ba212 100644 --- a/ld/testsuite/ld-ctf/diag-cttname-null.s +++ b/ld/testsuite/ld-ctf/diag-cttname-null.s @@ -15,7 +15,7 @@ .long 0x8 .long 0x10 .long 0x40 - .long 0x42 + .long 0x37 .long 0x1 .long 0x7 .long 0x7 diff --git a/ld/testsuite/ld-ctf/diag-cuname.s b/ld/testsuite/ld-ctf/diag-cuname.s index dcdbd62..95f3d72 100644 --- a/ld/testsuite/ld-ctf/diag-cuname.s +++ b/ld/testsuite/ld-ctf/diag-cuname.s @@ -15,7 +15,7 @@ .long 0x8 .long 0x10 .long 0x40 - .long 0x42 + .long 0x37 .long 0x1 .long 0x7 .long 0x7 diff --git a/ld/testsuite/ld-ctf/diag-parlabel.s b/ld/testsuite/ld-ctf/diag-parlabel.s index e0ce57c..b31fb81 100644 --- a/ld/testsuite/ld-ctf/diag-parlabel.s +++ b/ld/testsuite/ld-ctf/diag-parlabel.s @@ -15,7 +15,7 @@ .long 0x8 .long 0x10 .long 0x40 - .long 0x42 + .long 0x37 .long 0x1 .long 0x7 .long 0x7 diff --git a/ld/testsuite/ld-ctf/diag-parname.s b/ld/testsuite/ld-ctf/diag-parname.s index da30e4a..d30178d 100644 --- a/ld/testsuite/ld-ctf/diag-parname.s +++ b/ld/testsuite/ld-ctf/diag-parname.s @@ -15,7 +15,7 @@ .long 0x8 .long 0x10 .long 0x40 - .long 0x42 + .long 0x37 .long 0x1 .long 0x7 .long 0x7 diff --git a/ld/testsuite/ld-ctf/diag-strlen-invalid.d b/ld/testsuite/ld-ctf/diag-strlen-invalid.d new file mode 100644 index 0000000..8a7b69b --- /dev/null +++ b/ld/testsuite/ld-ctf/diag-strlen-invalid.d @@ -0,0 +1,5 @@ +#as: +#source: diag-strlen-invalid.s +#ld: -shared +#name: Diagnostics - String offset invalid. +#warning: .* byte long CTF dictionary overruns .* byte long CTF section diff --git a/ld/testsuite/ld-ctf/diag-strlen-invalid.s b/ld/testsuite/ld-ctf/diag-strlen-invalid.s new file mode 100644 index 0000000..dbfdd21 --- /dev/null +++ b/ld/testsuite/ld-ctf/diag-strlen-invalid.s @@ -0,0 +1,44 @@ + .file "A.c" + .section .ctf,"",@progbits +.Lctf0: + .2byte 0xdff2 + .byte 0x4 + .byte 0 + .long 0 + .long 0 + .long 0x9 + .long 0 + .long 0 + .long 0x4 + .long 0x4 + .long 0x8 + .long 0x8 + .long 0x10 + .long 0x40 + .long 0x42 + .long 0x1 + .long 0x7 + .long 0x7 + .long 0x1 + .long 0xff00 + .long 0x1a000001 + .long 0x8 + .long 0x5 + .long 0 + .long 0x3 + .long 0x3 + .long 0x26000000 + .long 0x6 + .long 0 + .long 0xe000000 + .long 0x2 + .ascii "\0" + .ascii "A\0" + .ascii "B\0" + .ascii "b\0" + .ascii "a\0" + .ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0" + .text + .comm a,8,8 + .ident "GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)" + .section .note.GNU-stack,"",@progbits |