Bugzilla – Bug 65236
VUL-0: kernel: ia64 ptrace local crash
Last modified: 2021-10-27 15:42:38 UTC
SM-Tracker-253
CAN-2005-0135
From: Alexander Icasiano <alexi@sgi.com> User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206) To: dann frazier <dannf@hp.com> Cc: Mike O'Connor <mjo@dojo.mi.org>, vendor-sec List <vendor-sec@lst.de>, davidm@hpl.hp.com, bjorn.helgaas@hp.com Subject: Re: [vendor-sec] ia64 ptrace corner cases Errors-To: vendor-sec-admin@lst.de Date: Fri, 11 Feb 2005 09:19:36 -0800 SGI assigns CVE CAN-2005-0136 to the vulnerability fixed by: http://lia64.bkbits.net:8080/linux-ia64-release-2.6.11/cset@41f2d1eePludGYyb1yOmGaW6Iois8Q [IA64] clean up ptrace corner cases Hope that helps, Alex
Subject: Re: [vendor-sec] ia64 ptrace corner cases To: vendor-sec List <vendor-sec@lst.de> From: Mike O'Connor <mjo@dojo.mi.org> Reply-To: Mike O'Connor <mjo@dojo.mi.org> Errors-To: vendor-sec-admin@lst.de Date: Mon, 14 Feb 2005 19:26:19 -0500 (EST) :SGI assigns CVE CAN-2005-0136 to the vulnerability fixed by: :http://lia64.bkbits.net:8080/linux-ia64-release-2.6.11/cset@41f2d1eePludGYyb1yOmGaW6Iois8Q : :[IA64] clean up ptrace corner cases Here's the exploit for those who care. Our folks are working on 2.4.21-esque fixes, and we'll pass along when ready. =========================================================================== I copied some contents of emails. I am on vacation and can't connect to my server to get the latest test case, but the attached case should trigger the bug in base kernel 2.4. Pls. See http://www.gelato.unsw.edu.au/linux-ia64/0409/11073.html. Stephane Eranian ran into it by strace. When I used 'strace -f', the problem is a little different from Stephane's. Kernel printed stack dump info and killed the test program. I checked the source codes and found that 'strace -f' will change the arg values of the straced process. Then, I created the scenario to trigger the bug. Scenario: We could write program A by assemble codes. Before calling break.i to trap into kernel, the application alloc 70 GR and let 60GR at out area. Write another program B. B will ptrace A. When A traps into kernel to call sys_clone2, it will sleep at ia64_trace_syscall=> syscall_trace_leave=> syscall_trace=>ptrace_notify just like what I write in the email. Look at the disassembled codes of ia64_trace_syscall, ia64_trace_syscall uses 'alloc r41=ar.pfs,11,11,0' to setup its current frame, so the out area(60 GR) has far more than 11. The surplus will be used by syscall_trace_leave=> syscall_trace=>ptrace_notify. When application sleeps in ptrace_notify, application B could call ptrace to change the values of all the 60GR. You know, now all 60 GRs are store in RBS in kernel. So after application A is woken up, kernel might panic because kernel was using them too. I wrote the *malicious* test case to trigger the security hole. It calls sys_ptrace instead of using command strace. It includes 3 parts. 1) driver.c 2) child.c 3) myclone.S Start ./dirver, then driver will fork and exec child, so driver process is the parent of child. Then, driver ptraces child by sys_ptrace with flag PTRACE_O_TRACEFORK|PTRACE_O_TRACECLONE. When child calls __myclone2 to trap into kernel, kernel will let child sleep at do_fork()->ptrace_notify()->ptrace_stop() and notify driver process, then driver process will call sys_ptrace to change the out registers in function __myclone2 of child. Function __myclone2 intentionally allocates 8 local registers and 76 out registers by assembly codes. When process child traps in kernel by sys_clone2, r46 of function __myclone2 will become r38 in function sys_clone2 in kernel, which is used to store rp. And r38(r46) will be stored in kernel stack of process child when it sleeps in kernel. Process driver could change the value of r38(r46) to the address of function panic. Then, when process child restores to run in kernel, r38(r46) will be restored with the address of function panic, then kerne! l will panic when child exits from kernel. The attachment is the test case to trigger the bug in base kernel 2.6. I think kernel 2.4 also has the problem. Yanmin begin 644 new09_stuff.tar
Created attachment 28493 [details] new09_stuff.tar uudecode'd attachment
From: Alex Icasiano <alexi@sgi.com> User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206) To: Mark J Cox <mjc@redhat.com> Cc: Mike O'Connor <mjo@dojo.mi.org>, vendor-sec List <vendor-sec@lst.de>, davidm@hpl.hp.com, bjorn.helgaas@hp.com Subject: Re: [vendor-sec] ia64 ptrace corner cases Errors-To: vendor-sec-admin@lst.de Date: Wed, 16 Feb 2005 08:34:06 -0800 SGI assigns CVE CAN-2005-0137 to this issue. As a reminder, we assigned CAN-2005-0136 to the other ia64 ptrace corner case, hopefully not be confused as they same email subject title. Thanks, Alex
patch for second issue not there yet I think.
Subject: Re: [vendor-sec] ia64 ptrace corner cases To: vendor-sec List <vendor-sec@lst.de> From: Mike O'Connor <mjo@dojo.mi.org> Reply-To: Mike O'Connor <mjo@dojo.mi.org> Errors-To: vendor-sec-admin@lst.de Date: Fri, 18 Feb 2005 23:50:54 -0500 (EST) :> I don't see a 2.4 backport under way. Are they working on this? : :I don't think so; I've added David to the CC in case this has changed. : :> If not, I can see if our engineers can take a whack at it... : :Great, thanks. Here's a 2.4.21 backport for CAN-2005-0136. I'm not sure how this applies to 2.4.{more recent}, and the ia64 community isn't doing a whole lot of maintenance of 2.4.x, but hopefully it helps. You can test with the test code I sent in: https://www.lst.de/cgi-bin/mailman/private/vendor-sec/2005-February/010752.html =========================================================================== linux/arch/ia64/kernel/entry.S ===========================================================================
Created attachment 28648 [details] CAN-2005-0136_ia64-kernel.diff
Date: Mon, 21 Feb 2005 12:38:20 +0100 From: Thomas Biege <thomas@suse.de> To: Thomas Biege <thomas@suse.de> Subject: [joey@infodrom.org: [vendor-sec] Re: ia64 ptrace corner cases] User-Agent: Mutt/1.5.6i ----- Forwarded message from Martin Schulze <joey@infodrom.org> ----- From: Martin Schulze <joey@infodrom.org> To: Free Software Distribution Vendors <vendor-sec@lst.de> User-Agent: Mutt/1.5.6+20040907i Subject: [vendor-sec] Re: ia64 ptrace corner cases Errors-To: vendor-sec-admin@lst.de Date: Mon, 21 Feb 2005 09:33:07 +0100 I'm a bit confused about the status of these vulnerabilities in the IA-64 kernels: CVE Id type 2.4/patch 2.6/patch public? ------------------------------------------------------------------------- CAN-2005-0135 ia64/unwind ??? ??? CVE invisible CAN-2005-0136 ia64/ptrace vendor-sec vuln, [1] CVE invisible CAN-2005-0137 ia64/syscall vendor-sec non-vuln CVE invisible [1] http://lia64.bkbits.net:8080/linux-ia64-release-2.6.11/cset@41f2d1eePludGYyb1yOmGaW6Iois8Q Are all three treated as invisible even though the fix for CAN-2005-0136 is publically available? Regards, Joey
CAN-2005-0137 is this problem: >>The number of entries in the syscall_table is incorrect. The exception >>handling code assumes that there are 255 entries but there are only 254. >>If any user issues syscall number 1024+255 (1279), the exception handler >>jumps to garbage, and voila -- instead of ENOSYS, you get a DoS. >> >>The fix is in arch/ia64/kernel/entry.S >> >>*************** sys_call_table: >>*** 1257,1259 **** >>--- 1257,1260 ---- >>data8 sys_ni_syscall >>data8 sys_ni_syscall >>data8 sys_ni_syscall >>+ data8 sys_ni_syscall
coordinate release date should be 11th of march. (but it's already public, so...)
In 2.6, the situation is even worse. The patch produces lots of huge rejects, and this time one really needs to speak ia64 assembler. Is it ok to resolve this one as WONTFIX, since a fix done by me will surely break the whole kernel?
arch/ia64/kernel/ivt.S is substantially different in 2.6.5. Someone needs to backport the necessary changes.
Intel, HP, can you help with this ia64-specific security issue?
Yanmin Zhang at Intel produced the original fix. Yanmin: please backport to SuSE SLES9-SP1 kernel.
The patch in #10 is for a 2.4.21 kernel, no use on SLES9. Bjorn Helgaas has included the ptrace fix in linux-2.4.29-ia64-050312. I will take a look at backporting from 2.6.11 to SLES9, if Yanmin Zhang does not beet me to it.
Created attachment 32130 [details] Patch against 2.6.5-SLES9_SP1_BRANCH_20050311102304 With a bit of juggling in ivt.S::ia64_syscall_setup, I managed to keep the code size down to just one extra bundle. Most of the patch is the same as 2.6.11, ia64_syscall_setup is significantly different. It works for me, but it would be nice to get a review of ia64_syscall_setup by somebody else who is familiar with the code.
Thanks very much! Fix has been committed to affected trees.
Thanks a lot, Keith! Yanmin (or Tony), if you could have a look as Keith requested, we'd appreciate that.
for tracking
argh. we have applied our 2.4 backport and it now no longer boots. We need a 2.4 backport of the orignal patch.
Jan, Clyde, can you help? The 2.4 version in attachment #31803 [details] has an issue.
http://lia64.bkbits.net:8080/linux-ia64-2.4/cset%4042336f6cz5HsmJFjYj1_N0adSnqKvg is the patch in ia64 bitkeeper.
From simply looking at the patch I can't see anything bad.
The reason for the problem is that the added code makes the break fault handler overflow its (fixed) space in the IVT (and of course as with everything in Linux no mechanism exists to detect this at build time). The brute-force solution would be to move demine_args out of the IVT; I'll have to check tomorrow if, with not too intrusive changes, I can rearrange existing code to avoid that.
I'm confused :(. To which kernel do comments #34 and #38 apply? I checked 2.4.29-ia64-050312 and 2.6.5-SLES9_SP1_BRANCH_20050329143635-sn2, routines ia64_syscall_setup and break_fault. Both routines have plenty of free space before they run into the next ivt entry. Both routines can use up to 64 bundles, break_fault uses ~20, ia64_syscall_setup uses ~30 bundles.
To 2.4.21-283 and 2.4.21-286 (the mentioned function demine_args doesn't even exist anymore in 2.4.29).
(In reply to comment #40) > To 2.4.21-283 and 2.4.21-286 (the mentioned function demine_args doesn't even > exist anymore in 2.4.29). That makes more sense. For those kernels, move the entire demine_args function from the end of break_fault to immediately after the line 'FAULT(13)'. There are 62 spare bundles in the fault 13 area, more than enough for demine_args. If SLES already has code parked in fault 13, find another free fault area of 64 bundles.
Created attachment 32962 [details] 2.4.21-286 version of patch
Created attachment 32963 [details] 2.4.21-286 version of patch (demine_args moved) Second version, following the recommendations in comments #38 and #40.
andreas, can you test this patch please?
gerald, perhaps you can have someone test this.
Raymund, can you please help testing this? Keith, if you could eyeball the patch, that would be great as well!
The 2.4 patch looks OK.
Thanks, Keith! I'll give it a try...
Well, that patch compiles and boots just fine. Even 'strace' is working. Now, do I need to "backport" that exploit from comment #5 to 2.4.21? Or does somebody else have it ready?
There have been attempts to backport the exploit from 2.6 to various 2.4 kernels without success. 2.4 is different enough (and 2.4.21 is different from 2.4.29 in this area) that the original exploit does not work. Instead of the exploit, I tested the SGI patch with a bit of assembler that created frames with 7, 8 or 9 output registers, loaded r15 with 1041 (getpid) and issued break 0x100000. 7 and 8 output registers should work, 9 should fail. I also tried loading r15 with a NaT value and issuing break 0x100000, that should also fail. int main(void) { register int ret asm("r8"); __asm__ ( "{" "alloc r2=ar.pfs,0,0,9,0\n" "mov r3=0\n" ";;\n" "mov r15=1041\n" "}" ";;\n" "//ld8.s r15=[r3]\n" "break.i 0x100000\n" ::: "r2", "r3", "r15" ); return ret; } The fourth digit in alloc is the output frame size. Uncomment ld8.s to issue a syscall with r15 containing NaT.
First of all: Thanks, Jan, for the patch! Second, thanks again, Keith, for confirming that "backporting" isn't trivial. Besides, that patch has been committed to CVS (kernel-source HEAD) in the meantime and Marcus requested to get this one back for further tracking...
I'm really sorry to review the patch at comment #43 too late. There are 2 problems in the patch. If frame size is more than local+8, the patch chooses to use sys_ni_syscall, so path break_fault=>ia64_trace_syscall=>invoke_syscall_trace=>syscall_trace is still executed and process might sleep if it is ptraced. Then, the parent process could clobber the registers of the child. Secondly, if frame size is more than local+8, -EINVAL should be returned instead of -ENOSYS.
Created attachment 37157 [details] The patch against kernel suse8_2.4.21-277 This is the patch against kernel suse8 2.4.21-277. I tested it on my IA64 machine. I can't get the source codes of 2.4.21-286. Who could help apply it to kernel 2.4.21-286 and test it? Sorry to post the patch so late.
I worked out the patch based on Jan's patch. Thank Jan.
released ul1-ia64 kernel updates now with this patch. sles9-ia64 kernel was already released.