Bug 1670019 (CVE-2019-6706) - CVE-2019-6706 lua: use-after-free in lua_upvaluejoin in lapi.c resulting in denial of service
Summary: CVE-2019-6706 lua: use-after-free in lua_upvaluejoin in lapi.c resulting in d...
Status: NEW
Alias: CVE-2019-6706
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard: impact=moderate,public=20190110,repor...
Keywords: Security
: 1669031 (view as bug list)
Depends On: 1670167 1670261 1670020
Blocks: 1670022
TreeView+ depends on / blocked
 
Reported: 2019-01-28 12:28 UTC by msiddiqu
Modified: 2019-04-30 10:59 UTC (History)
8 users (show)

(edit)
Clone Of:
(edit)
Last Closed:


Attachments (Terms of Use)

Description msiddiqu 2019-01-28 12:28:55 UTC
Discovered in lua-5.3.5

Lua 5.3.5 has a use-after-free in lua_upvaluejoin in lapi.c. For example, a crash outcome might be achieved by an attacker who is able to trigger a debug.upvaluejoin call in which the arguments have certain relationships.

Upstream: 

http://lua.2524044.n2.nabble.com/CVE-2019-6706-use-after-free-in-lua-upvaluejoin-function-tc7685575.html
http://lua.2524044.n2.nabble.com/Bug-Report-Use-after-free-in-debug-upvaluejoin-tc7685506.html

Comment 1 msiddiqu 2019-01-28 12:29:09 UTC
Created lua tracking bugs for this issue:

Affects: fedora-all [bug 1670020]

Comment 3 Tomas Hoger 2019-01-28 13:25:55 UTC
*** Bug 1669031 has been marked as a duplicate of this bug. ***

Comment 4 Scott Gayou 2019-01-28 19:45:10 UTC
upvaluejoin seems to have been added in 5.2 [1]. Thus, Red Hat Enterprise Linux 6 and 7 are not impacted. (stdin:1: attempt to call field 'upvaluejoin' (a nil value))

[1] - http://lua-users.org/wiki/LuaFiveTwo

Comment 6 Scott Gayou 2019-01-28 20:24:29 UTC
I believe the final call to lua_upvaluejoin segfaults during the call to the luaC_upvalbarrier macro.

luaC_upvalbarrier(L, *up1); 

```
#define luaC_upvalbarrier(L,uv) ( \
        (iscollectable((uv)->v) && !upisopen(uv)) ? \
         luaC_upvalbarrier_(L,uv) : cast_void(0))
```

iscollectable eventually dereferences (uv)->v, which is NULL.

luaC_upvdeccount(L, *up1); seems to set (uv)-> to NULL as it frees after refcount is equal to zero.

```
void luaC_upvdeccount (lua_State *L, UpVal *uv) {
  lua_assert(uv->refcount > 0);
  uv->refcount--;
  if (uv->refcount == 0 && !upisopen(uv))
    luaM_free(L, uv);
}
```

Presumably this happens because upvaljoin is called with two of the same objects (not anticipated?) instead of two separate upvalues. Just a guess, not a lua expert.

```
debug.upvaluejoin (f1, n1, f2, n2)

Make the n1-th upvalue of the Lua closure f1 refer to the n2-th upvalue of the Lua closure f2. 
```


Note You need to log in before you can comment on or make changes to this bug.