[Bug 279772] use (write) after free in libedit's em_copy_prev_word()
Date: Sat, 15 Jun 2024 20:17:43 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279772 Bug ID: 279772 Summary: use (write) after free in libedit's em_copy_prev_word() Product: Base System Version: CURRENT Hardware: Any OS: Any Status: New Severity: Affects Some People Priority: --- Component: bin Assignee: bugs@FreeBSD.org Reporter: rtm@lcs.mit.edu Attachment #251479 text/plain mime type: Created attachment 251479 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=251479&action=edit demo of a use-after-free in libedit's em_copy_prev_word() em_copy_prev_word() in contrib/libedit/emacs.c: oldc = el->el_line.cursor; /* does a bounds check */ cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, el->el_state.argument, ce__isword); c_insert(el, (int)(oldc - cp)); for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++) *dp++ = *cp; c_insert() can call realloc() on el->el_line.buffer. This means that oldc and cp can end up pointing into the old buffer that realloc() freed. Then the assignment in the for loop reads and writes freed memory. I've attached a demo of this in sh's use of libedit. The demo requires /usr/local/bin/valgrind. $ cc sh11a.c -lutil $ ./a.out ... Invalid read of size 4 at 0x487C1AC: em_copy_prev_word (rtm/freebsd/contrib/libedit/emacs.c:458) by 0x4889747: el_wgets (rtm/freebsd/contrib/libedit/read.c:540) by 0x4879B3C: el_gets (rtm/freebsd/contrib/libedit/eln.c:75) by 0x123D6E: preadfd (rtm/freebsd/bin/sh/input.c:138) by 0x12387A: preadbuffer (rtm/freebsd/bin/sh/input.c:210) by 0x1326C5: xxreadtoken (rtm/freebsd/bin/sh/parser.c:910) by 0x12E4FC: readtoken (rtm/freebsd/bin/sh/parser.c:827) by 0x12E379: parsecmd (rtm/freebsd/bin/sh/parser.c:222) by 0x129786: cmdloop (rtm/freebsd/bin/sh/main.c:206) by 0x1295D2: main (rtm/freebsd/bin/sh/main.c:167) Address 0x553d160 is 0 bytes inside a block of size 8,192 free'd at 0x4851951: realloc (vg_replace_malloc.c:1694) by 0x48732AA: ch_enlargebufs (rtm/freebsd/contrib/libedit/chared.c:502) by 0x487318C: c_insert (rtm/freebsd/contrib/libedit/chared.c:104) by 0x487C16A: em_copy_prev_word (rtm/freebsd/contrib/libedit/emacs.c:456) by 0x4889747: el_wgets (rtm/freebsd/contrib/libedit/read.c:540) by 0x4879B3C: el_gets (rtm/freebsd/contrib/libedit/eln.c:75) by 0x123D6E: preadfd (rtm/freebsd/bin/sh/input.c:138) by 0x12387A: preadbuffer (rtm/freebsd/bin/sh/input.c:210) by 0x1326C5: xxreadtoken (rtm/freebsd/bin/sh/parser.c:910) by 0x12E4FC: readtoken (rtm/freebsd/bin/sh/parser.c:827) by 0x12E379: parsecmd (rtm/freebsd/bin/sh/parser.c:222) by 0x129786: cmdloop (rtm/freebsd/bin/sh/main.c:206) Block was alloc'd at at 0x4851951: realloc (vg_replace_malloc.c:1694) by 0x48732AA: ch_enlargebufs (rtm/freebsd/contrib/libedit/chared.c:502) by 0x4875B8D: ed_insert (rtm/freebsd/contrib/libedit/common.c:86) by 0x4889747: el_wgets (rtm/freebsd/contrib/libedit/read.c:540) by 0x4879B3C: el_gets (rtm/freebsd/contrib/libedit/eln.c:75) by 0x123D6E: preadfd (rtm/freebsd/bin/sh/input.c:138) by 0x12387A: preadbuffer (rtm/freebsd/bin/sh/input.c:210) by 0x1326C5: xxreadtoken (rtm/freebsd/bin/sh/parser.c:910) by 0x12E4FC: readtoken (rtm/freebsd/bin/sh/parser.c:827) by 0x12E379: parsecmd (rtm/freebsd/bin/sh/parser.c:222) by 0x129786: cmdloop (rtm/freebsd/bin/sh/main.c:206) by 0x1295D2: main (rtm/freebsd/bin/sh/main.c:167) Invalid write of size 4 at 0x487C1BD: em_copy_prev_word (rtm/freebsd/contrib/libedit/emacs.c:458) by 0x4889747: el_wgets (rtm/freebsd/contrib/libedit/read.c:540) by 0x4879B3C: el_gets (rtm/freebsd/contrib/libedit/eln.c:75) by 0x123D6E: preadfd (rtm/freebsd/bin/sh/input.c:138) by 0x12387A: preadbuffer (rtm/freebsd/bin/sh/input.c:210) by 0x1326C5: xxreadtoken (rtm/freebsd/bin/sh/parser.c:910) by 0x12E4FC: readtoken (rtm/freebsd/bin/sh/parser.c:827) by 0x12E379: parsecmd (rtm/freebsd/bin/sh/parser.c:222) by 0x129786: cmdloop (rtm/freebsd/bin/sh/main.c:206) by 0x1295D2: main (rtm/freebsd/bin/sh/main.c:167) Address 0x553e164 is 4,100 bytes inside a block of size 8,192 free'd at 0x4851951: realloc (vg_replace_malloc.c:1694) by 0x48732AA: ch_enlargebufs (rtm/freebsd/contrib/libedit/chared.c:502) by 0x487318C: c_insert (rtm/freebsd/contrib/libedit/chared.c:104) by 0x487C16A: em_copy_prev_word (rtm/freebsd/contrib/libedit/emacs.c:456) by 0x4889747: el_wgets (rtm/freebsd/contrib/libedit/read.c:540) by 0x4879B3C: el_gets (rtm/freebsd/contrib/libedit/eln.c:75) by 0x123D6E: preadfd (rtm/freebsd/bin/sh/input.c:138) by 0x12387A: preadbuffer (rtm/freebsd/bin/sh/input.c:210) by 0x1326C5: xxreadtoken (rtm/freebsd/bin/sh/parser.c:910) by 0x12E4FC: readtoken (rtm/freebsd/bin/sh/parser.c:827) by 0x12E379: parsecmd (rtm/freebsd/bin/sh/parser.c:222) by 0x129786: cmdloop (rtm/freebsd/bin/sh/main.c:206) Block was alloc'd at at 0x4851951: realloc (vg_replace_malloc.c:1694) by 0x48732AA: ch_enlargebufs (rtm/freebsd/contrib/libedit/chared.c:502) by 0x4875B8D: ed_insert (rtm/freebsd/contrib/libedit/common.c:86) by 0x4889747: el_wgets (rtm/freebsd/contrib/libedit/read.c:540) by 0x4879B3C: el_gets (rtm/freebsd/contrib/libedit/eln.c:75) by 0x123D6E: preadfd (rtm/freebsd/bin/sh/input.c:138) by 0x12387A: preadbuffer (rtm/freebsd/bin/sh/input.c:210) by 0x1326C5: xxreadtoken (rtm/freebsd/bin/sh/parser.c:910) by 0x12E4FC: readtoken (rtm/freebsd/bin/sh/parser.c:827) by 0x12E379: parsecmd (rtm/freebsd/bin/sh/parser.c:222) by 0x129786: cmdloop (rtm/freebsd/bin/sh/main.c:206) by 0x1295D2: main (rtm/freebsd/bin/sh/main.c:167) -- You are receiving this mail because: You are the assignee for the bug.