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

Another use-after-free bug in everyone's favorite function: varsub() #576

Open
krader1961 opened this issue Jun 5, 2018 · 1 comment
Open
Labels

Comments

@krader1961
Copy link
Contributor

While working to reach zero unit test failures on OpenBSD I noticed that sometimes the types unit test would die with a SIGSEGV in the varsub() function. I finally got around to analyzing a core file. Here is the relevant info:

(gdb) frame 6
#6  0x15ccf46c in varsub (mp=0x84cd8d00) at ../src/cmd/ksh93/sh/macro.c:1795
1795                    mac_copy(mp, v, vsize > 0 ? vsize : strlen(v));
(gdb) p v
$1 = 0x7f042650 <Address 0x7f042650 out of bounds>
(gdb) p *np
$2 = {nvlink = {rh = {__rght = 0x0, __ptbl = 0x0}, lh = {__left = 0x35caa17c, __hash = 902472060}}, nvname = 0x7ce39ba6 "f", nvflag = 4608,
  nvsize = 0, nvfun = 0x81a86b38, nvalue = {vp = 0x7f042650, cp = 0x7f042650 <Address 0x7f042650 out of bounds>,
    sp = 0x7f042650 <Address 0x7f042650 out of bounds>, ip = 0x7f042650, c = 80 'P', i = 2130978384, u = 2130978384, lp = 0x7f042650,
    pidp = 0x7f042650, uidp = 0x7f042650, llp = 0x7f042650, i16 = 9808, i16p = 0x7f042650, dp = 0x7f042650, ldp = 0x7f042650, f = 1.75657025e+38,
    fp = 0x7f042650, array = 0x7f042650, np = 0x7f042650, up = 0x7f042650, rp = 0x7f042650, funp = 0x7f042650, nrp = 0x7f042650, bfp = 0x7f042650,
    pathcomp = 0x7f042650}, nvshell = 0x35caa17c, nvenv = 0x0}

The failure is because the value of v is in a page that is no longer mapped. On macOS this manifests as a test failure:

<E> types[714]: z.out wrong value
<E> expect: |foo f 123|
<E> actual: |foo f áO|
<W> types[-1]: error_count = 1

Notice that the actual value has been corrupted. A strong indication the buffer was freed and part of it was reused by a subsequent allocation. Coupled with the failure mode on OpenBSD it is a certainty this is a use-after-free bug.

@kernigh
Copy link
Contributor

kernigh commented Jun 7, 2018

I saw for the first time today, also on OpenBSD: types/C failed because strlen() got SIGSEGV, because varsub() called strlen(v) with the unmapped v, perhaps set by v = nv_getval(np) on line 1724.

(gdb) frame 5
#5  0x00001266465759ed in varsub (mp=0x12691f28ae80)
    at ../src/cmd/ksh93/sh/macro.c:1694
1694                    mac_copy(mp, v, vsize > 0 ? vsize : strlen(v));
(gdb) print v
$10 = 0x1268a8772840 <error: Cannot access memory at address 0x1268a8772840>
(gdb) print vsize
$11 = -1
(gdb) print np->nvalue.cp
$29 = 0x1268a8772840 <error: Cannot access memory at address 0x1268a8772840>

@krader1961 krader1961 changed the title Another use-after-free bug in everyone's favorite function Another use-after-free bug in everyone's favorite function: varsub() Jun 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants