2005-03-26 03:39:44

by Chris Wright

[permalink] [raw]
Subject: Linux 2.6.11.6

With some pending security fixes it's time to for a -stable update. So,
here's 2.6.11.6, in the normal kernel.org places. This includes some
security fixes, esp. one which closes a local root exploit in bluetooth.

The diffstat and short summary of the fixes are below.

I'll also be replying to this message with a copy of the patch between
2.6.11.5 and 2.6.11.6, as it is small enough to do so.


thanks,
-chris
--

Makefile | 2 +-
fs/binfmt_elf.c | 30 +++++++++++++++++-------------
fs/ext2/dir.c | 1 +
fs/isofs/inode.c | 5 +++++
fs/isofs/rock.c | 25 ++++++++++++++++++-------
net/bluetooth/af_bluetooth.c | 6 +++---
6 files changed, 45 insertions(+), 24 deletions(-)

Summary of changes from v2.6.11.5 to v2.6.11.6
==============================================

Chris Wright:
o isofs: more defensive checks against corrupt isofs images
o Linux 2.6.11.6

Herbert Xu:
o Potential DOS in load_elf_library

Linus Torvalds:
o isofs: Handle corupted rock-ridge info slightly better
o isofs: more "corrupted iso image" error cases

Marcel Holtmann:
o Fix signedness problem at socket creation

Mathieu Lafon:
o Suspected information leak (mem pages) in ext2


2005-03-26 03:42:30

by Chris Wright

[permalink] [raw]
Subject: Re: Linux 2.6.11.6

diff -Nru a/Makefile b/Makefile
--- a/Makefile 2005-03-25 18:26:00 -08:00
+++ b/Makefile 2005-03-25 18:26:00 -08:00
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 11
-EXTRAVERSION = .5
+EXTRAVERSION = .6
NAME=Woozy Numbat

# *DOCUMENTATION*
diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c
--- a/fs/binfmt_elf.c 2005-03-25 18:26:00 -08:00
+++ b/fs/binfmt_elf.c 2005-03-25 18:26:00 -08:00
@@ -1008,6 +1008,7 @@
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;
@@ -1031,44 +1032,47 @@
/* 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);
diff -Nru a/fs/ext2/dir.c b/fs/ext2/dir.c
--- a/fs/ext2/dir.c 2005-03-25 18:26:00 -08:00
+++ b/fs/ext2/dir.c 2005-03-25 18:26:00 -08:00
@@ -592,6 +592,7 @@
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));
diff -Nru a/fs/isofs/inode.c b/fs/isofs/inode.c
--- a/fs/isofs/inode.c 2005-03-25 18:26:00 -08:00
+++ b/fs/isofs/inode.c 2005-03-25 18:26:00 -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 -Nru a/fs/isofs/rock.c b/fs/isofs/rock.c
--- a/fs/isofs/rock.c 2005-03-25 18:26:00 -08:00
+++ b/fs/isofs/rock.c 2005-03-25 18:26:00 -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; \
@@ -73,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; \
@@ -103,12 +108,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 +128,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 +193,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 +470,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 +495,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 +553,7 @@
fail:
brelse(bh);
unlock_kernel();
+ error:
SetPageError(page);
kunmap(page);
unlock_page(page);
diff -Nru a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
--- a/net/bluetooth/af_bluetooth.c 2005-03-25 18:26:00 -08:00
+++ b/net/bluetooth/af_bluetooth.c 2005-03-25 18:26:00 -08:00
@@ -64,7 +64,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])
@@ -77,7 +77,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])
@@ -92,7 +92,7 @@
{
int err = 0;

- if (proto >= BT_MAX_PROTO)
+ if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL;

#if defined(CONFIG_KMOD)

2005-03-26 03:47:43

by Hua Zhong (hzhong)

[permalink] [raw]
Subject: RE: Linux 2.6.11.6

> int bt_sock_unregister(int proto)
> {
> - if (proto >= BT_MAX_PROTO)
> + if (proto < 0 || proto >= BT_MAX_PROTO)
> return -EINVAL;

Just curious: would it be better to say

if ((unsigned int)proto >= BT_MAX_PTORO)

?

Is it faster too?

Hua

2005-03-26 03:56:54

by Kyle Moffett

[permalink] [raw]
Subject: Re: Linux 2.6.11.6

On Mar 25, 2005, at 22:47, Hua Zhong wrote:
>> int bt_sock_unregister(int proto)
>> {
>> - if (proto >= BT_MAX_PROTO)
>> + if (proto < 0 || proto >= BT_MAX_PROTO)
>> return -EINVAL;
>
> Just curious: would it be better to say
>
> if ((unsigned int)proto >= BT_MAX_PTORO)

Erm, it _would_ work, but it's _much_ less clear, less typesafe,
and besides, GCC can probably optimize that test anyways.

Cheers,
Kyle Moffett

-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCM/CS/IT/U d- s++: a18 C++++>$ UB/L/X/*++++(+)>$ P+++(++++)>$
L++++(+++) E W++(+) N+++(++) o? K? w--- O? M++ V? PS+() PE+(-) Y+
PGP+++ t+(+++) 5 X R? tv-(--) b++++(++) DI+ D+ G e->++++$ h!*()>++$ r
!y?(-)
------END GEEK CODE BLOCK------


2005-03-26 04:01:41

by Chris Wright

[permalink] [raw]
Subject: Re: Linux 2.6.11.6

* Hua Zhong ([email protected]) wrote:
> > int bt_sock_unregister(int proto)
> > {
> > - if (proto >= BT_MAX_PROTO)
> > + if (proto < 0 || proto >= BT_MAX_PROTO)
> > return -EINVAL;
>
> Just curious: would it be better to say
>
> if ((unsigned int)proto >= BT_MAX_PTORO)

the first check makes it painfully obvious what it's checking. i think
it's a wash (-O2 seems to collapse to the same check), with a win for
readability.

thanks,
-chris
--
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net

2005-03-26 08:50:59

by Moritz Muehlenhoff

[permalink] [raw]
Subject: Re: Linux 2.6.11.6

Hi,

In gmane.linux.kernel, you wrote:
> With some pending security fixes it's time to for a -stable update. So,
> here's 2.6.11.6, in the normal kernel.org places. This includes some
> security fixes, esp. one which closes a local root exploit in bluetooth.

Could you please add CAN IDs to the stable changelog for already assigned
vulnerabilities?

Cheers,
Moritz

2005-03-26 09:28:07

by Chris Wright

[permalink] [raw]
Subject: Re: Linux 2.6.11.6

* Moritz Muehlenhoff ([email protected]) wrote:
> In gmane.linux.kernel, you wrote:
> > With some pending security fixes it's time to for a -stable update. So,
> > here's 2.6.11.6, in the normal kernel.org places. This includes some
> > security fixes, esp. one which closes a local root exploit in bluetooth.
>
> Could you please add CAN IDs to the stable changelog for already assigned
> vulnerabilities?

That's what I did for .5 -> .6. We can't retroactively update changeset
comments, and I'm not sure we have any other candidates in -stable.
We'll certainly continue to add them as we have them.

thanks,
-chris

2005-03-27 18:53:29

by Ryan Anderson

[permalink] [raw]
Subject: Re: Linux 2.6.11.6

On Sat, Mar 26, 2005 at 01:27:53AM -0800, Chris Wright wrote:
> > Could you please add CAN IDs to the stable changelog for already assigned
> > vulnerabilities?
>
> That's what I did for .5 -> .6. We can't retroactively update changeset
> comments, and I'm not sure we have any other candidates in -stable.
> We'll certainly continue to add them as we have them.

bk helptool comments

You can, actually.


--

Ryan Anderson
sometimes Pug Majere

2005-03-27 18:59:11

by Dave Jones

[permalink] [raw]
Subject: Re: Linux 2.6.11.6

On Sun, Mar 27, 2005 at 01:52:59PM -0500, Ryan Anderson wrote:
> On Sat, Mar 26, 2005 at 01:27:53AM -0800, Chris Wright wrote:
> > > Could you please add CAN IDs to the stable changelog for already assigned
> > > vulnerabilities?
> >
> > That's what I did for .5 -> .6. We can't retroactively update changeset
> > comments, and I'm not sure we have any other candidates in -stable.
> > We'll certainly continue to add them as we have them.
>
> bk helptool comments
>
> You can, actually.

"Nota bene: if the deltas being commented have been committed to a
changeset and have been pulled out of this repository, the comment
changes will not propagate on the next bk pull. It is strongly sug-
gested that you use this only on uncommitted deltas which have not
been pulled or cloned. In the future, we will add a way of enforcing this."

That would suggest otherwise.

Dave

2005-03-27 20:00:11

by Chris Wright

[permalink] [raw]
Subject: Re: Linux 2.6.11.6

* Ryan Anderson ([email protected]) wrote:
> On Sat, Mar 26, 2005 at 01:27:53AM -0800, Chris Wright wrote:
> > > Could you please add CAN IDs to the stable changelog for already assigned
> > > vulnerabilities?
> >
> > That's what I did for .5 -> .6. We can't retroactively update changeset
> > comments, and I'm not sure we have any other candidates in -stable.
> > We'll certainly continue to add them as we have them.
>
> bk helptool comments

Yeah, I've actually used that, but as Dave mentioned, it's only really
useful while you have the changes locally and haven't pushed them out yet.

thanks,
-chris