source:
patches/linux-2.6.24.7-security_fixes-1.patch@
9bb8064
Last change on this file since 9bb8064 was c01b0f33, checked in by , 16 years ago | |
---|---|
|
|
File size: 15.5 KB |
-
fs/cifs/asn1.c
Submitted By: Ken Moffat <ken at linuxfromscratch dot org> Date: 2008-06-17 Initial Package Version: 2.6.24.7 Upstream Status: Merged Origin: Debian Description: 2.6.24 is no longer maintained by -stable. These patches from debian (some are straight git pulls from upstream, others are backports) fix the following: CVE-2008-{1615,1673,2136,2137,2148}. fixes CVE-2008-1673 Subject: asn1: additional sanity checking during BER decoding X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=ddb2c43594f22843e9f3153da151deaba1a834c5 asn1: additional sanity checking during BER decoding - Don't trust a length which is greater than the working buffer. An invalid length could cause overflow when calculating buffer size for decoding oid. - An oid length of zero is invalid and allows for an off-by-one error when decoding oid because the first subid actually encodes first 2 subids. - A primitive encoding may not have an indefinite length. Thanks to Wei Wang from McAfee for report. Cc: Steven French <sfrench@us.ibm.com> Cc: stable@kernel.org Acked-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Chris Wright <chrisw@sous-sol.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> --- diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index cb52cbb..f58e41d 100644
a b asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len) 186 186 } 187 187 } 188 188 } 189 190 /* don't trust len bigger than ctx buffer */ 191 if (*len > ctx->end - ctx->pointer) 192 return 0; 193 189 194 return 1; 190 195 } 191 196 … … asn1_header_decode(struct asn1_ctx *ctx, 203 208 if (!asn1_length_decode(ctx, &def, &len)) 204 209 return 0; 205 210 211 /* primitive shall be definite, indefinite shall be constructed */ 212 if (*con == ASN1_PRI && !def) 213 return 0; 214 206 215 if (def) 207 216 *eoc = ctx->pointer + len; 208 217 else … … asn1_oid_decode(struct asn1_ctx *ctx, 389 398 unsigned long *optr; 390 399 391 400 size = eoc - ctx->pointer + 1; 401 402 /* first subid actually encodes first two subids */ 403 if (size < 2 || size > ULONG_MAX/sizeof(unsigned long)) 404 return 0; 405 392 406 *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); 393 407 if (*oid == NULL) 394 408 return 0; -
net/ipv4/netfilter/nf_nat_snmp_basic.c
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 5daefad..7750c97 100644
a b static unsigned char asn1_length_decode(struct asn1_ctx *ctx, 232 232 } 233 233 } 234 234 } 235 236 /* don't trust len bigger than ctx buffer */ 237 if (*len > ctx->end - ctx->pointer) 238 return 0; 239 235 240 return 1; 236 241 } 237 242 … … static unsigned char asn1_header_decode(struct asn1_ctx *ctx, 250 255 if (!asn1_length_decode(ctx, &def, &len)) 251 256 return 0; 252 257 258 /* primitive shall be definite, indefinite shall be constructed */ 259 if (*con == ASN1_PRI && !def) 260 return 0; 261 253 262 if (def) 254 263 *eoc = ctx->pointer + len; 255 264 else … … static unsigned char asn1_oid_decode(struct asn1_ctx *ctx, 434 443 unsigned long *optr; 435 444 436 445 size = eoc - ctx->pointer + 1; 446 447 /* first subid actually encodes first two subids */ 448 if (size < 2 || size > ULONG_MAX/sizeof(unsigned long)) 449 return 0; 450 437 451 *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); 438 452 if (*oid == NULL) { 439 453 if (net_ratelimit()) -
arch/x86/kernel/entry_64.S
fixes local ptrace dos on x86_64, CVE-2008-1615 from debian's 2.6.24, backported by dann frazier diff -urpN linux-source-2.6.24.orig/arch/x86/kernel/entry_64.S linux-source-2.6.24/arch/x86/kernel/entry_64.S
old new paranoid_swapgs\trace: 779 779 swapgs 780 780 paranoid_restore\trace: 781 781 RESTORE_ALL 8 782 iretq782 jmp iret_label 783 783 paranoid_userspace\trace: 784 784 GET_THREAD_INFO(%rcx) 785 785 movl threadinfo_flags(%rcx),%ebx -
linux-source-2.6.24
fix ipv6 over ipv4 remotely triggerable memory leak, CVE-2008-2136 commit 36ca34cc3b8335eb1fe8bd9a1d0a2592980c3f02 Author: David S. Miller <davem@davemloft.net> Date: Thu May 8 23:40:26 2008 -0700 sit: Add missing kfree_skb() on pskb_may_pull() failure. Noticed by Paul Marks <paul@pmarks.net>. Signed-off-by: David S. Miller <davem@davemloft.net> Adjusted to apply to Debian's 2.6.24 by dann frazier <dannf@debian.org> diff -urpN linux-source-2.6.24.orig/net/ipv6/sit.c linux-source-2.6.24/net/ipv6/sit.c
old new static int ipip6_rcv(struct sk_buff *skb 395 395 } 396 396 397 397 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 398 kfree_skb(skb);399 398 read_unlock(&ipip6_lock); 400 399 out: 400 kfree_skb(skb); 401 401 return 0; 402 402 } 403 403 -
arch/sparc/kernel/sys_sparc.c
* [sparc] Validate address ranges regardless of MAP_FIXED (CVE-2008-2137) commit 94d149c34cda933ff5096aca94bb23bf68602f4e Author: David S. Miller <davem@davemloft.net> Date: Mon May 12 16:33:33 2008 -0700 sparc: Fix mremap address range validation. Just like mmap, we need to validate address ranges regardless of MAP_FIXED. sparc{,64}_mmap_check()'s flag argument is unused, remove. Based upon a report and preliminary patch by Jan Lieskovsky <jlieskov@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index e995491..3c6b49a 100644
a b out: 219 219 return err; 220 220 } 221 221 222 int sparc_mmap_check(unsigned long addr, unsigned long len , unsigned long flags)222 int sparc_mmap_check(unsigned long addr, unsigned long len) 223 223 { 224 224 if (ARCH_SUN4C_SUN4 && 225 225 (len > 0x20000000 || … … asmlinkage unsigned long sparc_mremap(unsigned long addr, 295 295 unsigned long old_len, unsigned long new_len, 296 296 unsigned long flags, unsigned long new_addr) 297 297 { 298 struct vm_area_struct *vma;299 298 unsigned long ret = -EINVAL; 300 if (ARCH_SUN4C_SUN4) { 301 if (old_len > 0x20000000 || new_len > 0x20000000) 302 goto out; 303 if (addr < 0xe0000000 && addr + old_len > 0x20000000) 304 goto out; 305 } 306 if (old_len > TASK_SIZE - PAGE_SIZE || 307 new_len > TASK_SIZE - PAGE_SIZE) 299 300 if (unlikely(sparc_mmap_check(addr, old_len))) 301 goto out; 302 if (unlikely(sparc_mmap_check(new_addr, new_len))) 308 303 goto out; 309 304 down_write(¤t->mm->mmap_sem); 310 if (flags & MREMAP_FIXED) {311 if (ARCH_SUN4C_SUN4 &&312 new_addr < 0xe0000000 &&313 new_addr + new_len > 0x20000000)314 goto out_sem;315 if (new_addr + new_len > TASK_SIZE - PAGE_SIZE)316 goto out_sem;317 } else if ((ARCH_SUN4C_SUN4 && addr < 0xe0000000 &&318 addr + new_len > 0x20000000) ||319 addr + new_len > TASK_SIZE - PAGE_SIZE) {320 unsigned long map_flags = 0;321 struct file *file = NULL;322 323 ret = -ENOMEM;324 if (!(flags & MREMAP_MAYMOVE))325 goto out_sem;326 327 vma = find_vma(current->mm, addr);328 if (vma) {329 if (vma->vm_flags & VM_SHARED)330 map_flags |= MAP_SHARED;331 file = vma->vm_file;332 }333 334 new_addr = get_unmapped_area(file, addr, new_len,335 vma ? vma->vm_pgoff : 0,336 map_flags);337 ret = new_addr;338 if (new_addr & ~PAGE_MASK)339 goto out_sem;340 flags |= MREMAP_FIXED;341 }342 305 ret = do_mremap(addr, old_len, new_len, flags, new_addr); 343 out_sem:344 306 up_write(¤t->mm->mmap_sem); 345 307 out: 346 308 return ret; -
arch/sparc64/kernel/sys_sparc.c
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 0dbc941..ac1bff5 100644
a b asmlinkage long sparc64_personality(unsigned long personality) 542 542 return ret; 543 543 } 544 544 545 int sparc64_mmap_check(unsigned long addr, unsigned long len, 546 unsigned long flags) 545 int sparc64_mmap_check(unsigned long addr, unsigned long len) 547 546 { 548 547 if (test_thread_flag(TIF_32BIT)) { 549 548 if (len >= STACK_TOP32) … … asmlinkage unsigned long sys64_mremap(unsigned long addr, 609 608 unsigned long old_len, unsigned long new_len, 610 609 unsigned long flags, unsigned long new_addr) 611 610 { 612 struct vm_area_struct *vma;613 611 unsigned long ret = -EINVAL; 614 612 615 613 if (test_thread_flag(TIF_32BIT)) 616 614 goto out; 617 615 if (unlikely(new_len >= VA_EXCLUDE_START)) 618 616 goto out; 619 if (unlikely(invalid_64bit_range(addr, old_len))) 617 if (unlikely(sparc64_mmap_check(addr, old_len))) 618 goto out; 619 if (unlikely(sparc64_mmap_check(new_addr, new_len))) 620 620 goto out; 621 621 622 622 down_write(¤t->mm->mmap_sem); 623 if (flags & MREMAP_FIXED) {624 if (invalid_64bit_range(new_addr, new_len))625 goto out_sem;626 } else if (invalid_64bit_range(addr, new_len)) {627 unsigned long map_flags = 0;628 struct file *file = NULL;629 630 ret = -ENOMEM;631 if (!(flags & MREMAP_MAYMOVE))632 goto out_sem;633 634 vma = find_vma(current->mm, addr);635 if (vma) {636 if (vma->vm_flags & VM_SHARED)637 map_flags |= MAP_SHARED;638 file = vma->vm_file;639 }640 641 /* MREMAP_FIXED checked above. */642 new_addr = get_unmapped_area(file, addr, new_len,643 vma ? vma->vm_pgoff : 0,644 map_flags);645 ret = new_addr;646 if (new_addr & ~PAGE_MASK)647 goto out_sem;648 flags |= MREMAP_FIXED;649 }650 623 ret = do_mremap(addr, old_len, new_len, flags, new_addr); 651 out_sem:652 624 up_write(¤t->mm->mmap_sem); 653 625 out: 654 626 return ret; -
arch/sparc64/kernel/sys_sparc32.c
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 1aa4288..ba5bd62 100644
a b asmlinkage unsigned long sys32_mremap(unsigned long addr, 867 867 unsigned long old_len, unsigned long new_len, 868 868 unsigned long flags, u32 __new_addr) 869 869 { 870 struct vm_area_struct *vma;871 870 unsigned long ret = -EINVAL; 872 871 unsigned long new_addr = __new_addr; 873 872 874 if ( old_len > STACK_TOP32 || new_len > STACK_TOP32)873 if (unlikely(sparc64_mmap_check(addr, old_len))) 875 874 goto out; 876 if ( addr > STACK_TOP32 - old_len)875 if (unlikely(sparc64_mmap_check(new_addr, new_len))) 877 876 goto out; 878 877 down_write(¤t->mm->mmap_sem); 879 if (flags & MREMAP_FIXED) {880 if (new_addr > STACK_TOP32 - new_len)881 goto out_sem;882 } else if (addr > STACK_TOP32 - new_len) {883 unsigned long map_flags = 0;884 struct file *file = NULL;885 886 ret = -ENOMEM;887 if (!(flags & MREMAP_MAYMOVE))888 goto out_sem;889 890 vma = find_vma(current->mm, addr);891 if (vma) {892 if (vma->vm_flags & VM_SHARED)893 map_flags |= MAP_SHARED;894 file = vma->vm_file;895 }896 897 /* MREMAP_FIXED checked above. */898 new_addr = get_unmapped_area(file, addr, new_len,899 vma ? vma->vm_pgoff : 0,900 map_flags);901 ret = new_addr;902 if (new_addr & ~PAGE_MASK)903 goto out_sem;904 flags |= MREMAP_FIXED;905 }906 878 ret = do_mremap(addr, old_len, new_len, flags, new_addr); 907 out_sem:908 879 up_write(¤t->mm->mmap_sem); 909 880 out: 910 881 return ret; -
include/asm-sparc/mman.h
diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h index e18be98..3d16b40 100644
a b 24 24 25 25 #ifdef __KERNEL__ 26 26 #ifndef __ASSEMBLY__ 27 #define arch_mmap_check sparc_mmap_check 28 int sparc_mmap_check(unsigned long addr, unsigned long len, 29 unsigned long flags); 27 #define arch_mmap_check(addr,len,flags) sparc_mmap_check(addr,len) 28 int sparc_mmap_check(unsigned long addr, unsigned long len); 30 29 #endif 31 30 #endif 32 31 -
include/asm-sparc64/mman.h
diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h index e584563..625be4d 100644
a b 24 24 25 25 #ifdef __KERNEL__ 26 26 #ifndef __ASSEMBLY__ 27 #define arch_mmap_check sparc64_mmap_check 28 int sparc64_mmap_check(unsigned long addr, unsigned long len, 29 unsigned long flags); 27 #define arch_mmap_check(addr,len,flags) sparc64_mmap_check(addr,len) 28 int sparc64_mmap_check(unsigned long addr, unsigned long len); 30 29 #endif 31 30 #endif 32 31 -
arch/sparc/kernel/sys_sparc.c
a second part for this commit 5816339310b2d9623cf413d33e538b45e815da5d Author: David S. Miller <davem@davemloft.net> Date: Wed May 7 02:24:28 2008 -0700 sparc: Fix mmap VA span checking. We should not conditionalize VA range checks on MAP_FIXED. Signed-off-by: David S. Miller <davem@davemloft.net> diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index f188b5d..e995491 100644
a b int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) 223 223 { 224 224 if (ARCH_SUN4C_SUN4 && 225 225 (len > 0x20000000 || 226 ((flags & MAP_FIXED) && 227 addr < 0xe0000000 && addr + len > 0x20000000))) 226 (addr < 0xe0000000 && addr + len > 0x20000000))) 228 227 return -EINVAL; 229 228 230 229 /* See asm-sparc/uaccess.h */ -
arch/sparc64/kernel/sys_sparc.c
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 8d4761f..0dbc941 100644
a b int sparc64_mmap_check(unsigned long addr, unsigned long len, 549 549 if (len >= STACK_TOP32) 550 550 return -EINVAL; 551 551 552 if ( (flags & MAP_FIXED) &&addr > STACK_TOP32 - len)552 if (addr > STACK_TOP32 - len) 553 553 return -EINVAL; 554 554 } else { 555 555 if (len >= VA_EXCLUDE_START) 556 556 return -EINVAL; 557 557 558 if ( (flags & MAP_FIXED) &&invalid_64bit_range(addr, len))558 if (invalid_64bit_range(addr, len)) 559 559 return -EINVAL; 560 560 } 561 561 -
fs/utimes.c
fix CVE-2008-2148 (prevent local users modifying file times without permission) commit 02c6be615f1fcd37ac5ed93a3ad6692ad8991cd9 Author: Miklos Szeredi <mszeredi@suse.cz> Date: Thu May 1 04:34:45 2008 -0700 vfs: fix permission checking in sys_utimensat If utimensat() is called with both times set to UTIME_NOW or one of them to UTIME_NOW and the other to UTIME_OMIT, then it will update the file time without any permission checking. I don't think this can be used for anything other than a local DoS, but could be quite bewildering at that (e.g. "Why was that large source tree rebuilt when I didn't modify anything???") This affects all kernels from 2.6.22, when the utimensat() syscall was introduced. Fix by doing the same permission checking as for the "times == NULL" case. Thanks to Michael Kerrisk, whose utimensat-non-conformances-and-fixes.patch in -mm also fixes this (and breaks other stuff), only he didn't realize the security implications of this bug. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Cc: Ulrich Drepper <drepper@redhat.com> Cc: Michael Kerrisk <mtk-manpages@gmx.net> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> diff --git a/fs/utimes.c b/fs/utimes.c index a2bef77..af059d5 100644
a b asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times) 40 40 41 41 #endif 42 42 43 static bool nsec_special(long nsec) 44 { 45 return nsec == UTIME_OMIT || nsec == UTIME_NOW; 46 } 47 43 48 static bool nsec_valid(long nsec) 44 49 { 45 if (nsec == UTIME_OMIT || nsec == UTIME_NOW)50 if (nsec_special(nsec)) 46 51 return true; 47 52 48 53 return nsec >= 0 && nsec <= 999999999; … … long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags 119 124 newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; 120 125 newattrs.ia_valid |= ATTR_MTIME_SET; 121 126 } 122 } else { 127 } 128 129 /* 130 * If times is NULL or both times are either UTIME_OMIT or 131 * UTIME_NOW, then need to check permissions, because 132 * inode_change_ok() won't do it. 133 */ 134 if (!times || (nsec_special(times[0].tv_nsec) && 135 nsec_special(times[1].tv_nsec))) { 123 136 error = -EACCES; 124 137 if (IS_IMMUTABLE(inode)) 125 138 goto mnt_drop_write_and_out;
Note:
See TracBrowser
for help on using the repository browser.