Bug 1460940

Summary: ksh strdup result leak in sh_subshell() when trap used
Product: Red Hat Enterprise Linux 7 Reporter: Siteshwar Vashisht <svashisht>
Component: kshAssignee: Siteshwar Vashisht <svashisht>
Status: CLOSED WONTFIX QA Contact: Karel Volný <kvolny>
Severity: high Docs Contact:
Priority: urgent    
Version: 7.4CC: basinilya, cchouhan, fkrska, jkejda, kdudka, kvolny, ngalvin, pandrade, qe-baseos-apps, rblakley
Target Milestone: rcKeywords: Reopened, Reproducer
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: 1368591 Environment:
Last Closed: 2020-02-05 13:31:14 UTC Type: Bug
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: 1368591    
Bug Blocks: 1719445    
Attachments:
Description Flags
Fix a leak in subshell when trap is used
none
Fix a leak in subshell when trap is used
kdudka: review+
Fix a leak in subshell when trap is used none

Comment 4 Kamil Dudka 2018-03-09 11:13:25 UTC
I can reproduce with ksh distributed with RHEL-7 and Fedora 27 but not with the latest upstream version of ksh.  We will need to check whether it was fixed on purpose, or as a side effect of other code or configuration changes.

Comment 9 Siteshwar Vashisht 2018-03-16 15:09:06 UTC
Created attachment 1408847 [details]
Fix a leak in subshell when trap is used

This has been picked up from latest upstream.

Comment 10 Kamil Dudka 2018-03-16 16:02:44 UTC
Comment on attachment 1408847 [details]
Fix a leak in subshell when trap is used

I did not try to build/run it but the backport looks good.  I think you can remove the 'isig' variable, which becomes unused after applying this patch.  The assignment nsig += sizeof(char *); looks redundant but safe.  It is also not clear why shp->st.otrapcom is assigned.  It does not seem to be read anywhere in the code or am I missing something?

Comment 11 Siteshwar Vashisht 2018-03-19 09:39:54 UTC
The only place I see it being used is here[1].

[1] https://github.com/att/ast/blob/2012-08-01-master/src/cmd/ksh93/bltins/trap.c#L140

Comment 12 Kamil Dudka 2018-03-19 09:51:08 UTC
Indeed.  I overlooked this one.  Then we should probably nullify shp->st.otrapcom after calling free(savsig) to avoid a use after free, but not necessarily in this RHEL-7 fix.

Comment 13 Siteshwar Vashisht 2018-03-19 11:31:16 UTC
Created attachment 1409826 [details]
Fix a leak in subshell when trap is used

Updated patch to remove isig variable.

Comment 19 Siteshwar Vashisht 2018-05-15 13:26:20 UTC
Created attachment 1436790 [details]
Fix a leak in subshell when trap is used

Comment 20 Kamil Dudka 2018-05-25 16:18:13 UTC
Comment on attachment 1436790 [details]
Fix a leak in subshell when trap is used

As noted on IRC, I would modify the code to assign NULL immediately after free() to minimize the window where the array references already freed objects.

Comment 22 Siteshwar Vashisht 2018-09-10 14:57:31 UTC
*** Bug 1577907 has been marked as a duplicate of this bug. ***

Comment 23 Siteshwar Vashisht 2019-08-14 12:04:31 UTC
Patch posted in comment 19 introduces a regression:

test basic failed at 2019-08-14+13:49:32 with exit code 1 [ 102 tests 1 error ]
test basic(C.UTF-8) begins at 2019-08-14+13:49:32
        basic.sh[257]: traps ignored by parent not ignored
test basic(C.UTF-8) failed at 2019-08-14+13:50:01 with exit code 1 [ 102 tests 1 error ]
test basic(shcomp) begins at 2019-08-14+13:50:01
        shcomp-basic.ksh[257]: traps ignored by parent not ignored

Comment 24 RHEL Program Management 2019-08-14 12:05:11 UTC
Development Management has reviewed and declined this request. You may appeal this decision by reopening this request.

Comment 26 Paulo Andrade 2019-08-14 18:58:07 UTC
(In reply to Siteshwar Vashisht from comment #23)
> Patch posted in comment 19 introduces a regression:
> 
> test basic failed at 2019-08-14+13:49:32 with exit code 1 [ 102 tests 1
> error ]
> test basic(C.UTF-8) begins at 2019-08-14+13:49:32
>         basic.sh[257]: traps ignored by parent not ignored
> test basic(C.UTF-8) failed at 2019-08-14+13:50:01 with exit code 1 [ 102
> tests 1 error ]
> test basic(shcomp) begins at 2019-08-14+13:50:01
>         shcomp-basic.ksh[257]: traps ignored by parent not ignored

  The issue should be corrected by reverting ksh-20120801-trapcom.patch
and adding this pseudo patch to sh/subshell.c:

 			nsig += sizeof(char*);
			memcpy(savsig=malloc(nsig),(char*)&shp->st.trapcom[0],nsig);
+			memset((char*)&shp->st.trapcom[0],0,nsig);
 			/* this nonsense needed for $(trap) */
 			shp->st.otrapcom = (char**)savsig;

and equivalent change to sh/xec.c.

  ksh-20120801-trapcom.patch was a rather complex/incorrect correction to #1117404

  The leak happens in sh_sigreset(0) that does set the shp->st.trapcom[X] to
NULL, and only calls free if the mode argument is non zero.

  The upstream code was buggy in that it would save a vector of string pointers,
release the pointers and later restore the vector of string pointers.
  Since sh_sigreset is always called with a zero argument, it means it will always
set the pointers to NULL in sh.st.trapcom[X], calling memset will prevent it from
releasing the pointers in the later call to sh_sigreset(1), *or* to the right thing
at that moment, contrary to ksh-20120801-trapcom.patch.