Bug 1670019 (CVE-2019-6706)

Summary: CVE-2019-6706 lua: use-after-free in lua_upvaluejoin in lapi.c resulting in denial of service
Product: [Other] Security Response Reporter: msiddiqu
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: abhgupta, bugzilla-redhat, dbaker, jokerman, packaging-team-maint, sisharma, sthangav, trankin
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2019-11-06 00:51:54 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1670020, 1670167, 1670261    
Bug Blocks: 1670022    

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. 
```

Comment 11 errata-xmlrpc 2019-11-05 22:07:45 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 8

Via RHSA-2019:3706 https://access.redhat.com/errata/RHSA-2019:3706

Comment 12 Product Security DevOps Team 2019-11-06 00:51:54 UTC
This bug is now closed. Further updates for individual products will be reflected on the CVE page(s):

https://access.redhat.com/security/cve/cve-2019-6706