r3628 - in trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian: .
patches patches/series
Simon Horman
horms at costa.debian.org
Fri Jul 29 08:33:28 UTC 2005
Author: horms
Date: 2005-07-29 08:33:26 +0000 (Fri, 29 Jul 2005)
New Revision: 3628
Added:
trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/arch-ia64-ptrace-getregs-putregs.dpatch
trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/arch-ia64-ptrace-restore_sigcontext.dpatch
Modified:
trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog
trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-17
Log:
* arch-ia64-ptrace-getregs-putregs.dpatch
security, ia64: Fux unchecked user-memory accesses in ptrage_getregs()
and ptrace_setregs.
* arch-ia64-ptrace-restore_sigcontext.dpatch
security, ia64, Fix to prevent users from using ptrace to set the pl field
of the ar.rsc reginster to any value, leading to the
ability to overwrite kernel memory.
Note, this patch requires the arch-ia64-ptrace-getregs-putregs.dpatch
patch to apply cleanly.
See CAN-2005-1761.
Modified: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog 2005-07-29 06:33:25 UTC (rev 3627)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog 2005-07-29 08:33:26 UTC (rev 3628)
@@ -136,8 +136,20 @@
x86_64: Compat mode program can hang kernel
See CAN-2005-1765. (Simon Horman)
- -- Simon Horman <horms at debian.org> Fri, 29 Jul 2005 13:22:44 +0900
+ * arch-ia64-ptrace-getregs-putregs.dpatch
+ security, ia64: Fux unchecked user-memory accesses in ptrage_getregs()
+ and ptrace_setregs. (Simon Horman)
+
+ * arch-ia64-ptrace-restore_sigcontext.dpatch
+ security, ia64, Fix to prevent users from using ptrace to set the pl field
+ of the ar.rsc reginster to any value, leading to the
+ ability to overwrite kernel memory.
+ Note, this patch requires the arch-ia64-ptrace-getregs-putregs.dpatch
+ patch to apply cleanly.
+ See CAN-2005-1761. (Simon Horman)
+ -- Simon Horman <horms at debian.org> Fri, 29 Jul 2005 17:24:54 +0900
+
kernel-source-2.6.8 (2.6.8-16) unstable; urgency=low
* smbfs-overrun.dpatch:
Added: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/arch-ia64-ptrace-getregs-putregs.dpatch
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/arch-ia64-ptrace-getregs-putregs.dpatch 2005-07-29 06:33:25 UTC (rev 3627)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/arch-ia64-ptrace-getregs-putregs.dpatch 2005-07-29 08:33:26 UTC (rev 3628)
@@ -0,0 +1,248 @@
+From: David Mosberger <davidm at hpl.hp.com>
+Date: Tue, 5 Oct 2004 04:24:33 +0000 (+0000)
+Subject: [IA64] ptrace.c: Fix unchecked user-memory accesses due to ptrace_{get,set}regs()
+X-Git-Tag: v2.6.9-rc4
+X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/tglx/history.git;a=commitdiff;h=f0e75a5c015d11a397b99566034e618bf2dcdb4c
+
+ [IA64] ptrace.c: Fix unchecked user-memory accesses due to ptrace_{get,set}regs()
+
+ Here is another fix for a sparse-detected bug: turns out
+ ptrace_getregs() and ptrace_putregs() did unchecked user-memory
+ accesses! These were tricky to see, so it's not surprising that they
+ went unnoticed so far. Fortunately, sparse can detect these
+ trivially. Patch below should fix the problem, but it's completely
+ untested (I don't have any testcases for getregs/putregs).
+
+ These were found by sparse.
+
+ Signed-off-by: davidm at hpl.hp.com
+ Signed-off-by: Tony Luck <tony.luck at intel.com>
+---
+
+--- a/arch/ia64/kernel/ptrace.c
++++ b/arch/ia64/kernel/ptrace.c
+@@ -997,12 +997,14 @@ access_uarea (struct task_struct *child,
+ }
+
+ static long
+-ptrace_getregs (struct task_struct *child, struct pt_all_user_regs *ppr)
++ptrace_getregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
+ {
++ unsigned long psr, ec, lc, rnat, bsp, cfm, nat_bits, val;
++ struct unw_frame_info info;
++ struct ia64_fpreg fpval;
+ struct switch_stack *sw;
+ struct pt_regs *pt;
+ long ret, retval;
+- struct unw_frame_info info;
+ char nat = 0;
+ int i;
+
+@@ -1023,12 +1025,21 @@ ptrace_getregs (struct task_struct *chil
+ return -EIO;
+ }
+
++ if (access_uarea(child, PT_CR_IPSR, &psr, 0) < 0
++ || access_uarea(child, PT_AR_EC, &ec, 0) < 0
++ || access_uarea(child, PT_AR_LC, &lc, 0) < 0
++ || access_uarea(child, PT_AR_RNAT, &rnat, 0) < 0
++ || access_uarea(child, PT_AR_BSP, &bsp, 0) < 0
++ || access_uarea(child, PT_CFM, &cfm, 0)
++ || access_uarea(child, PT_NAT_BITS, &nat_bits, 0))
++ return -EIO;
++
+ retval = 0;
+
+ /* control regs */
+
+ retval |= __put_user(pt->cr_iip, &ppr->cr_iip);
+- retval |= access_uarea(child, PT_CR_IPSR, &ppr->cr_ipsr, 0);
++ retval |= __put_user(psr, &ppr->cr_ipsr);
+
+ /* app regs */
+
+@@ -1039,11 +1050,11 @@ ptrace_getregs (struct task_struct *chil
+ retval |= __put_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
+ retval |= __put_user(pt->ar_fpsr, &ppr->ar[PT_AUR_FPSR]);
+
+- retval |= access_uarea(child, PT_AR_EC, &ppr->ar[PT_AUR_EC], 0);
+- retval |= access_uarea(child, PT_AR_LC, &ppr->ar[PT_AUR_LC], 0);
+- retval |= access_uarea(child, PT_AR_RNAT, &ppr->ar[PT_AUR_RNAT], 0);
+- retval |= access_uarea(child, PT_AR_BSP, &ppr->ar[PT_AUR_BSP], 0);
+- retval |= access_uarea(child, PT_CFM, &ppr->cfm, 0);
++ retval |= __put_user(ec, &ppr->ar[PT_AUR_EC]);
++ retval |= __put_user(lc, &ppr->ar[PT_AUR_LC]);
++ retval |= __put_user(rnat, &ppr->ar[PT_AUR_RNAT]);
++ retval |= __put_user(bsp, &ppr->ar[PT_AUR_BSP]);
++ retval |= __put_user(cfm, &ppr->cfm);
+
+ /* gr1-gr3 */
+
+@@ -1053,7 +1064,9 @@ ptrace_getregs (struct task_struct *chil
+ /* gr4-gr7 */
+
+ for (i = 4; i < 8; i++) {
+- retval |= unw_access_gr(&info, i, &ppr->gr[i], &nat, 0);
++ if (unw_access_gr(&info, i, &val, &nat, 0) < 0)
++ return -EIO;
++ retval |= __put_user(val, &ppr->gr[i]);
+ }
+
+ /* gr8-gr11 */
+@@ -1077,7 +1090,9 @@ ptrace_getregs (struct task_struct *chil
+ /* b1-b5 */
+
+ for (i = 1; i < 6; i++) {
+- retval |= unw_access_br(&info, i, &ppr->br[i], 0);
++ if (unw_access_br(&info, i, &val, 0) < 0)
++ return -EIO;
++ __put_user(val, &ppr->br[i]);
+ }
+
+ /* b6-b7 */
+@@ -1088,8 +1103,9 @@ ptrace_getregs (struct task_struct *chil
+ /* fr2-fr5 */
+
+ for (i = 2; i < 6; i++) {
+- retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 0);
+- retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 0);
++ if (unw_get_fr(&info, i, &fpval) < 0)
++ return -EIO;
++ retval |= __copy_to_user(&ppr->fr[i], &fpval, sizeof (fpval));
+ }
+
+ /* fr6-fr11 */
+@@ -1103,8 +1119,9 @@ ptrace_getregs (struct task_struct *chil
+ /* fr16-fr31 */
+
+ for (i = 16; i < 32; i++) {
+- retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 0);
+- retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 0);
++ if (unw_get_fr(&info, i, &fpval) < 0)
++ return -EIO;
++ retval |= __copy_to_user(&ppr->fr[i], &fpval, sizeof (fpval));
+ }
+
+ /* fph */
+@@ -1118,22 +1135,25 @@ ptrace_getregs (struct task_struct *chil
+
+ /* nat bits */
+
+- retval |= access_uarea(child, PT_NAT_BITS, &ppr->nat, 0);
++ retval |= __put_user(nat_bits, &ppr->nat);
+
+ ret = retval ? -EIO : 0;
+ return ret;
+ }
+
+ static long
+-ptrace_setregs (struct task_struct *child, struct pt_all_user_regs *ppr)
++ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
+ {
++ unsigned long psr, ec, lc, rnat, bsp, cfm, nat_bits, val = 0;
++ struct unw_frame_info info;
+ struct switch_stack *sw;
++ struct ia64_fpreg fpval;
+ struct pt_regs *pt;
+ long ret, retval;
+- struct unw_frame_info info;
+- char nat = 0;
+ int i;
+
++ memset(&fpval, 0, sizeof(fpval));
++
+ retval = verify_area(VERIFY_READ, ppr, sizeof(struct pt_all_user_regs));
+ if (retval != 0) {
+ return -EIO;
+@@ -1156,7 +1176,7 @@ ptrace_setregs (struct task_struct *chil
+ /* control regs */
+
+ retval |= __get_user(pt->cr_iip, &ppr->cr_iip);
+- retval |= access_uarea(child, PT_CR_IPSR, &ppr->cr_ipsr, 1);
++ retval |= __get_user(psr, &ppr->cr_ipsr);
+
+ /* app regs */
+
+@@ -1167,11 +1187,11 @@ ptrace_setregs (struct task_struct *chil
+ retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
+ retval |= __get_user(pt->ar_fpsr, &ppr->ar[PT_AUR_FPSR]);
+
+- retval |= access_uarea(child, PT_AR_EC, &ppr->ar[PT_AUR_EC], 1);
+- retval |= access_uarea(child, PT_AR_LC, &ppr->ar[PT_AUR_LC], 1);
+- retval |= access_uarea(child, PT_AR_RNAT, &ppr->ar[PT_AUR_RNAT], 1);
+- retval |= access_uarea(child, PT_AR_BSP, &ppr->ar[PT_AUR_BSP], 1);
+- retval |= access_uarea(child, PT_CFM, &ppr->cfm, 1);
++ retval |= __get_user(ec, &ppr->ar[PT_AUR_EC]);
++ retval |= __get_user(lc, &ppr->ar[PT_AUR_LC]);
++ retval |= __get_user(rnat, &ppr->ar[PT_AUR_RNAT]);
++ retval |= __get_user(bsp, &ppr->ar[PT_AUR_BSP]);
++ retval |= __get_user(cfm, &ppr->cfm);
+
+ /* gr1-gr3 */
+
+@@ -1181,11 +1201,9 @@ ptrace_setregs (struct task_struct *chil
+ /* gr4-gr7 */
+
+ for (i = 4; i < 8; i++) {
+- long ret = unw_get_gr(&info, i, &ppr->gr[i], &nat);
+- if (ret < 0) {
+- return ret;
+- }
+- retval |= unw_access_gr(&info, i, &ppr->gr[i], &nat, 1);
++ retval |= __get_user(val, &ppr->gr[i]);
++ if (unw_set_gr(&info, i, val, 0) < 0) /* NaT bit will be set via PT_NAT_BITS */
++ return -EIO;
+ }
+
+ /* gr8-gr11 */
+@@ -1209,7 +1227,8 @@ ptrace_setregs (struct task_struct *chil
+ /* b1-b5 */
+
+ for (i = 1; i < 6; i++) {
+- retval |= unw_access_br(&info, i, &ppr->br[i], 1);
++ retval |= __get_user(val, &ppr->br[i]);
++ unw_set_br(&info, i, val);
+ }
+
+ /* b6-b7 */
+@@ -1220,8 +1239,9 @@ ptrace_setregs (struct task_struct *chil
+ /* fr2-fr5 */
+
+ for (i = 2; i < 6; i++) {
+- retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 1);
+- retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 1);
++ retval |= __copy_from_user(&fpval, &ppr->fr[i], sizeof(fpval));
++ if (unw_set_fr(&info, i, fpval) < 0)
++ return -EIO;
+ }
+
+ /* fr6-fr11 */
+@@ -1235,8 +1255,9 @@ ptrace_setregs (struct task_struct *chil
+ /* fr16-fr31 */
+
+ for (i = 16; i < 32; i++) {
+- retval |= access_fr(&info, i, 0, (unsigned long *) &ppr->fr[i], 1);
+- retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 1);
++ retval |= __copy_from_user(&fpval, &ppr->fr[i], sizeof(fpval));
++ if (unw_set_fr(&info, i, fpval) < 0)
++ return -EIO;
+ }
+
+ /* fph */
+@@ -1250,7 +1271,15 @@ ptrace_setregs (struct task_struct *chil
+
+ /* nat bits */
+
+- retval |= access_uarea(child, PT_NAT_BITS, &ppr->nat, 1);
++ retval |= __get_user(nat_bits, &ppr->nat);
++
++ retval |= access_uarea(child, PT_CR_IPSR, &psr, 1);
++ retval |= access_uarea(child, PT_AR_EC, &ec, 1);
++ retval |= access_uarea(child, PT_AR_LC, &lc, 1);
++ retval |= access_uarea(child, PT_AR_RNAT, &rnat, 1);
++ retval |= access_uarea(child, PT_AR_BSP, &bsp, 1);
++ retval |= access_uarea(child, PT_CFM, &cfm, 1);
++ retval |= access_uarea(child, PT_NAT_BITS, &nat_bits, 1);
+
+ ret = retval ? -EIO : 0;
+ return ret;
Added: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/arch-ia64-ptrace-restore_sigcontext.dpatch
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/arch-ia64-ptrace-restore_sigcontext.dpatch 2005-07-29 06:33:25 UTC (rev 3627)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/arch-ia64-ptrace-restore_sigcontext.dpatch 2005-07-29 08:33:26 UTC (rev 3628)
@@ -0,0 +1,107 @@
+commit 4ea78729b8dbfc400fe165a57b90a394a7275a54
+tree cc8d7def737ca5a4189481466d1e4164eef98313
+parent 7b404b3459db1326bbdc7085edb1f58b98da5826
+author Matthew Chapman <matthewc at hp.com> 1119395960 -0700
+committer Tony Luck <tony.luck at intel.com> 1119395960 -0700
+
+[IA64] ptrace and restore_sigcontext() allow ar.rsc.pl==0
+
+This patch fixes handling of accesses to ar.rsc via ptrace & restore_sigcontext
+[With Thanks to Chris Wright for noticing the restore_sigcontext path]
+
+Signed-off-by: Matthew Chapman <matthewc at hp.com>
+Acked-by: David Mosberger <davidm at hpl.hp.com>
+Signed-off-by: Tony Luck <tony.luck at intel.com>
+
+I:100644 100644 575a8f657b3129bacc8ec2979470ecc84c9b7b3f 6d57aebad485fd35db55c8ffbc9497fd6aba34b9 M arch/ia64/kernel/ptrace.c
+R:100644 100644 499b7e5317cf4f5ac3564ccf55bfdc5dc2829da5 edd9f07860b227a230ab981d1a8691a68bd01a7a M arch/ia64/kernel/signal.c
+
+Key:
+S: Skipped
+I: Included Included verbatim
+D: Deleted Manually deleted by subsequent user edit
+R: Revised Manually revised by subsequent user edit
+
+Rediffed for application to Debian - Horms
+
+--- a/arch/ia64/kernel/ptrace.c 2005-07-29 17:11:31.000000000 +0900
++++ b/arch/ia64/kernel/ptrace.c 2005-07-29 17:17:15.000000000 +0900
+@@ -854,6 +854,13 @@
+ *data = (pt->cr_ipsr & IPSR_READ_MASK);
+ return 0;
+
++ case PT_AR_RSC:
++ if (write_access)
++ pt->ar_rsc = *data | (3 << 2); /* force PL3 */
++ else
++ *data = pt->ar_rsc;
++ return 0;
++
+ case PT_AR_RNAT:
+ urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
+ rnat_addr = (long) ia64_rse_rnat_addr((long *) urbs_end);
+@@ -909,9 +916,6 @@
+ ptr = (unsigned long *)
+ ((long) pt + offsetof(struct pt_regs, ar_bspstore));
+ break;
+- case PT_AR_RSC:
+- ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_rsc));
+- break;
+ case PT_AR_UNAT:
+ ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_unat));
+ break;
+@@ -1144,7 +1148,7 @@
+ static long
+ ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
+ {
+- unsigned long psr, ec, lc, rnat, bsp, cfm, nat_bits, val = 0;
++ unsigned long psr, rsc, ec, lc, rnat, bsp, cfm, nat_bits, val = 0;
+ struct unw_frame_info info;
+ struct switch_stack *sw;
+ struct ia64_fpreg fpval;
+@@ -1181,7 +1185,7 @@
+ /* app regs */
+
+ retval |= __get_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]);
+- retval |= __get_user(pt->ar_rsc, &ppr->ar[PT_AUR_RSC]);
++ retval |= __get_user(rsc, &ppr->ar[PT_AUR_RSC]);
+ retval |= __get_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]);
+ retval |= __get_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]);
+ retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
+@@ -1274,6 +1278,7 @@
+ retval |= __get_user(nat_bits, &ppr->nat);
+
+ retval |= access_uarea(child, PT_CR_IPSR, &psr, 1);
++ retval |= access_uarea(child, PT_AR_RSC, &rsc, 1);
+ retval |= access_uarea(child, PT_AR_EC, &ec, 1);
+ retval |= access_uarea(child, PT_AR_LC, &lc, 1);
+ retval |= access_uarea(child, PT_AR_RNAT, &rnat, 1);
+diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
+--- a/arch/ia64/kernel/signal.c
++++ b/arch/ia64/kernel/signal.c
+@@ -94,7 +94,7 @@ sys_sigaltstack (const stack_t __user *u
+ static long
+ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
+ {
+- unsigned long ip, flags, nat, um, cfm;
++ unsigned long ip, flags, nat, um, cfm, rsc;
+ long err;
+
+ /* Always make any pending restarted system calls return -EINTR */
+@@ -106,7 +106,7 @@ restore_sigcontext (struct sigcontext __
+ err |= __get_user(ip, &sc->sc_ip); /* instruction pointer */
+ err |= __get_user(cfm, &sc->sc_cfm);
+ err |= __get_user(um, &sc->sc_um); /* user mask */
+- err |= __get_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
++ err |= __get_user(rsc, &sc->sc_ar_rsc);
+ err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat);
+ err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);
+ err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
+@@ -119,6 +119,7 @@ restore_sigcontext (struct sigcontext __
+ err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8); /* r15 */
+
+ scr->pt.cr_ifs = cfm | (1UL << 63);
++ scr->pt.ar_rsc = rsc | (3 << 2); /* force PL3 */
+
+ /* establish new instruction pointer: */
+ scr->pt.cr_iip = ip & ~0x3UL;
Modified: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-17
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-17 2005-07-29 06:33:25 UTC (rev 3627)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-17 2005-07-29 08:33:26 UTC (rev 3628)
@@ -28,3 +28,5 @@
+ net-netlink-autobind-return.dpatch
+ fs-ext3-64bit-offset.dpatch
+ arch-x86_64-mm-mmap.dpatch
++ arch-ia64-ptrace-getregs-putregs.dpatch
++ arch-ia64-ptrace-restore_sigcontext.dpatch
More information about the Kernel-svn-changes
mailing list