NFSv4: Fix an Oops in the NFSv4 getacl code
This commit is contained in:
parent
7052360844
commit
14843a4634
11
kernel.spec
11
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 3
|
||||
%global baserelease 6
|
||||
%global fedora_build %{baserelease}
|
||||
|
||||
# real_sublevel is the 3.x kernel version we're starting with
|
||||
|
@ -669,8 +669,10 @@ Patch21004: arm-tegra-nvec-kconfig.patch
|
|||
#rhbz 717735
|
||||
Patch21045: nfs-client-freezer.patch
|
||||
|
||||
Patch21046: nfs-oops-getacl.patch
|
||||
|
||||
#rhbz 590880
|
||||
Patch21046: alps.patch
|
||||
Patch21050: alps.patch
|
||||
|
||||
Patch21070: ext4-Support-check-none-nocheck-mount-options.patch
|
||||
Patch21071: ext4-Fix-error-handling-on-inode-bitmap-corruption.patch
|
||||
|
@ -1281,6 +1283,8 @@ ApplyPatch hpsa-add-irqf-shared.patch
|
|||
#rhbz 717735
|
||||
ApplyPatch nfs-client-freezer.patch
|
||||
|
||||
ApplyPatch nfs-oops-getacl.patch
|
||||
|
||||
#rhbz 590880
|
||||
ApplyPatch alps.patch
|
||||
|
||||
|
@ -1962,6 +1966,9 @@ fi
|
|||
# and build.
|
||||
|
||||
%changelog
|
||||
* Mon Feb 20 2012 Dave Jones <davej@redhat.com>
|
||||
- NFSv4: Fix an Oops in the NFSv4 getacl code
|
||||
|
||||
* Fri Feb 17 2012 Dave Jones <davej@redhat.com>
|
||||
- improve handling of null rate in LIS3LV02Dx accelerometer driver. (rhbz 785814)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue