diff options
author | Iain Hibbert <plunky@rya-online.net> | 2010-02-17 18:58:37 +0000 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-02-17 11:14:41 -0800 |
commit | 81913e5a7a971524cfdb0eb2035373bb73be940b (patch) | |
tree | 4272d7676698650df5e9dd66d993f49484787625 | |
parent | 70aeac18802bfa7b5208a761b0873512cf9e5529 (diff) | |
download | bluez-hcidump-81913e5a7a971524cfdb0eb2035373bb73be940b.tar.gz |
Prevent buffer overruns when parsing invalid OBEX frames
-rw-r--r-- | parser/obex.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/parser/obex.c b/parser/obex.c index 133f2a2..50b9737 100644 --- a/parser/obex.c +++ b/parser/obex.c @@ -200,27 +200,55 @@ static void parse_headers(int level, struct frame *frm) printf("%s (0x%02x)", hi2str(hi), hi); switch (hi & 0xc0) { case 0x00: /* Unicode */ + if (frm->len < 2) { + printf("\n"); + return; + } + len = get_u16(frm) - 3; printf(" = Unicode length %d\n", len); + + if (frm->len < len) + return; + raw_ndump(level, frm, len); frm->ptr += len; frm->len -= len; break; case 0x40: /* Byte sequence */ + if (frm->len < 2) { + printf("\n"); + return; + } + len = get_u16(frm) - 3; printf(" = Sequence length %d\n", len); + + if (frm->len < len) + return; + raw_ndump(level, frm, len); frm->ptr += len; frm->len -= len; break; case 0x80: /* One byte */ + if (frm->len < 1) { + printf("\n"); + return; + } + hv8 = get_u8(frm); printf(" = %d\n", hv8); break; case 0xc0: /* Four bytes */ + if (frm->len < 4) { + printf("\n"); + return; + } + hv32 = get_u32(frm); printf(" = %u\n", hv32); break; @@ -276,6 +304,11 @@ void obex_dump(int level, struct frame *frm) switch (opcode & 0x7f) { case 0x00: /* Connect */ + if (frm->len < 4) { + printf("\n"); + return; + } + version = get_u8(frm); flags = get_u8(frm); pktlen = get_u16(frm); @@ -284,17 +317,19 @@ void obex_dump(int level, struct frame *frm) break; case 0x05: /* SetPath */ - if (length > 3) { - flags = get_u8(frm); - constants = get_u8(frm); - printf(" flags %d constants %d\n", - flags, constants); - } else + if (frm->len < 2) { printf("\n"); + return; + } + + flags = get_u8(frm); + constants = get_u8(frm); + printf(" flags %d constants %d\n", flags, constants); break; default: printf("\n"); + break; } if ((status & 0x70) && (parser.flags & DUMP_VERBOSE)) { |