Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tcpdump-4.7.3 libpcap-1.7.3 problem from snprintf(buf, bufsize, “%subopt:%u”, 128) try to access 0x80 #10347

Closed
hypSSLAB opened this issue May 18, 2023 · 1 comment

Comments

@hypSSLAB
Copy link

tcpdump-4.7.3
libpcap-1.7.3

Project: libpcap
Fuzzing Engine: AFL-QEMU
Fuzz Target: fuzz_both
Platform Id: linux
Crash Address: 0x00007ffff7eb0717
Crash State:
__strlen_avx2
rpl_dio_printopt
tok2strbuf

Sanitizer:address(ASAN)

snprintf(buf, bufsize, “%subopt:%u”, 128)

-> try to access 0x80

Summary: CRASH detected in __strlen_avx2 due to a fault at or near 0x00000000000000a0 leading to SIGSEGV (si_signo=11) / SEGV_MAPERR (si_code=1)
Command line: ./tcpdump_173 -vvvvXX -ee -nn -r @@
Testcase: ./crash/ID_1_id:000004,sig:11,src:005450,time:22427279,execs:15050838,op:havoc,rep:4

const char *
tok2strbuf(register const struct tok *lp, register const char *fmt,
register u_int v, char *buf, size_t bufsize)
{
if (lp != NULL) {
while (lp->s != NULL) {
if (lp->v == v)
return (lp->s);
++lp;
}
}
if (fmt == NULL)
fmt = "#%d";

(void)snprintf(buf, bufsize, fmt, v);
return (const char *)buf;

}

static void
rpl_dio_printopt(netdissect_options *ndo,
const struct rpl_dio_genoption *opt,
u_int length)
{
if(length < RPL_DIO_GENOPTION_LEN) return;
length -= RPL_DIO_GENOPTION_LEN;

    ND_TCHECK(opt->rpl_dio_len);

    while((opt->rpl_dio_type == RPL_OPT_PAD0 &&
           (u_char *)opt < ndo->ndo_snapend) ||
          ND_TTEST2(*opt,(opt->rpl_dio_len+2))) {

            unsigned int optlen = opt->rpl_dio_len+2;
            if(opt->rpl_dio_type == RPL_OPT_PAD0) {
                    optlen = 1;
                    ND_PRINT((ndo, " opt:pad0"));
            } else {
                    ND_PRINT((ndo, " opt:%s len:%u ",
                              tok2str(rpl_subopt_values, "%subopt:%u", opt->rpl_dio_type),
                              optlen));
                    if(ndo->ndo_vflag > 2) {
                            unsigned int paylen = opt->rpl_dio_len;
                            if(paylen > length) paylen = length;
                            hex_print(ndo,
                                      " ",
                                      ((uint8_t *)opt) + RPL_DIO_GENOPTION_LEN,  /* content of DIO option */
                                      paylen);
                    }
            }
            opt = (struct rpl_dio_genoption *)(((char *)opt) + optlen);
            length -= optlen;
    }
    return;

trunc:
ND_PRINT((ndo," [|truncated]"));
return;
}

Summary: CRASH detected in __strlen_avx2 due to a fault at or near 0x00000000000000a0 leading to SIGSEGV (si_signo=11) / SEGV_MAPERR (si_code=1)
Command line: ./tcpdump_173 -vvvvXX -ee -nn -r @@
Testcase: ./crash/ID_1_id:000004,sig:11,src:005450,time:22427279,execs:15050838,op:havoc,rep:4
Crash bucket: 23acad05b0f5cf25c9fcb4574ba54067

Crashing thread backtrace:
#0 0x00007ffff7eb0717 in __strlen_avx2 (/lib/x86_64-linux-gnu/libc.so.6)
at ../sysdeps/x86_64/multiarch/strlen-avx2.S:96

#1 0x00007ffff7da0d15 in __vfprintf_internal (/lib/x86_64-linux-gnu/libc.so.6)
at vfprintf-internal.c:1688

#2 0x00007ffff7db3f9a in __vsnprintf_internal (/lib/x86_64-linux-gnu/libc.so.6)
at vsnprintf.c:114

#3 0x00007ffff7d89df6 in __GI___snprintf (/lib/x86_64-linux-gnu/libc.so.6)
at snprintf.c:31

#4 0x00000000004ac007 in tok2strbuf (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
318: const tok2strbuf(lp = (const tok *)0x20, fmt = (const char *)0x7fffffffc7a8 "", v = (u_int)161, buf = (char )0x6bd640 "", bufsize = (size_t)128) {
|||:
|||: /
Local reference: const char * fmt = 0x7fffffffc7a8 ""; /
|||: /
Local reference: char * buf = 0x6bd640 ""; /
|||: /
Local reference: size_t bufsize = 128; /
|||: /
Local reference: u_int v = 161; */
329: fmt = "#%d";
330:
331: (void)snprintf(buf, bufsize, fmt, v);
|||:
---: }
at ./util.c:331

#5 0x00000000004ac065 in tok2str (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
339: const tok2str(lp = (const tok *)0x20, fmt = (const char )0x7fffffffc7a8 "", v = (int)161) {
|||:
|||: /
Local reference: char * ret = 0x6bd640 ""; /
|||: /
Local reference: char [4][128] buf = {'\000' <repeats 127 times>, '\000' <repeats 127 times>, '\000' <repeats 127 times>, '\000' <repeats 127 times>}; /
|||: /
Local reference: int idx = 1; /
|||: /
Local reference: const tok * lp = 0x20; /
|||: /
Local reference: const char * fmt = 0x7fffffffc7a8 ""; /
|||: /
Local reference: int v = 161; */
346: ret = buf[idx];
347: idx = (idx+1) & 3;
348: return tok2strbuf(lp, fmt, v, ret, sizeof(buf[0]));
|||:
---: }
at ./util.c:348

#6 0x00000000004af2bc in rpl_dio_printopt (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
671: void rpl_dio_printopt(ndo = (netdissect_options *)0x6beba0 , opt = (const rpl_dio_genoption )0x6c2552, length = (u_int)15857) {
|||:
|||: /
Local reference: netdissect_options * ndo = 0x6beba0 ; /
|||: /
Local reference: const rpl_dio_genoption * opt = 0x6c2552; */
687: ND_PRINT((ndo, " opt:pad0"));
688: } else {
689: ND_PRINT((ndo, " opt:%s len:%u ",
|||:
---: }
at ./print-icmp6.c:689

#7 0x00000000004af761 in rpl_dao_print (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
740: void rpl_dao_print(ndo = (netdissect_options *)0x6beba0 , bp = (const u_char )0x6c254e "", length = (u_int)15863) {
|||:
|||: /
Local reference: netdissect_options * ndo = 0x6beba0 ; /
|||: /
Local reference: const rpl_dio_genoption * opt = 0x6c254e; /
|||: /
Local reference: const u_char * bp = 0x6c254e ""; /
|||: /
Local reference: u_int length = 15863; */
770: if(ndo->ndo_vflag > 1) {
771: const struct rpl_dio_genoption *opt = (struct rpl_dio_genoption *)bp;
772: rpl_dio_printopt(ndo, opt, length);
|||:
---: }
at ./print-icmp6.c:772

#8 0x00000000004afb0c in rpl_print (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
831: void rpl_print(ndo = (netdissect_options *)0x6beba0 , hdr = (const icmp6_hdr *)0x6c2546, bp = (const u_char )0x6c254a "", length = (u_int)15867) {
|||:
|||: /
Local reference: netdissect_options * ndo = 0x6beba0 ; /
|||: /
Local reference: const u_char * bp = 0x6c254a ""; /
|||: /
Local reference: u_int length = 15867; */
862: ND_PRINT((ndo, "Destination Advertisement Object"));
863: if(ndo->ndo_vflag) {
864: rpl_dao_print(ndo, bp, length);
|||:
---: }
at ./print-icmp6.c:864

#9 0x00000000004b0dd7 in icmp6_print (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
889: void icmp6_print(ndo = (netdissect_options *)0x6beba0 , bp = (const u_char *)0x6c2546 "\233\002\004", length = (u_int)15871, bp2 = (const u_char )0x6c251e "a", fragmented = (int)0) {
||||:
||||: /
Local reference: const icmp6_hdr * dp = 0x6c2546; /
||||: /
Local reference: netdissect_options * ndo = 0x6beba0 ; /
||||: /
Local reference: u_int length = 15871; /
1164: case ND_RPL_MESSAGE:
1165: /
plus 4, because struct icmp6_hdr contains 4 bytes of icmp payload */
1166: rpl_print(ndo, dp, &dp->icmp6_data8[0], length-sizeof(struct icmp6_hdr)+4);
||||:
----: }
at ./print-icmp6.c:1166

#10 0x0000000000441308 in ip6_print (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
75: void ip6_print(ndo = (netdissect_options *)0x6beba0 , bp = (const u_char )0x6c251e "a", length = (u_int)2149646397) {
|||:
|||: /
Local reference: const u_char * cp = 0x6c2546 "\233\002\004"; /
|||: /
Local reference: u_int len = 15871; /
|||: /
Local reference: const ip6_hdr * ip6 = 0x6c251e; /
|||: /
Local reference: int fragmented = 0; /
|||: /
Local reference: netdissect_options * ndo = 0x6beba0 ; */
201: return;
202: case IPPROTO_ICMPV6:
203: icmp6_print(ndo, cp, len, (const u_char *)ip6, fragmented);
|||:
---: }
at ./print-ip6.c:203

#11 0x000000000043478d in ethertype_print (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
316: int ethertype_print(ndo = (netdissect_options *)0x6beba0 , ether_type = (u_short)34525, p = (const u_char )0x6c251e "a", length = (u_int)2149646397, caplen = (u_int)113) {
|||:
|||: /
Local reference: netdissect_options * ndo = 0x6beba0 ; /
|||: /
Local reference: const u_char * p = 0x6c251e "a"; /
|||: /
Local reference: u_int length = 2149646397; */
325:
326: case ETHERTYPE_IPV6:
327: ip6_print(ndo, p, length);
|||:
---: }
at ./print-ether.c:327

#12 0x0000000000434302 in ether_print (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
127: void ether_print(ndo = (netdissect_options *)0x6beba0 , p = (const u_char )0x6c251e "a", length = (u_int)2149646397, caplen = (u_int)113, print_encap_header = (void ()(netdissect_options *, const u_char *))0x0, encap_header_arg = (const u_char )0x0) {
|||:
|||: /
Local reference: u_short ether_type = 34525; /
|||: /
Local reference: netdissect_options * ndo = 0x6beba0 ; /
|||: /
Local reference: const u_char * p = 0x6c251e "a"; /
|||: /
Local reference: u_int length = 2149646397; /
|||: /
Local reference: u_int caplen = 113; */
220: }
221: } else {
222: if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) {
|||:
---: }
at ./print-ether.c:222

#13 0x00000000004343cb in ether_if_print (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
243: u_int ether_if_print(ndo = (netdissect_options *)0x6beba0 , h = (const pcap_pkthdr *)0x7fffffffce70, p = (const u_char )0x6c2510 "") {
|||: /
Local reference: const u_char * p = 0x6c2510 ""; /
|||: /
Local reference: netdissect_options * ndo = 0x6beba0 ; /
|||: /
Local reference: const pcap_pkthdr * h = 0x7fffffffce70; */
244: const u_char *p)
245: {
246: ether_print(ndo, p, h->len, h->caplen, NULL, NULL);
|||:
---: }
at ./print-ether.c:246

#14 0x0000000000407cc5 in print_packet (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
2442: void print_packet(user = (u_char *)0x7fffffffcfb0 "\240\353k", h = (const pcap_pkthdr *)0x7fffffffce70, sp = (const u_char )0x6c2510 "") {
||||:
||||: /
Local reference: print_info * print_info = 0x7fffffffcfb0; /
||||: /
Local reference: u_int hdrlen = 0; /
||||: /
Local reference: netdissect_options * ndo = 0x6beba0 ; /
||||: /
Local reference: const pcap_pkthdr * h = 0x7fffffffce70; /
||||: /
Local reference: const u_char * sp = 0x6c2510 ""; */
2467:
2468: if(print_info->ndo_type) {
2469: hdrlen = (*print_info->p.ndo_printer)(print_info->ndo, h, sp);
||||:
----: }
at ./tcpdump.c:2469

#15 0x00000000004d4f75 in pcap_offline_read (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
373: int pcap_offline_read(p = (pcap_t *)0x6c04f0, cnt = (int)-1, callback = (pcap_handler)0x407bef <print_packet>, user = (u_char )0x7fffffffcfb0 "\240\353k") {
|||:
|||: /
Local reference: bpf_insn * fcode = 0x6c07a0; /
|||: /
Local reference: pcap_t * p = 0x6c04f0; /
|||: /
Local reference: u_char * data = 0x6c2510 ""; /
|||: /
Local reference: pcap_pkthdr h = {ts = {tv_sec = 0, tv_usec = 306841}, caplen = 127, len = 2149646411}; /
|||: /
Local reference: pcap_handler callback = 0x407bef <print_packet>; /
|||: /
Local reference: u_char * user = 0x7fffffffcfb0 "\240\353k"; */
407: if ((fcode = p->fcode.bf_insns) == NULL ||
408: bpf_filter(fcode, data, h.len, h.caplen)) {
409: (*callback)(user, &h, data);
|||:
---: }
at ./savefile.c:409

#16 0x00000000004c1ada in pcap_loop (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
852: int pcap_loop(p = (pcap_t *)0x6c04f0, cnt = (int)-1, callback = (pcap_handler)0x407bef <print_packet>, user = (u_char )0x7fffffffcfb0 "\240\353k") {
|||:
|||: /
Local reference: int n = 0; /
|||: /
Local reference: pcap_t * p = 0x6c04f0; /
|||: /
Local reference: int cnt = -1; /
|||: /
Local reference: pcap_handler callback = 0x407bef <print_packet>; /
|||: /
Local reference: u_char * user = 0x7fffffffcfb0 "\240\353k"; */
859: * 0 means EOF, so don't loop if we get 0.
860: */
861: n = pcap_offline_read(p, cnt, callback, user);
|||:
---: }
at ./pcap.c:861

#17 0x000000000040704a in main (/root/ATFF/test/fuzzing_tcpdump/tcpdump_173_afl_qemu_test/tcpdump_173)
999: int main(argc = (int)6, argv = (char *)0x7fffffffe228) {
||||:
||||: /
Local reference: int status = 3; /
||||: /
Local reference: pcap_handler callback = 0x407bef <print_packet>; /
||||: /
Local reference: u_char * pcap_userdata = 0x7fffffffcfb0 "\240\353k"; */
2000:
2001: do {
2002: status = pcap_loop(pd, cnt, callback, pcap_userdata);
||||:
----: }
at ./tcpdump.c:2002

Crash context:
/* Register reference: rdi - 0x00000000000000a0 (160) */
Execution stopped here ==> 0x00007ffff7eb0717: vpcmpeqb ymm1,ymm0,YMMWORD PTR [rdi]

Register info:
rax - 0x0000000000000020 (32)
rbx - 0x00007ffff7d9eb13 (140737351641875)
rcx - 0x0000000000000001 (1)
rdx - 0x00000000000000a1 (161)
rsi - 0x00007fffffffc7a8 (140737488340904)
rdi - 0x00000000000000a0 (160)
rbp - 0x00007fffffffc7e0 (0x7fffffffc7e0)
rsp - 0x00007fffffffc268 (0x7fffffffc268)
r8 - 0x00000000ffffffff (4294967295)
r9 - 0x0000000000000000 (0)
r10 - 0x00000000005143f9 (5325817)
r11 - 0x00000000000000a1 (161)
r12 - 0x00007fffffffc800 (140737488340992)
r13 - 0x00000000005143f8 (5325816)
r14 - 0x00007fffffffc980 (140737488341376)
r15 - 0x0000000000000073 (115)
rip - 0x00007ffff7eb0717 (0x7ffff7eb0717 <__strlen_avx2+71>)
eflags - 0x00010206 ([ PF IF RF ])
cs - 0x00000033 (51)
ss - 0x0000002b (43)
ds - 0x00000000 (0)
es - 0x00000000 (0)
fs - 0x00000000 (0)
gs - 0x00000000 (0)
k0 - 0x0000000000000000 (0)
k1 - 0x0000000000000000 (0)
k2 - 0x0000000000000000 (0)
k3 - 0x0000000000000000 (0)
k4 - 0x0000000000000000 (0)
k5 - 0x0000000000000000 (0)
k6 - 0x0000000000000000 (0)
k7 - 0x0000000000000000 (0)

@jonathanmetzman
Copy link
Contributor

What do you want us to do with this info?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants