summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Jones <davej@redhat.com>2012-02-20 13:40:26 -0500
committerDave Jones <davej@redhat.com>2012-02-20 13:40:26 -0500
commite9f72477ec5bc201b8c3f4ec81689a8f67cfcc19 (patch)
tree10c443648415fd27616730d15b54811aa23ae1a8
parentcd70fad7efdfdf12088efc10d80c35a8f759b524 (diff)
downloadkernel-e9f72477ec5bc201b8c3f4ec81689a8f67cfcc19.tar.gz
kernel-e9f72477ec5bc201b8c3f4ec81689a8f67cfcc19.tar.xz
kernel-e9f72477ec5bc201b8c3f4ec81689a8f67cfcc19.zip
NFSv4: Fix an Oops in the NFSv4 getacl code
-rw-r--r--kernel.spec9
-rw-r--r--nfs-oops-getacl.patch96
2 files changed, 104 insertions, 1 deletions
diff --git a/kernel.spec b/kernel.spec
index 9d67c935c..dbe3b2d8d 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -54,7 +54,7 @@ Summary: The Linux kernel
# For non-released -rc kernels, this will be appended after the rcX and
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
#
-%global baserelease 2
+%global baserelease 3
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
@@ -734,6 +734,8 @@ Patch14000: hibernate-freeze-filesystems.patch
Patch14010: lis3-improve-handling-of-null-rate.patch
+Patch14020: nfs-oops-getacl.patch
+
Patch20000: utrace.patch
# Flattened devicetree support
@@ -1455,6 +1457,8 @@ ApplyPatch hibernate-freeze-filesystems.patch
ApplyPatch lis3-improve-handling-of-null-rate.patch
+ApplyPatch nfs-oops-getacl.patch
+
# utrace.
ApplyPatch utrace.patch
@@ -2366,6 +2370,9 @@ fi
# ||----w |
# || ||
%changelog
+* Mon Feb 20 2012 Dave Jones <davej@redhat.com>
+- NFSv4: Fix an Oops in the NFSv4 getacl code
+
* Mon Feb 20 2012 Josh Boyer <jwboyer@gmail.com> - 3.3.0-0.rc4.git0.2
- Reenable debugging options.
diff --git a/nfs-oops-getacl.patch b/nfs-oops-getacl.patch
new file mode 100644
index 000000000..53e599dd4
--- /dev/null
+++ b/nfs-oops-getacl.patch
@@ -0,0 +1,96 @@
+From 331818f1c468a24e581aedcbe52af799366a9dfe Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Fri, 3 Feb 2012 18:30:53 -0500
+Subject: [PATCH] NFSv4: Fix an Oops in the NFSv4 getacl code
+
+Commit bf118a342f10dafe44b14451a1392c3254629a1f (NFSv4: include bitmap
+in nfsv4 get acl data) introduces the 'acl_scratch' page for the case
+where we may need to decode multi-page data. However it fails to take
+into account the fact that the variable may be NULL (for the case where
+we're not doing multi-page decode), and it also attaches it to the
+encoding xdr_stream rather than the decoding one.
+
+The immediate result is an Oops in nfs4_xdr_enc_getacl due to the
+call to page_address() with a NULL page pointer.
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Cc: Andy Adamson <andros@netapp.com>
+Cc: stable@vger.kernel.org
+---
+ fs/nfs/nfs4proc.c | 8 ++++----
+ fs/nfs/nfs4xdr.c | 5 ++++-
+ include/linux/nfs_xdr.h | 2 +-
+ 3 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index f0c849c..d202e04 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -3575,8 +3575,8 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
+ }
+ if (npages > 1) {
+ /* for decoding across pages */
+- args.acl_scratch = alloc_page(GFP_KERNEL);
+- if (!args.acl_scratch)
++ res.acl_scratch = alloc_page(GFP_KERNEL);
++ if (!res.acl_scratch)
+ goto out_free;
+ }
+ args.acl_len = npages * PAGE_SIZE;
+@@ -3612,8 +3612,8 @@ out_free:
+ for (i = 0; i < npages; i++)
+ if (pages[i])
+ __free_page(pages[i]);
+- if (args.acl_scratch)
+- __free_page(args.acl_scratch);
++ if (res.acl_scratch)
++ __free_page(res.acl_scratch);
+ return ret;
+ }
+
+diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
+index 95e92e4..33bd8d0 100644
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -2522,7 +2522,6 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
+
+ xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
+ args->acl_pages, args->acl_pgbase, args->acl_len);
+- xdr_set_scratch_buffer(xdr, page_address(args->acl_scratch), PAGE_SIZE);
+
+ encode_nops(&hdr);
+ }
+@@ -6032,6 +6031,10 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+ struct compound_hdr hdr;
+ int status;
+
++ if (res->acl_scratch != NULL) {
++ void *p = page_address(res->acl_scratch);
++ xdr_set_scratch_buffer(xdr, p, PAGE_SIZE);
++ }
+ status = decode_compound_hdr(xdr, &hdr);
+ if (status)
+ goto out;
+diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
+index a764cef..d6ba9a1 100644
+--- a/include/linux/nfs_xdr.h
++++ b/include/linux/nfs_xdr.h
+@@ -614,7 +614,6 @@ struct nfs_getaclargs {
+ size_t acl_len;
+ unsigned int acl_pgbase;
+ struct page ** acl_pages;
+- struct page * acl_scratch;
+ struct nfs4_sequence_args seq_args;
+ };
+
+@@ -624,6 +623,7 @@ struct nfs_getaclres {
+ size_t acl_len;
+ size_t acl_data_offset;
+ int acl_flags;
++ struct page * acl_scratch;
+ struct nfs4_sequence_res seq_res;
+ };
+
+--
+1.7.4.1
+