2007-06-08 07:01:07

by Chris Wright

[permalink] [raw]
Subject: Linux 2.6.20.13

We (the -stable team) are announcing the release of the 2.6.20.13 kernel.
This release has three security fixes in it:

54bb290b: random: fix error in entropy extraction (CVE-2007-2453 1 of 2)
f5939fcd: random: fix seeding with zero entropy (CVE-2007-2453 2 of 2)
6a535788: cpuset: prevent information leak in cpuset_tasks_read (CVE-2007-2875)
13ad357c: NETFILTER: {ip, nf}_conntrack_sctp: fix remotely triggerable NULL ptr dereference (CVE-2007-2876)

The /dev/[u]random fix is especially important for machines with no
entropy source (e.g. keyboard, mice, or disk drives) and no realtime clock
since successive boots could generate same output from RNG. The cpuset
bug is a possible information leak when reading from /dev/cpuset/tasks
(assuming cpusets support is compiled in and the cpuset fs mounted
on /dev/cpuset). The SCTP bug is remotely triggerable when using SCTP
conntrack.

I'll also be replying to this message with a copy of the patch between
2.6.20.12 and 2.6.20.13

The updated 2.6.20.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.20.y.git
and can be browsed at the normal kernel.org git web browser:
http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.20.y.git;a=summary

thanks,
-chris

---------

Makefile | 2
drivers/char/random.c | 67 +++++++++++++++------------
kernel/cpuset.c | 7 --
net/ipv4/netfilter/ip_conntrack_proto_sctp.c | 3 -
net/netfilter/nf_conntrack_proto_sctp.c | 3 -
5 files changed, 44 insertions(+), 38 deletions(-)

Summary of changes from v2.6.20.12 to v2.6.20.13
================================================

Chris Wright (2):
cpuset: prevent information leak in cpuset_tasks_read (CVE-2007-2875)
Linux 2.6.20.13

Matt Mackall (2):
random: fix error in entropy extraction (CVE-2007-2453 1 of 2)
random: fix seeding with zero entropy (CVE-2007-2453 2 of 2)

Patrick McHardy (1):
NETFILTER: {ip, nf}_conntrack_sctp: fix remotely triggerable NULL ptr dereference (CVE-2007-2876)


2007-06-08 07:01:44

by Chris Wright

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

diff --git a/Makefile b/Makefile
index 87f5956..a87a7d1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 20
-EXTRAVERSION = .12
+EXTRAVERSION = .13
NAME = Homicidal Dwarf Hamster

# *DOCUMENTATION*
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 13d0b13..263e5e5 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -760,7 +760,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,

static void extract_buf(struct entropy_store *r, __u8 *out)
{
- int i, x;
+ int i;
__u32 data[16], buf[5 + SHA_WORKSPACE_WORDS];

sha_init(buf);
@@ -772,9 +772,11 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
* attempts to find previous ouputs), unless the hash
* function can be inverted.
*/
- for (i = 0, x = 0; i < r->poolinfo->poolwords; i += 16, x+=2) {
- sha_transform(buf, (__u8 *)r->pool+i, buf + 5);
- add_entropy_words(r, &buf[x % 5], 1);
+ for (i = 0; i < r->poolinfo->poolwords; i += 16) {
+ /* hash blocks of 16 words = 512 bits */
+ sha_transform(buf, (__u8 *)(r->pool + i), buf + 5);
+ /* feed back portion of the resulting hash */
+ add_entropy_words(r, &buf[i % 5], 1);
}

/*
@@ -782,7 +784,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
* portion of the pool while mixing, and hash one
* final time.
*/
- __add_entropy_words(r, &buf[x % 5], 1, data);
+ __add_entropy_words(r, &buf[i % 5], 1, data);
sha_transform(buf, (__u8 *)data, buf + 5);

/*
@@ -1022,37 +1024,44 @@ random_poll(struct file *file, poll_table * wait)
return mask;
}

-static ssize_t
-random_write(struct file * file, const char __user * buffer,
- size_t count, loff_t *ppos)
+static int
+write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
{
- int ret = 0;
size_t bytes;
__u32 buf[16];
const char __user *p = buffer;
- size_t c = count;

- while (c > 0) {
- bytes = min(c, sizeof(buf));
+ while (count > 0) {
+ bytes = min(count, sizeof(buf));
+ if (copy_from_user(&buf, p, bytes))
+ return -EFAULT;

- bytes -= copy_from_user(&buf, p, bytes);
- if (!bytes) {
- ret = -EFAULT;
- break;
- }
- c -= bytes;
+ count -= bytes;
p += bytes;

- add_entropy_words(&input_pool, buf, (bytes + 3) / 4);
- }
- if (p == buffer) {
- return (ssize_t)ret;
- } else {
- struct inode *inode = file->f_path.dentry->d_inode;
- inode->i_mtime = current_fs_time(inode->i_sb);
- mark_inode_dirty(inode);
- return (ssize_t)(p - buffer);
+ add_entropy_words(r, buf, (bytes + 3) / 4);
}
+
+ return 0;
+}
+
+static ssize_t
+random_write(struct file * file, const char __user * buffer,
+ size_t count, loff_t *ppos)
+{
+ size_t ret;
+ struct inode *inode = file->f_path.dentry->d_inode;
+
+ ret = write_pool(&blocking_pool, buffer, count);
+ if (ret)
+ return ret;
+ ret = write_pool(&nonblocking_pool, buffer, count);
+ if (ret)
+ return ret;
+
+ inode->i_mtime = current_fs_time(inode->i_sb);
+ mark_inode_dirty(inode);
+ return (ssize_t)count;
}

static int
@@ -1091,8 +1100,8 @@ random_ioctl(struct inode * inode, struct file * file,
return -EINVAL;
if (get_user(size, p++))
return -EFAULT;
- retval = random_write(file, (const char __user *) p,
- size, &file->f_pos);
+ retval = write_pool(&input_pool, (const char __user *)p,
+ size);
if (retval < 0)
return retval;
credit_entropy_store(&input_pool, ent_count);
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 6b05dc6..5074f7d 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -1751,12 +1751,7 @@ static ssize_t cpuset_tasks_read(struct file *file, char __user *buf,
{
struct ctr_struct *ctr = file->private_data;

- if (*ppos + nbytes > ctr->bufsz)
- nbytes = ctr->bufsz - *ppos;
- if (copy_to_user(buf, ctr->buf + *ppos, nbytes))
- return -EFAULT;
- *ppos += nbytes;
- return nbytes;
+ return simple_read_from_buffer(buf, nbytes, ppos, ctr->buf, ctr->bufsz);
}

static int cpuset_tasks_release(struct inode *unused_inode, struct file *file)
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
index 2443322..ff48378 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
@@ -461,7 +461,8 @@ static int sctp_new(struct ip_conntrack *conntrack,
SCTP_CONNTRACK_NONE, sch->type);

/* Invalid: delete conntrack */
- if (newconntrack == SCTP_CONNTRACK_MAX) {
+ if (newconntrack == SCTP_CONNTRACK_NONE ||
+ newconntrack == SCTP_CONNTRACK_MAX) {
DEBUGP("ip_conntrack_sctp: invalid new deleting.\n");
return 0;
}
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 76e2636..fcc9152 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -470,7 +470,8 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
SCTP_CONNTRACK_NONE, sch->type);

/* Invalid: delete conntrack */
- if (newconntrack == SCTP_CONNTRACK_MAX) {
+ if (newconntrack == SCTP_CONNTRACK_NONE ||
+ newconntrack == SCTP_CONNTRACK_MAX) {
DEBUGP("nf_conntrack_sctp: invalid new deleting.\n");
return 0;
}

2007-06-09 19:00:33

by Matt Mackall

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

On Fri, Jun 08, 2007 at 12:00:28AM -0700, Chris Wright wrote:
> We (the -stable team) are announcing the release of the 2.6.20.13 kernel.
> This release has three security fixes in it:
>
> 54bb290b: random: fix error in entropy extraction (CVE-2007-2453 1 of 2)
> f5939fcd: random: fix seeding with zero entropy (CVE-2007-2453 2 of 2)
>
> The /dev/[u]random fix is especially important for machines with no
> entropy source (e.g. keyboard, mice, or disk drives) and no realtime clock
> since successive boots could generate same output from RNG.

For the record, /dev/random was not impacted. It will fail safe (eg
block forever) on machines with no entropy sources.

--
Mathematics is the supreme nostalgia of our time.