diff options
author | Alexandre Oliva <lxoliva@fsfla.org> | 2011-11-17 05:58:12 +0000 |
---|---|---|
committer | Alexandre Oliva <lxoliva@fsfla.org> | 2011-11-17 05:58:12 +0000 |
commit | 55cd14c5ed37953dc24afaf73ac03a8f53ccc88c (patch) | |
tree | 2bfa9a7feff6cfa04317e0db443b8e72846c2a3d | |
parent | e9a14c7ca60952b243ac0c4066e31afdd1c223f9 (diff) | |
download | linux-libre-raptor-55cd14c5ed37953dc24afaf73ac03a8f53ccc88c.tar.gz linux-libre-raptor-55cd14c5ed37953dc24afaf73ac03a8f53ccc88c.zip |
2.6.41.1-2.fc15
4 files changed, 241 insertions, 3 deletions
diff --git a/freed-ora/current/f15/.gitignore b/freed-ora/current/f15/.gitignore index 2cd2f944c..d7b2f036b 100644 --- a/freed-ora/current/f15/.gitignore +++ b/freed-ora/current/f15/.gitignore @@ -3,4 +3,5 @@ linux-*.tar.bz2 patch-*.bz2 clog *.rpm +*.orig kernel-[23].*/ diff --git a/freed-ora/current/f15/jbd-jbd2-validate-sb-s_first-in-journal_get_superblo.patch b/freed-ora/current/f15/jbd-jbd2-validate-sb-s_first-in-journal_get_superblo.patch new file mode 100644 index 000000000..f5d82914f --- /dev/null +++ b/freed-ora/current/f15/jbd-jbd2-validate-sb-s_first-in-journal_get_superblo.patch @@ -0,0 +1,95 @@ +From 8762202dd0d6e46854f786bdb6fb3780a1625efe Mon Sep 17 00:00:00 2001 +From: Eryu Guan <guaneryu@gmail.com> +Date: Tue, 1 Nov 2011 19:04:59 -0400 +Subject: [PATCH] jbd/jbd2: validate sb->s_first in journal_get_superblock() + +I hit a J_ASSERT(blocknr != 0) failure in cleanup_journal_tail() when +mounting a fsfuzzed ext3 image. It turns out that the corrupted ext3 +image has s_first = 0 in journal superblock, and the 0 is passed to +journal->j_head in journal_reset(), then to blocknr in +cleanup_journal_tail(), in the end the J_ASSERT failed. + +So validate s_first after reading journal superblock from disk in +journal_get_superblock() to ensure s_first is valid. + +The following script could reproduce it: + +fstype=ext3 +blocksize=1024 +img=$fstype.img +offset=0 +found=0 +magic="c0 3b 39 98" + +dd if=/dev/zero of=$img bs=1M count=8 +mkfs -t $fstype -b $blocksize -F $img +filesize=`stat -c %s $img` +while [ $offset -lt $filesize ] +do + if od -j $offset -N 4 -t x1 $img | grep -i "$magic";then + echo "Found journal: $offset" + found=1 + break + fi + offset=`echo "$offset+$blocksize" | bc` +done + +if [ $found -ne 1 ];then + echo "Magic \"$magic\" not found" + exit 1 +fi + +dd if=/dev/zero of=$img seek=$(($offset+23)) conv=notrunc bs=1 count=1 + +mkdir -p ./mnt +mount -o loop $img ./mnt + +Cc: Jan Kara <jack@suse.cz> +Signed-off-by: Eryu Guan <guaneryu@gmail.com> +Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> +--- + fs/jbd/journal.c | 8 ++++++++ + fs/jbd2/journal.c | 8 ++++++++ + 2 files changed, 16 insertions(+), 0 deletions(-) + +diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c +index 9fe061f..fea8dd6 100644 +--- a/fs/jbd/journal.c ++++ b/fs/jbd/journal.c +@@ -1135,6 +1135,14 @@ static int journal_get_superblock(journal_t *journal) + goto out; + } + ++ if (be32_to_cpu(sb->s_first) == 0 || ++ be32_to_cpu(sb->s_first) >= journal->j_maxlen) { ++ printk(KERN_WARNING ++ "JBD: Invalid start block of journal: %u\n", ++ be32_to_cpu(sb->s_first)); ++ goto out; ++ } ++ + return 0; + + out: +diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c +index f24df13..d6e93d0 100644 +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -1251,6 +1251,14 @@ static int journal_get_superblock(journal_t *journal) + goto out; + } + ++ if (be32_to_cpu(sb->s_first) == 0 || ++ be32_to_cpu(sb->s_first) >= journal->j_maxlen) { ++ printk(KERN_WARNING ++ "JBD2: Invalid start block of journal: %u\n", ++ be32_to_cpu(sb->s_first)); ++ goto out; ++ } ++ + return 0; + + out: +-- +1.7.7.1 + diff --git a/freed-ora/current/f15/kernel.spec b/freed-ora/current/f15/kernel.spec index 09649bf07..23289b32c 100644 --- a/freed-ora/current/f15/kernel.spec +++ b/freed-ora/current/f15/kernel.spec @@ -42,7 +42,7 @@ Summary: The Linux kernel # When changing real_sublevel below, reset this by hand to 1 # (or to 0 and then use rpmdev-bumpspec). # -%global baserelease 1 +%global baserelease 2 %global fedora_build %{baserelease} # real_sublevel is the 3.x kernel version we're starting with @@ -151,8 +151,10 @@ Summary: The Linux kernel %if 0%{?stable_rc} %define stable_rctag .rc%{stable_rc} +%define pkg_release 0%{stable_rctag}.%{fedora_build}%{?buildid}%{?dist}%{?libres} +%else +%define pkg_release %{fedora_build}%{?buildid}%{?dist}%{?libres} %endif -%define pkg_release %{fedora_build}%{?stable_rctag}%{?buildid}%{?dist}%{?libres} # The kernel tarball/base version %define realversion 3.%{real_sublevel} @@ -648,8 +650,14 @@ Patch3000: rcutree-avoid-false-quiescent-states.patch # fs fixes +#rhbz 753346 +Patch3500: jbd-jbd2-validate-sb-s_first-in-journal_get_superblo.patch + # NFSv4 +#rhbz 753236 +Patch4000: nfsv4-include-bitmap-in-nfsv4_get_acl_data.patch + # patches headed upstream Patch12010: add-appleir-usb-driver.patch @@ -938,6 +946,11 @@ exit 1 %endif %endif +%if !%{baserelease} +echo "baserelease must be greater than zero" +exit 1 +%endif + # more sanity checking; do it quietly if [ "%{patches}" != "%%{patches}" ] ; then for patch in %{patches} ; do @@ -1137,6 +1150,8 @@ ApplyPatch linux-2.6-i386-nx-emulation.patch # # ext4 +#rhbz 753346 +ApplyPatch jbd-jbd2-validate-sb-s_first-in-journal_get_superblo.patch # xfs ApplyPatch xfs-Fix-possible-memory-corruption-in-xfs_readlink.patch @@ -1147,6 +1162,7 @@ ApplyPatch xfs-Fix-possible-memory-corruption-in-xfs_readlink.patch # eCryptfs # NFSv4 +ApplyPatch nfsv4-include-bitmap-in-nfsv4_get_acl_data.patch # USB @@ -1907,7 +1923,15 @@ fi # and build. %changelog -* Mon Nov 14 2011 Alexandre Oliva <lxoliva@fsfla.org> -libre +* Mon Nov 14 2011 Josh Boyer <jwboyer@redhat.com> 2.6.41.1-2 +- CVE-2011-4131: nfs4_getfacl decoding kernel oops (rhbz 753236) +- CVE-2011-4132: jbd/jbd2: invalid value of first log block leads to oops (rhbz 753346) + +* Fri Nov 11 2011 Chuck Ebbert <cebbert@redhat.com> +- Use the same naming scheme as rawhide for -stable RC kernels + (e.g. 2.6.41.1-0.rc1.1 instead of 2.6.41.1-1.rc1) + +* Fri Nov 11 2011 Alexandre Oliva <lxoliva@fsfla.org> -libre Mon Nov 14 - Use patch-3.1-libre-3.1.1-libre as patch-libre-3.1.1. * Fri Nov 11 2011 Josh Boyer <jwboyer@redhat.com> 2.6.41.1-1 diff --git a/freed-ora/current/f15/nfsv4-include-bitmap-in-nfsv4_get_acl_data.patch b/freed-ora/current/f15/nfsv4-include-bitmap-in-nfsv4_get_acl_data.patch new file mode 100644 index 000000000..1b795e97f --- /dev/null +++ b/freed-ora/current/f15/nfsv4-include-bitmap-in-nfsv4_get_acl_data.patch @@ -0,0 +1,118 @@ +From: Andy Adamson <andros@xxxxxxxxxx> + +The NFSv4 bitmap size is unbounded: a server can return an arbitrary +sized bitmap in an FATTR4_WORD0_ACL request. Replace using the +nfs4_fattr_bitmap_maxsz as a guess to the maximum bitmask returned by a server +with the inclusion of the bitmap (xdr length plus bitmasks) and the acl data +xdr length to the (cached) acl page data. + +This is a general solution to commit e5012d1f "NFSv4.1: update +nfs4_fattr_bitmap_maxsz" and fixes hitting a BUG_ON in xdr_shrink_bufhead +when getting ACLs. + +Cc:stable@xxxxxxxxxx +Signed-off-by: Andy Adamson <andros@xxxxxxxxxx> +--- + fs/nfs/nfs4proc.c | 20 ++++++++++++++++++-- + fs/nfs/nfs4xdr.c | 15 ++++++++++++--- + 2 files changed, 30 insertions(+), 5 deletions(-) + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index deb88d9..97014dd 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -3671,6 +3671,22 @@ static void nfs4_zap_acl_attr(struct inode *inode) + nfs4_set_cached_acl(inode, NULL); + } + ++/* ++ * The bitmap xdr length, bitmasks, and the attr xdr length are stored in ++ * the acl cache to handle variable length bitmasks. Just copy the acl data. ++ */ ++static void nfs4_copy_acl(char *buf, char *acl_data, size_t acl_len) ++{ ++ __be32 *q, *p = (__be32 *)acl_data; ++ int32_t len; ++ ++ len = be32_to_cpup(p); /* number of bitmasks */ ++ len += 2; /* add words for bitmap and attr xdr len */ ++ q = p + len; ++ len = len << 2; /* convert to bytes for acl_len math */ ++ memcpy(buf, (char *)q, acl_len - len); ++} ++ + static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen) + { + struct nfs_inode *nfsi = NFS_I(inode); +@@ -3688,7 +3704,7 @@ static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_ + ret = -ERANGE; /* see getxattr(2) man page */ + if (acl->len > buflen) + goto out; +- memcpy(buf, acl->data, acl->len); ++ nfs4_copy_acl(buf, acl->data, acl->len); + out_len: + ret = acl->len; + out: +@@ -3763,7 +3779,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu + if (res.acl_len > buflen) + goto out_free; + if (localpage) +- memcpy(buf, resp_buf, res.acl_len); ++ nfs4_copy_acl(buf, resp_buf, res.acl_len); + } + ret = res.acl_len; + out_free: +diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c +index f9fd96d..9c07380 100644 +--- a/fs/nfs/nfs4xdr.c ++++ b/fs/nfs/nfs4xdr.c +@@ -2513,7 +2513,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); +- replen = hdr.replen + op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz + 1; ++ replen = hdr.replen + op_decode_hdr_maxsz + 1; + encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); + + xdr_inline_pages(&req->rq_rcv_buf, replen << 2, +@@ -4955,7 +4955,7 @@ decode_restorefh(struct xdr_stream *xdr) + static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, + size_t *acl_len) + { +- __be32 *savep; ++ __be32 *savep, *bm_p; + uint32_t attrlen, + bitmap[3] = {0}; + struct kvec *iov = req->rq_rcv_buf.head; +@@ -4964,6 +4964,7 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, + *acl_len = 0; + if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) + goto out; ++ bm_p = xdr->p; + if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) + goto out; + if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) +@@ -4972,12 +4973,20 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, + if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U))) + return -EIO; + if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { +- size_t hdrlen; ++ size_t hdrlen, len; + u32 recvd; + ++ /*The bitmap (xdr len + bitmasks) and the attr xdr len words ++ * are stored with the acl data to handle the problem of ++ * variable length bitmasks.*/ ++ xdr->p = bm_p; ++ len = be32_to_cpup(bm_p); ++ len += 2; /* add bitmap and attr xdr len words */ ++ + /* We ignore &savep and don't do consistency checks on + * the attr length. Let userspace figure it out.... */ + hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base; ++ attrlen += len << 2; /* attrlen is in bytes */ + recvd = req->rq_rcv_buf.len - hdrlen; + if (attrlen > recvd) { + dprintk("NFS: server cheating in getattr" +-- +1.7.6.4 |