source: patches/linux-2.6.24.7-security_fixes-1.patch@ dc4f9f2

clfs-1.1.0
Last change on this file since dc4f9f2 was 67300de, checked in by Joe Ciccone <jciccone@…>, 16 years ago

Create a clfs-1.1 branch in preperation for a RC.

  • Property mode set to 100644
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)  
    186186                        }
    187187                }
    188188        }
     189
     190        /* don't trust len bigger than ctx buffer */
     191        if (*len > ctx->end - ctx->pointer)
     192                return 0;
     193
    189194        return 1;
    190195}
    191196
    asn1_header_decode(struct asn1_ctx *ctx,  
    203208        if (!asn1_length_decode(ctx, &def, &len))
    204209                return 0;
    205210
     211        /* primitive shall be definite, indefinite shall be constructed */
     212        if (*con == ASN1_PRI && !def)
     213                return 0;
     214
    206215        if (def)
    207216                *eoc = ctx->pointer + len;
    208217        else
    asn1_oid_decode(struct asn1_ctx *ctx,  
    389398        unsigned long *optr;
    390399
    391400        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
    392406        *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
    393407        if (*oid == NULL)
    394408                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,  
    232232                        }
    233233                }
    234234        }
     235
     236        /* don't trust len bigger than ctx buffer */
     237        if (*len > ctx->end - ctx->pointer)
     238                return 0;
     239
    235240        return 1;
    236241}
    237242
    static unsigned char asn1_header_decode(struct asn1_ctx *ctx,  
    250255        if (!asn1_length_decode(ctx, &def, &len))
    251256                return 0;
    252257
     258        /* primitive shall be definite, indefinite shall be constructed */
     259        if (*con == ASN1_PRI && !def)
     260                return 0;
     261
    253262        if (def)
    254263                *eoc = ctx->pointer + len;
    255264        else
    static unsigned char asn1_oid_decode(struct asn1_ctx *ctx,  
    434443        unsigned long *optr;
    435444
    436445        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
    437451        *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
    438452        if (*oid == NULL) {
    439453                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:  
    779779        swapgs
    780780paranoid_restore\trace:
    781781        RESTORE_ALL 8
    782         iretq
     782        jmp iret_label
    783783paranoid_userspace\trace:
    784784        GET_THREAD_INFO(%rcx)
    785785        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  
    395395        }
    396396
    397397        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
    398         kfree_skb(skb);
    399398        read_unlock(&ipip6_lock);
    400399out:
     400        kfree_skb(skb);
    401401        return 0;
    402402}
    403403
  • 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:  
    219219        return err;
    220220}
    221221
    222 int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
     222int sparc_mmap_check(unsigned long addr, unsigned long len)
    223223{
    224224        if (ARCH_SUN4C_SUN4 &&
    225225            (len > 0x20000000 ||
    asmlinkage unsigned long sparc_mremap(unsigned long addr,  
    295295        unsigned long old_len, unsigned long new_len,
    296296        unsigned long flags, unsigned long new_addr)
    297297{
    298         struct vm_area_struct *vma;
    299298        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)))
    308303                goto out;
    309304        down_write(&current->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         }
    342305        ret = do_mremap(addr, old_len, new_len, flags, new_addr);
    343 out_sem:
    344306        up_write(&current->mm->mmap_sem);
    345307out:
    346308        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)  
    542542        return ret;
    543543}
    544544
    545 int sparc64_mmap_check(unsigned long addr, unsigned long len,
    546                 unsigned long flags)
     545int sparc64_mmap_check(unsigned long addr, unsigned long len)
    547546{
    548547        if (test_thread_flag(TIF_32BIT)) {
    549548                if (len >= STACK_TOP32)
    asmlinkage unsigned long sys64_mremap(unsigned long addr,  
    609608        unsigned long old_len, unsigned long new_len,
    610609        unsigned long flags, unsigned long new_addr)
    611610{
    612         struct vm_area_struct *vma;
    613611        unsigned long ret = -EINVAL;
    614612
    615613        if (test_thread_flag(TIF_32BIT))
    616614                goto out;
    617615        if (unlikely(new_len >= VA_EXCLUDE_START))
    618616                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)))
    620620                goto out;
    621621
    622622        down_write(&current->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         }
    650623        ret = do_mremap(addr, old_len, new_len, flags, new_addr);
    651 out_sem:
    652624        up_write(&current->mm->mmap_sem);
    653625out:
    654626        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,  
    867867        unsigned long old_len, unsigned long new_len,
    868868        unsigned long flags, u32 __new_addr)
    869869{
    870         struct vm_area_struct *vma;
    871870        unsigned long ret = -EINVAL;
    872871        unsigned long new_addr = __new_addr;
    873872
    874         if (old_len > STACK_TOP32 || new_len > STACK_TOP32)
     873        if (unlikely(sparc64_mmap_check(addr, old_len)))
    875874                goto out;
    876         if (addr > STACK_TOP32 - old_len)
     875        if (unlikely(sparc64_mmap_check(new_addr, new_len)))
    877876                goto out;
    878877        down_write(&current->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         }
    906878        ret = do_mremap(addr, old_len, new_len, flags, new_addr);
    907 out_sem:
    908879        up_write(&current->mm->mmap_sem);
    909880out:
    910881        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  
    2424
    2525#ifdef __KERNEL__
    2626#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)
     28int sparc_mmap_check(unsigned long addr, unsigned long len);
    3029#endif
    3130#endif
    3231
  • 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  
    2424
    2525#ifdef __KERNEL__
    2626#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)
     28int sparc64_mmap_check(unsigned long addr, unsigned long len);
    3029#endif
    3130#endif
    3231
  • 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)  
    223223{
    224224        if (ARCH_SUN4C_SUN4 &&
    225225            (len > 0x20000000 ||
    226              ((flags & MAP_FIXED) &&
    227               addr < 0xe0000000 && addr + len > 0x20000000)))
     226             (addr < 0xe0000000 && addr + len > 0x20000000)))
    228227                return -EINVAL;
    229228
    230229        /* 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,  
    549549                if (len >= STACK_TOP32)
    550550                        return -EINVAL;
    551551
    552                 if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len)
     552                if (addr > STACK_TOP32 - len)
    553553                        return -EINVAL;
    554554        } else {
    555555                if (len >= VA_EXCLUDE_START)
    556556                        return -EINVAL;
    557557
    558                 if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len))
     558                if (invalid_64bit_range(addr, len))
    559559                        return -EINVAL;
    560560        }
    561561
  • 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)  
    4040
    4141#endif
    4242
     43static bool nsec_special(long nsec)
     44{
     45        return nsec == UTIME_OMIT || nsec == UTIME_NOW;
     46}
     47
    4348static bool nsec_valid(long nsec)
    4449{
    45         if (nsec == UTIME_OMIT || nsec == UTIME_NOW)
     50        if (nsec_special(nsec))
    4651                return true;
    4752
    4853        return nsec >= 0 && nsec <= 999999999;
    long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags  
    119124                        newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
    120125                        newattrs.ia_valid |= ATTR_MTIME_SET;
    121126                }
    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))) {
    123136                error = -EACCES;
    124137                if (IS_IMMUTABLE(inode))
    125138                        goto mnt_drop_write_and_out;
Note: See TracBrowser for help on using the repository browser.