]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
[PATCH] Add security patches for isofs, ext2 leak, load_elf_library, and bluetooth
authorchrisw@osdl.org <chrisw@osdl.org>
Sat, 26 Mar 2005 01:33:51 +0000 (17:33 -0800)
committerGreg KH <gregkh@suse.de>
Thu, 12 May 2005 05:15:42 +0000 (22:15 -0700)
queue/00-iso9660-handling-flaws.patch [new file with mode: 0644]
queue/01-iso9660-handling-flaws.patch [new file with mode: 0644]
queue/02-iso9660-handling-flaws.patch [new file with mode: 0644]
queue/af_bluetooth-bounds-check.patch [new file with mode: 0644]
queue/ext2-info-leak.patch [new file with mode: 0644]
queue/load_elf_library-kfree-fix.patch [new file with mode: 0644]

diff --git a/queue/00-iso9660-handling-flaws.patch b/queue/00-iso9660-handling-flaws.patch
new file mode 100644 (file)
index 0000000..243ec0b
--- /dev/null
@@ -0,0 +1,105 @@
+From security-bounces@linux.kernel.org  Tue Mar 15 16:25:33 2005
+From: Linus Torvalds <torvalds@osdl.org>
+Subject: [PATCH] isofs: Handle corupted rock-ridge info slightly better
+
+Michal Zalewski <lcamtuf@dione.ids.pl> discovers range checking flaws in
+iso9660 filesystem.
+
+http://marc.theaimsgroup.com/?l=bugtraq&m=111110067304783&w=2
+
+CAN-2005-0815 is assigned to this issue.
+
+From: Linus Torvalds <torvalds@osdl.org>
+
+isofs: Handle corupted rock-ridge info slightly better.
+
+Keyword here being 'slightly'. The code is a mess.
+
+Signed-off-by: Chris Wright <chrisw@osdl.org>
+
+diff -Nru a/fs/isofs/rock.c b/fs/isofs/rock.c
+--- a/fs/isofs/rock.c  2005-03-25 15:25:50 -08:00
++++ b/fs/isofs/rock.c  2005-03-25 15:25:50 -08:00
+@@ -53,6 +53,7 @@
+   if(LEN & 1) LEN++;                                          \
+   CHR = ((unsigned char *) DE) + LEN;                         \
+   LEN = *((unsigned char *) DE) - LEN;                          \
++  if (LEN<0) LEN=0;                                             \
+   if (ISOFS_SB(inode->i_sb)->s_rock_offset!=-1)                \
+   {                                                             \
+      LEN-=ISOFS_SB(inode->i_sb)->s_rock_offset;                \
+@@ -103,12 +104,13 @@
+     struct rock_ridge * rr;
+     int sig;
+     
+-    while (len > 1){ /* There may be one byte for padding somewhere */
++    while (len > 2){ /* There may be one byte for padding somewhere */
+       rr = (struct rock_ridge *) chr;
+-      if (rr->len == 0) goto out; /* Something got screwed up here */
++      if (rr->len < 3) goto out; /* Something got screwed up here */
+       sig = isonum_721(chr);
+       chr += rr->len; 
+       len -= rr->len;
++      if (len < 0) goto out;  /* corrupted isofs */
+       switch(sig){
+       case SIG('R','R'):
+@@ -122,6 +124,7 @@
+       break;
+       case SIG('N','M'):
+       if (truncate) break;
++      if (rr->len < 5) break;
+         /*
+        * If the flags are 2 or 4, this indicates '.' or '..'.
+        * We don't want to do anything with this, because it
+@@ -186,12 +189,13 @@
+     struct rock_ridge * rr;
+     int rootflag;
+     
+-    while (len > 1){ /* There may be one byte for padding somewhere */
++    while (len > 2){ /* There may be one byte for padding somewhere */
+       rr = (struct rock_ridge *) chr;
+-      if (rr->len == 0) goto out; /* Something got screwed up here */
++      if (rr->len < 3) goto out; /* Something got screwed up here */
+       sig = isonum_721(chr);
+       chr += rr->len; 
+       len -= rr->len;
++      if (len < 0) goto out;  /* corrupted isofs */
+       
+       switch(sig){
+ #ifndef CONFIG_ZISOFS         /* No flag for SF or ZF */
+@@ -462,7 +466,7 @@
+       struct rock_ridge *rr;
+       if (!ISOFS_SB(inode->i_sb)->s_rock)
+-              panic ("Cannot have symlink with high sierra variant of iso filesystem\n");
++              goto error;
+       block = ei->i_iget5_block;
+       lock_kernel();
+@@ -487,13 +491,15 @@
+       SETUP_ROCK_RIDGE(raw_inode, chr, len);
+       repeat:
+-      while (len > 1) { /* There may be one byte for padding somewhere */
++      while (len > 2) { /* There may be one byte for padding somewhere */
+               rr = (struct rock_ridge *) chr;
+-              if (rr->len == 0)
++              if (rr->len < 3)
+                       goto out;       /* Something got screwed up here */
+               sig = isonum_721(chr);
+               chr += rr->len;
+               len -= rr->len;
++              if (len < 0)
++                      goto out;       /* corrupted isofs */
+               switch (sig) {
+               case SIG('R', 'R'):
+@@ -543,6 +549,7 @@
+       fail:
+       brelse(bh);
+       unlock_kernel();
++      error:
+       SetPageError(page);
+       kunmap(page);
+       unlock_page(page);
diff --git a/queue/01-iso9660-handling-flaws.patch b/queue/01-iso9660-handling-flaws.patch
new file mode 100644 (file)
index 0000000..98f6d33
--- /dev/null
@@ -0,0 +1,41 @@
+From security-bounces@linux.kernel.org  Tue Mar 15 16:25:33 2005
+From: Linus Torvalds <torvalds@osdl.org>
+Subject: [PATCH] isofs: more "corrupted iso image" error cases
+
+Michal Zalewski <lcamtuf@dione.ids.pl> discovers range checking flaws in
+iso9660 filesystem.
+
+http://marc.theaimsgroup.com/?l=bugtraq&m=111110067304783&w=2
+
+CAN-2005-0815 is assigned to this issue.
+
+From: Linus Torvalds <torvalds@osdl.org>
+
+isofs: more "corrupted iso image" error cases
+
+Thanks to Michal Zalewski for testing.
+
+Signed-off-by: Chris Wright <chrisw@osdl.org>
+
+diff -Nru a/fs/isofs/inode.c b/fs/isofs/inode.c
+--- a/fs/isofs/inode.c 2005-03-25 15:26:02 -08:00
++++ b/fs/isofs/inode.c 2005-03-25 15:26:02 -08:00
+@@ -685,6 +685,8 @@
+         sbi->s_log_zone_size = isonum_723 (h_pri->logical_block_size);
+         sbi->s_max_size = isonum_733(h_pri->volume_space_size);
+       } else {
++        if (!pri)
++          goto out_freebh;
+         rootp = (struct iso_directory_record *) pri->root_directory_record;
+         sbi->s_nzones = isonum_733 (pri->volume_space_size);
+         sbi->s_log_zone_size = isonum_723 (pri->logical_block_size);
+@@ -1394,6 +1396,9 @@
+       unsigned long hashval;
+       struct inode *inode;
+       struct isofs_iget5_callback_data data;
++
++      if (offset >= 1ul << sb->s_blocksize_bits)
++              return NULL;
+       data.block = block;
+       data.offset = offset;
diff --git a/queue/02-iso9660-handling-flaws.patch b/queue/02-iso9660-handling-flaws.patch
new file mode 100644 (file)
index 0000000..459a466
--- /dev/null
@@ -0,0 +1,30 @@
+From security-bounces@linux.kernel.org  Tue Mar 15 16:25:33 2005
+From: Chris Wright <chrisw@osdl.org>
+Subject: [PATCH] isofs: more defensive checks against corrupt isofs images
+
+Michal Zalewski <lcamtuf@dione.ids.pl> discovers range checking flaws in
+iso9660 filesystem.
+
+http://marc.theaimsgroup.com/?l=bugtraq&m=111110067304783&w=2
+
+CAN-2005-0815 is assigned to this issue.
+
+Some more defensive checks to keep corrupt isofs images from corrupting
+memory or causing Oops.
+
+Signed-off-by: Chris Wright <chrisw@osdl.org>
+
+===== fs/isofs/rock.c 1.23 vs edited =====
+--- 1.23/fs/isofs/rock.c       2005-03-16 16:12:52 -08:00
++++ edited/fs/isofs/rock.c     2005-03-24 00:41:31 -08:00
+@@ -74,6 +74,10 @@
+     offset1 = 0; \
+     pbh = sb_bread(DEV->i_sb, block); \
+     if(pbh){       \
++      if (offset > pbh->b_size || offset + cont_size > pbh->b_size){  \
++      brelse(pbh); \
++      goto out; \
++      } \
+       memcpy(buffer + offset1, pbh->b_data + offset, cont_size - offset1); \
+       brelse(pbh); \
+       chr = (unsigned char *) buffer; \
diff --git a/queue/af_bluetooth-bounds-check.patch b/queue/af_bluetooth-bounds-check.patch
new file mode 100644 (file)
index 0000000..872c77d
--- /dev/null
@@ -0,0 +1,49 @@
+From foo@baz.org  Fri Mar 25 03:24:48 2005
+From: Marcus Meissner <meissner@suse.de>
+To: security@kernel.org
+Subject: [PATCH][Bluetooth] Fix signedness problem at socket creation
+
+From: Marcel Holtmann <marcel@holtmann.org>
+
+CAN-2005-0750 is assigned to this issue
+
+ilja <ilja@suresec.org> discovered potential local root exploit in
+bluetooth socket creation.
+
+This patch fixes a small signedness problem when creating the
+socket.
+
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Chris Wright <chrisw@osdl.org>
+
+diff -Nru a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
+--- a/net/bluetooth/af_bluetooth.c     2005-03-25 00:39:07 +01:00
++++ b/net/bluetooth/af_bluetooth.c     2005-03-25 00:39:07 +01:00
+@@ -62,7 +62,7 @@
+ int bt_sock_register(int proto, struct net_proto_family *ops)
+ {
+-      if (proto >= BT_MAX_PROTO)
++      if (proto < 0 || proto >= BT_MAX_PROTO)
+               return -EINVAL;
+       if (bt_proto[proto])
+@@ -75,7 +75,7 @@
+ int bt_sock_unregister(int proto)
+ {
+-      if (proto >= BT_MAX_PROTO)
++      if (proto < 0 || proto >= BT_MAX_PROTO)
+               return -EINVAL;
+       if (!bt_proto[proto])
+@@ -90,7 +90,7 @@
+ {
+       int err = 0;
+-      if (proto >= BT_MAX_PROTO)
++      if (proto < 0 || proto >= BT_MAX_PROTO)
+               return -EINVAL;
+ #if defined(CONFIG_KMOD)
+
diff --git a/queue/ext2-info-leak.patch b/queue/ext2-info-leak.patch
new file mode 100644 (file)
index 0000000..92ff620
--- /dev/null
@@ -0,0 +1,34 @@
+From security-bounces@linux.kernel.org  Wed Mar 16 09:53:38 2005
+Date: Wed, 16 Mar 2005 18:49:43 +0100
+From: "Mathieu Lafon" <mlafon@arkoon.net>
+To: security@kernel.org
+Cc: rfrancoise@arkoon.net
+Subject: [PATCH] Suspected information leak (mem pages) in ext2
+
+From: "Mathieu Lafon" <mlafon@arkoon.net>
+
+I think I have discovered a potential security problem in ext2: when a
+new directory is created, the ext2 block written to disk is not 
+initialized.
+
+Included is a proposed patch for Linux 2.6 (ext2_make_empty() function):
+
+CAN-2005-0400 is assigned to this issue.
+
+Signed-off-by: Chris Wright <chrisw@osdl.org>
+
+diff -rN -U 5 linux-2.6.10/fs/ext2/dir.c linux-2.6.10-ext2-info-leak-fix/fs/ext2/dir.c
+--- linux-2.6.10/fs/ext2/dir.c  Wed Mar 16 18:16:51 2005
++++ linux-2.6.10-ext2-info-leak-fix/fs/ext2/dir.c       Wed Mar 16 18:17:01 2005
+@@ -590,10 +590,11 @@
+       if (err) {
+               unlock_page(page);
+               goto fail;
+       }
+       kaddr = kmap_atomic(page, KM_USER0);
++       memset(kaddr, 0, chunk_size);
+       de = (struct ext2_dir_entry_2 *)kaddr;
+       de->name_len = 1;
+       de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
+       memcpy (de->name, ".\0\0", 4);
+       de->inode = cpu_to_le32(inode->i_ino);
diff --git a/queue/load_elf_library-kfree-fix.patch b/queue/load_elf_library-kfree-fix.patch
new file mode 100644 (file)
index 0000000..25ad89e
--- /dev/null
@@ -0,0 +1,94 @@
+From linux-kernel@vger.kernel.org Fri Mar 18 01:13:26 2005
+Date: Fri, 18 Mar 2005 01:05:01 -0800
+From: Andrew Morton <akpm@osdl.org>
+To: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: yxie@cs.stanford.edu, linux-kernel@vger.kernel.org
+Subject: [PATCH] Potential DOS in load_elf_library
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+Yichen Xie <yxie@cs.stanford.edu> points out that load_elf_library can
+modify `elf_phdata' before freeing it.
+
+CAN-2005-0749 is assigned to this issue.
+
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Chris Wright <chrisw@osdl.org>
+---
+
+ 25-akpm/fs/binfmt_elf.c |   30 +++++++++++++++++-------------
+ 1 files changed, 17 insertions(+), 13 deletions(-)
+
+diff -puN fs/binfmt_elf.c~load_elf_library-kfree-fix fs/binfmt_elf.c
+--- 25/fs/binfmt_elf.c~load_elf_library-kfree-fix      2005-03-20 16:56:41.000000000 -0800
++++ 25-akpm/fs/binfmt_elf.c    2005-03-20 16:56:41.000000000 -0800
+@@ -1026,6 +1026,7 @@ out_free_ph:
+ static int load_elf_library(struct file *file)
+ {
+       struct elf_phdr *elf_phdata;
++      struct elf_phdr *eppnt;
+       unsigned long elf_bss, bss, len;
+       int retval, error, i, j;
+       struct elfhdr elf_ex;
+@@ -1049,44 +1050,47 @@ static int load_elf_library(struct file 
+       /* j < ELF_MIN_ALIGN because elf_ex.e_phnum <= 2 */
+       error = -ENOMEM;
+-      elf_phdata = (struct elf_phdr *) kmalloc(j, GFP_KERNEL);
++      elf_phdata = kmalloc(j, GFP_KERNEL);
+       if (!elf_phdata)
+               goto out;
++      eppnt = elf_phdata;
+       error = -ENOEXEC;
+-      retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata, j);
++      retval = kernel_read(file, elf_ex.e_phoff, (char *)eppnt, j);
+       if (retval != j)
+               goto out_free_ph;
+       for (j = 0, i = 0; i<elf_ex.e_phnum; i++)
+-              if ((elf_phdata + i)->p_type == PT_LOAD) j++;
++              if ((eppnt + i)->p_type == PT_LOAD)
++                      j++;
+       if (j != 1)
+               goto out_free_ph;
+-      while (elf_phdata->p_type != PT_LOAD) elf_phdata++;
++      while (eppnt->p_type != PT_LOAD)
++              eppnt++;
+       /* Now use mmap to map the library into memory. */
+       down_write(&current->mm->mmap_sem);
+       error = do_mmap(file,
+-                      ELF_PAGESTART(elf_phdata->p_vaddr),
+-                      (elf_phdata->p_filesz +
+-                       ELF_PAGEOFFSET(elf_phdata->p_vaddr)),
++                      ELF_PAGESTART(eppnt->p_vaddr),
++                      (eppnt->p_filesz +
++                       ELF_PAGEOFFSET(eppnt->p_vaddr)),
+                       PROT_READ | PROT_WRITE | PROT_EXEC,
+                       MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
+-                      (elf_phdata->p_offset -
+-                       ELF_PAGEOFFSET(elf_phdata->p_vaddr)));
++                      (eppnt->p_offset -
++                       ELF_PAGEOFFSET(eppnt->p_vaddr)));
+       up_write(&current->mm->mmap_sem);
+-      if (error != ELF_PAGESTART(elf_phdata->p_vaddr))
++      if (error != ELF_PAGESTART(eppnt->p_vaddr))
+               goto out_free_ph;
+-      elf_bss = elf_phdata->p_vaddr + elf_phdata->p_filesz;
++      elf_bss = eppnt->p_vaddr + eppnt->p_filesz;
+       if (padzero(elf_bss)) {
+               error = -EFAULT;
+               goto out_free_ph;
+       }
+-      len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_MIN_ALIGN - 1);
+-      bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
++      len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + ELF_MIN_ALIGN - 1);
++      bss = eppnt->p_memsz + eppnt->p_vaddr;
+       if (bss > len) {
+               down_write(&current->mm->mmap_sem);
+               do_brk(len, bss - len);
+_