Sahir Hoda created PROTON-649:
-
Summary: pn_data_vfill buffer read overflow on input beginning
with '['
Key: PROTON-649
URL: https://issues.apache.org/jira/browse/PROTON-649
Project: Qpid Proton
Issue Type: Bug
Components: proton-c
Affects Versions: 0.7, 0.8
Reporter: Sahir Hoda
If the first character of the format string passed to pn_data_vfill is '[', the
function will access memory at one byte preceding the format buffer. This is
due to the following check:
{code}
case '[':
if (*(fmt - 2) != 'T') {
{code}
if the format character is '[', the memory location preceding the format
character is read. If the string begins with '[', however, this read is invalid.
I didn't test with proton-0.8, but it appears from code review that the issue
exists there as well.
The following patch protects against the invalid memory access:
{code}
--- a/proton-c/src/codec/codec.c
+++ b/proton-c/src/codec/codec.c
@@ -467,6 +467,7 @@ int pn_data_intern_node(pn_data_t *data, pni_node_t *node)
int pn_data_vfill(pn_data_t *data, const char *fmt, va_list ap)
{
int err;
+ const char * orig_fmt = fmt;
while (*fmt) {
char code = *(fmt++);
if (!code) return 0;
@@ -568,7 +569,7 @@ int pn_data_vfill(pn_data_t *data, const char *fmt, va_list
ap)
}
break;
case '[':
- if (*(fmt - 2) != 'T') {
+ if ((fmt == (orig_fmt + 1)) || *(fmt - 2) != 'T') {
err = pn_data_put_list(data);
if (err) return err;
pn_data_enter(data);
{code}
I ran into this issue while testing with AddressSanitizer
(https://code.google.com/p/address-sanitizer/wiki/AddressSanitizer), here is
the relevant output:
{noformat}
=
==15828==ERROR: AddressSanitizer: global-buffer-overflow on address
0x7f260637315f at pc 0x7f26062eb6d6 bp 0x7f2602fdaaa0 sp 0x7f2602fdaa98
READ of size 1 at 0x7f260637315f thread T23
#0 0x7f26062eb6d5 in pn_data_vfill
qpid-proton/proton-c/src/codec/codec.c:573
#1 0x7f26062ecabd in pn_data_fill qpid-proton/proton-c/src/codec/codec.c:667
#2 0x7f2606319655 in pni_disposition_encode
qpid-proton/proton-c/src/transport/transport.c:384
#3 0x7f26063267de in pn_post_disp
qpid-proton/proton-c/src/transport/transport.c:1392
#4 0x7f2606328ddc in pn_process_tpwork_receiver
qpid-proton/proton-c/src/transport/transport.c:1488
#5 0x7f2606329319 in pn_process_tpwork
qpid-proton/proton-c/src/transport/transport.c:1521
#6 0x7f260632ad8e in pn_phase
qpid-proton/proton-c/src/transport/transport.c:1693
#7 0x7f260632ae71 in pn_process
qpid-proton/proton-c/src/transport/transport.c:1711
#8 0x7f260632b50e in pn_output_write_amqp
qpid-proton/proton-c/src/transport/transport.c:1760
#9 0x7f260632d26b in pn_io_layer_output_passthru
qpid-proton/proton-c/src/transport/transport.c:1973
#10 0x7f260632d26b in pn_io_layer_output_passthru
qpid-proton/proton-c/src/transport/transport.c:1973
#11 0x7f260632bf04 in transport_produce
qpid-proton/proton-c/src/transport/transport.c:1802
#12 0x7f260632e119 in pn_transport_pending
qpid-proton/proton-c/src/transport/transport.c:2076
#13 0x7f26063591f0 in pn_connector_process
qpid-proton/proton-c/src/posix/driver.c:507
...
0x7f260637315f is located 52 bytes to the right of global variable '*.LC6' from
'qpid-proton/proton-c/src/transport/transport.c' (0x7f2606373120) of size 11
'*.LC6' is ascii string '[?DL[sSC]]'
0x7f260637315f is located 1 bytes to the left of global variable '*.LC7' from
'qpid-proton/proton-c/src/transport/transport.c' (0x7f2606373160) of size 6
'*.LC7' is ascii string '[ooC]'
SUMMARY: AddressSanitizer: global-buffer-overflow
qpid-proton/proton-c/src/codec/codec.c:573 pn_data_vfill
Shadow bytes around the buggy address:
0x0fe540c665d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe540c665e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe540c665f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe540c66600: 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9 00 01 f9 f9
0x0fe540c66610: f9 f9 f9 f9 00 00 02 f9 f9 f9 f9 f9 00 02 f9 f9
=0x0fe540c66620: f9 f9 f9 f9 00 03 f9 f9 f9 f9 f9[f9]06 f9 f9 f9
0x0fe540c66630: f9 f9 f9 f9 00 00 00 00 00 05 f9 f9 f9 f9 f9 f9
0x0fe540c66640: 00 00 00 00 00 04 f9 f9 f9 f9 f9 f9 00 00 00 00
0x0fe540c66650: 00 00 00 00 00 00 00 00 00 00 01 f9 f9 f9 f9 f9
0x0fe540c0: 00 00 00 00 00 00 02 f9 f9 f9 f9 f9 00 00 00 00
0x0fe540c66670: 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9 00 04 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial