Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Jun 2024 20:17:43 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 279772] use (write) after free in libedit's em_copy_prev_word()
Message-ID:  <bug-279772-227@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D279772

            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=3D251479&action=
=3Dedit
demo of a use-after-free in libedit's em_copy_prev_word()

em_copy_prev_word() in contrib/libedit/emacs.c:

        oldc =3D el->el_line.cursor;
        /* does a bounds check */
        cp =3D 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 =3D oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
                *dp++ =3D *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:4=
58)
     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:4=
56)
     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:4=
58)
     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:4=
56)
     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)

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-279772-227>