[kernel/f15: 1/2] Linux 3.2.12

Justin M. Forbes jforbes at fedoraproject.org
Tue Mar 20 15:51:14 UTC 2012


commit a5904b156a389e347cf19d56ecd2c829ec4e8a4e
Author: Justin M. Forbes <jforbes at redhat.com>
Date:   Tue Mar 20 10:47:43 2012 -0500

    Linux 3.2.12

 ...the-owner-group-name-string-when-doing-op.patch |  605 ++++++++++++++++++++
 SHLIB_BASE-randomization.patch                     |   69 +++
 kernel.spec                                        |   21 +-
 scsi-fix-sd_revalidate_disk-oops.patch             |  116 ----
 sources                                            |    2 +-
 5 files changed, 692 insertions(+), 121 deletions(-)
---
diff --git a/NFSv4-Save-the-owner-group-name-string-when-doing-op.patch b/NFSv4-Save-the-owner-group-name-string-when-doing-op.patch
new file mode 100644
index 0000000..610ec01
--- /dev/null
+++ b/NFSv4-Save-the-owner-group-name-string-when-doing-op.patch
@@ -0,0 +1,605 @@
+ommit 6926afd1925a54a13684ebe05987868890665e2b
+Author: Trond Myklebust <Trond.Myklebust at netapp.com>
+Date:   Sat Jan 7 13:22:46 2012 -0500
+
+    NFSv4: Save the owner/group name string when doing open
+
+    ...so that we can do the uid/gid mapping outside the asynchronous RPC
+    context.
+    This fixes a bug in the current NFSv4 atomic open code where the client
+    isn't able to determine what the true uid/gid fields of the file are,
+    (because the asynchronous nature of the OPEN call denies it the ability
+    to do an upcall) and so fills them with default values, marking the
+    inode as needing revalidation.
+    Unfortunately, in some cases, the VFS will do some additional sanity
+    checks on the file, and may override the server's decision to allow
+    the open because it sees the wrong owner/group fields.
+
+    Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+
+diff -up linux-3.2.noarch/fs/nfs/idmap.c.orig linux-3.2.noarch/fs/nfs/idmap.c
+--- linux-3.2.noarch/fs/nfs/idmap.c.orig	2012-03-15 10:38:58.876578000 -0400
++++ linux-3.2.noarch/fs/nfs/idmap.c	2012-03-15 10:51:10.344228000 -0400
+@@ -38,6 +38,89 @@
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/nfs_idmap.h>
++#include <linux/nfs_fs.h>
++
++/**
++ * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
++ * @fattr: fully initialised struct nfs_fattr
++ * @owner_name: owner name string cache
++ * @group_name: group name string cache
++ */
++void nfs_fattr_init_names(struct nfs_fattr *fattr,
++		struct nfs4_string *owner_name,
++		struct nfs4_string *group_name)
++{
++	fattr->owner_name = owner_name;
++	fattr->group_name = group_name;
++}
++
++static void nfs_fattr_free_owner_name(struct nfs_fattr *fattr)
++{
++	fattr->valid &= ~NFS_ATTR_FATTR_OWNER_NAME;
++	kfree(fattr->owner_name->data);
++}
++
++static void nfs_fattr_free_group_name(struct nfs_fattr *fattr)
++{
++	fattr->valid &= ~NFS_ATTR_FATTR_GROUP_NAME;
++	kfree(fattr->group_name->data);
++}
++
++static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr *fattr)
++{
++	struct nfs4_string *owner = fattr->owner_name;
++	__u32 uid;
++
++	if (!(fattr->valid & NFS_ATTR_FATTR_OWNER_NAME))
++		return false;
++	if (nfs_map_name_to_uid(server, owner->data, owner->len, &uid) == 0) {
++		fattr->uid = uid;
++		fattr->valid |= NFS_ATTR_FATTR_OWNER;
++	}
++	return true;
++}
++
++static bool nfs_fattr_map_group_name(struct nfs_server *server, struct nfs_fattr *fattr)
++{
++	struct nfs4_string *group = fattr->group_name;
++	__u32 gid;
++
++	if (!(fattr->valid & NFS_ATTR_FATTR_GROUP_NAME))
++		return false;
++	if (nfs_map_group_to_gid(server, group->data, group->len, &gid) == 0) {
++		fattr->gid = gid;
++		fattr->valid |= NFS_ATTR_FATTR_GROUP;
++	}
++	return true;
++}
++
++/**
++ * nfs_fattr_free_names - free up the NFSv4 owner and group strings
++ * @fattr: a fully initialised nfs_fattr structure
++ */
++void nfs_fattr_free_names(struct nfs_fattr *fattr)
++{
++	if (fattr->valid & NFS_ATTR_FATTR_OWNER_NAME)
++		nfs_fattr_free_owner_name(fattr);
++	if (fattr->valid & NFS_ATTR_FATTR_GROUP_NAME)
++		nfs_fattr_free_group_name(fattr);
++}
++
++/**
++ * nfs_fattr_map_and_free_names - map owner/group strings into uid/gid and free
++ * @server: pointer to the filesystem nfs_server structure
++ * @fattr: a fully initialised nfs_fattr structure
++ *
++ * This helper maps the cached NFSv4 owner/group strings in fattr into
++ * their numeric uid/gid equivalents, and then frees the cached strings.
++ */
++void nfs_fattr_map_and_free_names(struct nfs_server *server, struct nfs_fattr *fattr)
++{
++	if (nfs_fattr_map_owner_name(server, fattr))
++		nfs_fattr_free_owner_name(fattr);
++	if (nfs_fattr_map_group_name(server, fattr))
++		nfs_fattr_free_group_name(fattr);
++}
+ 
+ static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *res)
+ {
+diff -up linux-3.2.noarch/fs/nfs/inode.c.orig linux-3.2.noarch/fs/nfs/inode.c
+--- linux-3.2.noarch/fs/nfs/inode.c.orig	2012-03-15 10:39:00.362624000 -0400
++++ linux-3.2.noarch/fs/nfs/inode.c	2012-03-15 10:51:10.352227000 -0400
+@@ -1020,6 +1020,8 @@ void nfs_fattr_init(struct nfs_fattr *fa
+ 	fattr->valid = 0;
+ 	fattr->time_start = jiffies;
+ 	fattr->gencount = nfs_inc_attr_generation_counter();
++	fattr->owner_name = NULL;
++	fattr->group_name = NULL;
+ }
+ 
+ struct nfs_fattr *nfs_alloc_fattr(void)
+diff -up linux-3.2.noarch/fs/nfs/nfs4proc.c.orig linux-3.2.noarch/fs/nfs/nfs4proc.c
+--- linux-3.2.noarch/fs/nfs/nfs4proc.c.orig	2012-03-15 10:39:00.380629000 -0400
++++ linux-3.2.noarch/fs/nfs/nfs4proc.c	2012-03-15 10:51:10.362231000 -0400
+@@ -52,6 +52,7 @@
+ #include <linux/namei.h>
+ #include <linux/mount.h>
+ #include <linux/module.h>
++#include <linux/nfs_idmap.h>
+ #include <linux/sunrpc/bc_xprt.h>
+ #include <linux/xattr.h>
+ #include <linux/utsname.h>
+@@ -765,6 +766,8 @@ struct nfs4_opendata {
+ 	struct nfs_openres o_res;
+ 	struct nfs_open_confirmargs c_arg;
+ 	struct nfs_open_confirmres c_res;
++	struct nfs4_string owner_name;
++	struct nfs4_string group_name;
+ 	struct nfs_fattr f_attr;
+ 	struct nfs_fattr dir_attr;
+ 	struct dentry *dir;
+@@ -788,6 +791,7 @@ static void nfs4_init_opendata_res(struc
+ 	p->o_res.server = p->o_arg.server;
+ 	nfs_fattr_init(&p->f_attr);
+ 	nfs_fattr_init(&p->dir_attr);
++	nfs_fattr_init_names(&p->f_attr, &p->owner_name, &p->group_name);
+ }
+ 
+ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
+@@ -819,6 +823,7 @@ static struct nfs4_opendata *nfs4_openda
+ 	p->o_arg.name = &dentry->d_name;
+ 	p->o_arg.server = server;
+ 	p->o_arg.bitmask = server->attr_bitmask;
++	p->o_arg.dir_bitmask = server->cache_consistency_bitmask;
+ 	p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
+ 	if (flags & O_CREAT) {
+ 		u32 *s;
+@@ -855,6 +860,7 @@ static void nfs4_opendata_free(struct kr
+ 	dput(p->dir);
+ 	dput(p->dentry);
+ 	nfs_sb_deactive(sb);
++	nfs_fattr_free_names(&p->f_attr);
+ 	kfree(p);
+ }
+ 
+@@ -1579,6 +1585,8 @@ static int _nfs4_recover_proc_open(struc
+ 	if (status != 0 || !data->rpc_done)
+ 		return status;
+ 
++	nfs_fattr_map_and_free_names(NFS_SERVER(dir), &data->f_attr);
++
+ 	nfs_refresh_inode(dir, o_res->dir_attr);
+ 
+ 	if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
+@@ -1611,6 +1619,8 @@ static int _nfs4_proc_open(struct nfs4_o
+ 		return status;
+ 	}
+ 
++	nfs_fattr_map_and_free_names(server, &data->f_attr);
++
+ 	if (o_arg->open_flags & O_CREAT) {
+ 		update_changeattr(dir, &o_res->cinfo);
+ 		nfs_post_op_update_inode(dir, o_res->dir_attr);
+diff -up linux-3.2.noarch/fs/nfs/nfs4xdr.c.orig linux-3.2.noarch/fs/nfs/nfs4xdr.c
+--- linux-3.2.noarch/fs/nfs/nfs4xdr.c.orig	2012-03-15 10:38:54.054438000 -0400
++++ linux-3.2.noarch/fs/nfs/nfs4xdr.c	2012-03-15 10:51:10.373231000 -0400
+@@ -2298,7 +2298,7 @@ static void nfs4_xdr_enc_open(struct rpc
+ 	encode_getfh(xdr, &hdr);
+ 	encode_getfattr(xdr, args->bitmask, &hdr);
+ 	encode_restorefh(xdr, &hdr);
+-	encode_getfattr(xdr, args->bitmask, &hdr);
++	encode_getfattr(xdr, args->dir_bitmask, &hdr);
+ 	encode_nops(&hdr);
+ }
+ 
+@@ -3791,7 +3791,8 @@ out_overflow:
+ }
+ 
+ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap,
+-		const struct nfs_server *server, uint32_t *uid, int may_sleep)
++		const struct nfs_server *server, uint32_t *uid,
++		struct nfs4_string *owner_name)
+ {
+ 	uint32_t len;
+ 	__be32 *p;
+@@ -3808,8 +3809,12 @@ static int decode_attr_owner(struct xdr_
+ 		p = xdr_inline_decode(xdr, len);
+ 		if (unlikely(!p))
+ 			goto out_overflow;
+-		if (!may_sleep) {
+-			/* do nothing */
++		if (owner_name != NULL) {
++			owner_name->data = kmemdup(p, len, GFP_NOWAIT);
++			if (owner_name->data != NULL) {
++				owner_name->len = len;
++				ret = NFS_ATTR_FATTR_OWNER_NAME;
++			}
+ 		} else if (len < XDR_MAX_NETOBJ) {
+ 			if (nfs_map_name_to_uid(server, (char *)p, len, uid) == 0)
+ 				ret = NFS_ATTR_FATTR_OWNER;
+@@ -3829,7 +3834,8 @@ out_overflow:
+ }
+ 
+ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap,
+-		const struct nfs_server *server, uint32_t *gid, int may_sleep)
++		const struct nfs_server *server, uint32_t *gid,
++		struct nfs4_string *group_name)
+ {
+ 	uint32_t len;
+ 	__be32 *p;
+@@ -3846,8 +3852,12 @@ static int decode_attr_group(struct xdr_
+ 		p = xdr_inline_decode(xdr, len);
+ 		if (unlikely(!p))
+ 			goto out_overflow;
+-		if (!may_sleep) {
+-			/* do nothing */
++		if (group_name != NULL) {
++			group_name->data = kmemdup(p, len, GFP_NOWAIT);
++			if (group_name->data != NULL) {
++				group_name->len = len;
++				ret = NFS_ATTR_FATTR_GROUP_NAME;
++			}
+ 		} else if (len < XDR_MAX_NETOBJ) {
+ 			if (nfs_map_group_to_gid(server, (char *)p, len, gid) == 0)
+ 				ret = NFS_ATTR_FATTR_GROUP;
+@@ -4284,7 +4294,7 @@ xdr_error:
+ 
+ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
+ 		struct nfs_fattr *fattr, struct nfs_fh *fh,
+-		const struct nfs_server *server, int may_sleep)
++		const struct nfs_server *server)
+ {
+ 	int status;
+ 	umode_t fmode = 0;
+@@ -4351,12 +4361,12 @@ static int decode_getfattr_attrs(struct
+ 		goto xdr_error;
+ 	fattr->valid |= status;
+ 
+-	status = decode_attr_owner(xdr, bitmap, server, &fattr->uid, may_sleep);
++	status = decode_attr_owner(xdr, bitmap, server, &fattr->uid, fattr->owner_name);
+ 	if (status < 0)
+ 		goto xdr_error;
+ 	fattr->valid |= status;
+ 
+-	status = decode_attr_group(xdr, bitmap, server, &fattr->gid, may_sleep);
++	status = decode_attr_group(xdr, bitmap, server, &fattr->gid, fattr->group_name);
+ 	if (status < 0)
+ 		goto xdr_error;
+ 	fattr->valid |= status;
+@@ -4397,7 +4407,7 @@ xdr_error:
+ }
+ 
+ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr,
+-		struct nfs_fh *fh, const struct nfs_server *server, int may_sleep)
++		struct nfs_fh *fh, const struct nfs_server *server)
+ {
+ 	__be32 *savep;
+ 	uint32_t attrlen,
+@@ -4416,7 +4426,7 @@ static int decode_getfattr_generic(struc
+ 	if (status < 0)
+ 		goto xdr_error;
+ 
+-	status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, server, may_sleep);
++	status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, server);
+ 	if (status < 0)
+ 		goto xdr_error;
+ 
+@@ -4427,9 +4437,9 @@ xdr_error:
+ }
+ 
+ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
+-		const struct nfs_server *server, int may_sleep)
++		const struct nfs_server *server)
+ {
+-	return decode_getfattr_generic(xdr, fattr, NULL, server, may_sleep);
++	return decode_getfattr_generic(xdr, fattr, NULL, server);
+ }
+ 
+ /*
+@@ -5710,8 +5720,7 @@ static int nfs4_xdr_dec_open_downgrade(s
+ 	status = decode_open_downgrade(xdr, res);
+ 	if (status != 0)
+ 		goto out;
+-	decode_getfattr(xdr, res->fattr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -5737,8 +5746,7 @@ static int nfs4_xdr_dec_access(struct rp
+ 	status = decode_access(xdr, res);
+ 	if (status != 0)
+ 		goto out;
+-	decode_getfattr(xdr, res->fattr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -5767,8 +5775,7 @@ static int nfs4_xdr_dec_lookup(struct rp
+ 	status = decode_getfh(xdr, res->fh);
+ 	if (status)
+ 		goto out;
+-	status = decode_getfattr(xdr, res->fattr, res->server
+-			,!RPC_IS_ASYNC(rqstp->rq_task));
++	status = decode_getfattr(xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -5794,8 +5801,7 @@ static int nfs4_xdr_dec_lookup_root(stru
+ 		goto out;
+ 	status = decode_getfh(xdr, res->fh);
+ 	if (status == 0)
+-		status = decode_getfattr(xdr, res->fattr, res->server,
+-				!RPC_IS_ASYNC(rqstp->rq_task));
++		status = decode_getfattr(xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -5821,8 +5827,7 @@ static int nfs4_xdr_dec_remove(struct rp
+ 	status = decode_remove(xdr, &res->cinfo);
+ 	if (status)
+ 		goto out;
+-	decode_getfattr(xdr, res->dir_attr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->dir_attr, res->server);
+ out:
+ 	return status;
+ }
+@@ -5855,14 +5860,12 @@ static int nfs4_xdr_dec_rename(struct rp
+ 	if (status)
+ 		goto out;
+ 	/* Current FH is target directory */
+-	if (decode_getfattr(xdr, res->new_fattr, res->server,
+-				!RPC_IS_ASYNC(rqstp->rq_task)) != 0)
++	if (decode_getfattr(xdr, res->new_fattr, res->server))
+ 		goto out;
+ 	status = decode_restorefh(xdr);
+ 	if (status)
+ 		goto out;
+-	decode_getfattr(xdr, res->old_fattr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->old_fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -5898,14 +5901,12 @@ static int nfs4_xdr_dec_link(struct rpc_
+ 	 * Note order: OP_LINK leaves the directory as the current
+ 	 *             filehandle.
+ 	 */
+-	if (decode_getfattr(xdr, res->dir_attr, res->server,
+-				!RPC_IS_ASYNC(rqstp->rq_task)) != 0)
++	if (decode_getfattr(xdr, res->dir_attr, res->server))
+ 		goto out;
+ 	status = decode_restorefh(xdr);
+ 	if (status)
+ 		goto out;
+-	decode_getfattr(xdr, res->fattr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -5937,14 +5938,12 @@ static int nfs4_xdr_dec_create(struct rp
+ 	status = decode_getfh(xdr, res->fh);
+ 	if (status)
+ 		goto out;
+-	if (decode_getfattr(xdr, res->fattr, res->server,
+-				!RPC_IS_ASYNC(rqstp->rq_task)) != 0)
++	if (decode_getfattr(xdr, res->fattr, res->server))
+ 		goto out;
+ 	status = decode_restorefh(xdr);
+ 	if (status)
+ 		goto out;
+-	decode_getfattr(xdr, res->dir_fattr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->dir_fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -5976,8 +5975,7 @@ static int nfs4_xdr_dec_getattr(struct r
+ 	status = decode_putfh(xdr);
+ 	if (status)
+ 		goto out;
+-	status = decode_getfattr(xdr, res->fattr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	status = decode_getfattr(xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -6079,8 +6077,7 @@ static int nfs4_xdr_dec_close(struct rpc
+ 	 * 	an ESTALE error. Shouldn't be a problem,
+ 	 * 	though, since fattr->valid will remain unset.
+ 	 */
+-	decode_getfattr(xdr, res->fattr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -6111,13 +6108,11 @@ static int nfs4_xdr_dec_open(struct rpc_
+ 		goto out;
+ 	if (decode_getfh(xdr, &res->fh) != 0)
+ 		goto out;
+-	if (decode_getfattr(xdr, res->f_attr, res->server,
+-				!RPC_IS_ASYNC(rqstp->rq_task)) != 0)
++	if (decode_getfattr(xdr, res->f_attr, res->server) != 0)
+ 		goto out;
+ 	if (decode_restorefh(xdr) != 0)
+ 		goto out;
+-	decode_getfattr(xdr, res->dir_attr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->dir_attr, res->server);
+ out:
+ 	return status;
+ }
+@@ -6165,8 +6160,7 @@ static int nfs4_xdr_dec_open_noattr(stru
+ 	status = decode_open(xdr, res);
+ 	if (status)
+ 		goto out;
+-	decode_getfattr(xdr, res->f_attr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->f_attr, res->server);
+ out:
+ 	return status;
+ }
+@@ -6193,8 +6187,7 @@ static int nfs4_xdr_dec_setattr(struct r
+ 	status = decode_setattr(xdr);
+ 	if (status)
+ 		goto out;
+-	decode_getfattr(xdr, res->fattr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -6374,8 +6367,7 @@ static int nfs4_xdr_dec_write(struct rpc
+ 	if (status)
+ 		goto out;
+ 	if (res->fattr)
+-		decode_getfattr(xdr, res->fattr, res->server,
+-				!RPC_IS_ASYNC(rqstp->rq_task));
++		decode_getfattr(xdr, res->fattr, res->server);
+ 	if (!status)
+ 		status = res->count;
+ out:
+@@ -6404,8 +6396,7 @@ static int nfs4_xdr_dec_commit(struct rp
+ 	if (status)
+ 		goto out;
+ 	if (res->fattr)
+-		decode_getfattr(xdr, res->fattr, res->server,
+-				!RPC_IS_ASYNC(rqstp->rq_task));
++		decode_getfattr(xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -6564,8 +6555,7 @@ static int nfs4_xdr_dec_delegreturn(stru
+ 	status = decode_delegreturn(xdr);
+ 	if (status != 0)
+ 		goto out;
+-	decode_getfattr(xdr, res->fattr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -6594,8 +6584,7 @@ static int nfs4_xdr_dec_fs_locations(str
+ 		goto out;
+ 	xdr_enter_page(xdr, PAGE_SIZE);
+ 	status = decode_getfattr(xdr, &res->fs_locations->fattr,
+-				 res->fs_locations->server,
+-				 !RPC_IS_ASYNC(req->rq_task));
++				 res->fs_locations->server);
+ out:
+ 	return status;
+ }
+@@ -6844,8 +6833,7 @@ static int nfs4_xdr_dec_layoutcommit(str
+ 	status = decode_layoutcommit(xdr, rqstp, res);
+ 	if (status)
+ 		goto out;
+-	decode_getfattr(xdr, res->fattr, res->server,
+-			!RPC_IS_ASYNC(rqstp->rq_task));
++	decode_getfattr(xdr, res->fattr, res->server);
+ out:
+ 	return status;
+ }
+@@ -6976,7 +6964,7 @@ int nfs4_decode_dirent(struct xdr_stream
+ 		goto out_overflow;
+ 
+ 	if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
+-					entry->server, 1) < 0)
++					entry->server) < 0)
+ 		goto out_overflow;
+ 	if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
+ 		entry->ino = entry->fattr->mounted_on_fileid;
+diff -up linux-3.2.noarch/include/linux/nfs_idmap.h.orig linux-3.2.noarch/include/linux/nfs_idmap.h
+--- linux-3.2.noarch/include/linux/nfs_idmap.h.orig	2012-01-04 18:55:44.000000000 -0500
++++ linux-3.2.noarch/include/linux/nfs_idmap.h	2012-03-15 10:51:10.395228000 -0400
+@@ -66,6 +66,8 @@ struct idmap_msg {
+ /* Forward declaration to make this header independent of others */
+ struct nfs_client;
+ struct nfs_server;
++struct nfs_fattr;
++struct nfs4_string;
+ 
+ #ifdef CONFIG_NFS_USE_NEW_IDMAPPER
+ 
+@@ -97,6 +99,12 @@ void nfs_idmap_delete(struct nfs_client
+ 
+ #endif /* CONFIG_NFS_USE_NEW_IDMAPPER */
+ 
++void nfs_fattr_init_names(struct nfs_fattr *fattr,
++		struct nfs4_string *owner_name,
++		struct nfs4_string *group_name);
++void nfs_fattr_free_names(struct nfs_fattr *);
++void nfs_fattr_map_and_free_names(struct nfs_server *, struct nfs_fattr *);
++
+ int nfs_map_name_to_uid(const struct nfs_server *, const char *, size_t, __u32 *);
+ int nfs_map_group_to_gid(const struct nfs_server *, const char *, size_t, __u32 *);
+ int nfs_map_uid_to_name(const struct nfs_server *, __u32, char *, size_t);
+diff -up linux-3.2.noarch/include/linux/nfs_xdr.h.orig linux-3.2.noarch/include/linux/nfs_xdr.h
+--- linux-3.2.noarch/include/linux/nfs_xdr.h.orig	2012-03-15 10:38:54.464449000 -0400
++++ linux-3.2.noarch/include/linux/nfs_xdr.h	2012-03-15 10:51:10.415229000 -0400
+@@ -18,6 +18,11 @@
+ /* Forward declaration for NFS v3 */
+ struct nfs4_secinfo_flavors;
+ 
++struct nfs4_string {
++	unsigned int len;
++	char *data;
++};
++
+ struct nfs_fsid {
+ 	uint64_t		major;
+ 	uint64_t		minor;
+@@ -61,6 +66,8 @@ struct nfs_fattr {
+ 	struct timespec		pre_ctime;	/* pre_op_attr.ctime	  */
+ 	unsigned long		time_start;
+ 	unsigned long		gencount;
++	struct nfs4_string	*owner_name;
++	struct nfs4_string	*group_name;
+ };
+ 
+ #define NFS_ATTR_FATTR_TYPE		(1U << 0)
+@@ -85,6 +92,8 @@ struct nfs_fattr {
+ #define NFS_ATTR_FATTR_V4_REFERRAL	(1U << 19)	/* NFSv4 referral */
+ #define NFS_ATTR_FATTR_MOUNTPOINT	(1U << 20)	/* Treat as mountpoint */
+ #define NFS_ATTR_FATTR_MOUNTED_ON_FILEID		(1U << 21)
++#define NFS_ATTR_FATTR_OWNER_NAME	(1U << 22)
++#define NFS_ATTR_FATTR_GROUP_NAME	(1U << 23)
+ 
+ #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
+ 		| NFS_ATTR_FATTR_MODE \
+@@ -324,6 +333,7 @@ struct nfs_openargs {
+ 	const struct qstr *	name;
+ 	const struct nfs_server *server;	 /* Needed for ID mapping */
+ 	const u32 *		bitmask;
++	const u32 *		dir_bitmask;
+ 	__u32			claim;
+ 	struct nfs4_sequence_args	seq_args;
+ };
+@@ -342,6 +352,8 @@ struct nfs_openres {
+ 	__u32			do_recall;
+ 	__u64			maxsize;
+ 	__u32			attrset[NFS4_BITMAP_SIZE];
++	struct nfs4_string	*owner;
++	struct nfs4_string	*group_owner;
+ 	struct nfs4_sequence_res	seq_res;
+ };
+ 
+@@ -778,11 +790,6 @@ struct nfs3_getaclres {
+ 	struct posix_acl *	acl_default;
+ };
+ 
+-struct nfs4_string {
+-	unsigned int len;
+-	char *data;
+-};
+-
+ #ifdef CONFIG_NFS_V4
+ 
+ typedef u64 clientid4;
diff --git a/SHLIB_BASE-randomization.patch b/SHLIB_BASE-randomization.patch
new file mode 100644
index 0000000..80e4d64
--- /dev/null
+++ b/SHLIB_BASE-randomization.patch
@@ -0,0 +1,69 @@
+diff -uNrp kernel-3.2.fc16.orig/arch/x86/mm/mmap.c kernel-3.2.fc16.new/arch/x86/mm/mmap.c
+--- kernel-3.2.fc16.orig/arch/x86/mm/mmap.c	2012-03-19 16:47:03.495169091 -0400
++++ kernel-3.2.fc16.new/arch/x86/mm/mmap.c	2012-03-19 16:50:03.574168052 -0400
+@@ -106,6 +106,10 @@ static unsigned long mmap_legacy_base(vo
+                return TASK_UNMAPPED_BASE + mmap_rnd();
+ }
+
++#ifdef CONFIG_X86_32
++  #define SHLIB_BASE             0x00111000
++#endif
++
+ /*
+  * This function, called very early during the creation of a new
+  * process VM image, sets up which VM layout function to use:
+@@ -126,8 +126,10 @@ void arch_pick_mmap_layout(struct mm_str
+ #ifdef CONFIG_X86_32
+ 		if (!(current->personality & READ_IMPLIES_EXEC)
+ 		    && !(__supported_pte_mask & _PAGE_NX)
+-		    && mmap_is_ia32())
++		    && mmap_is_ia32()) {
++			mm->shlib_base = SHLIB_BASE + mmap_rnd();
+ 			mm->get_unmapped_exec_area = arch_get_unmapped_exec_area;
++		}
+ #endif
+ 		mm->unmap_area = arch_unmap_area_topdown;
+ 	}
+diff -uNrp kernel-3.2.fc16.orig/include/linux/mm_types.h kernel-3.2.fc16.new/include/linux/mm_types.h
+--- kernel-3.2.fc16.orig/include/linux/mm_types.h	2012-03-19 16:46:47.382169153 -0400
++++ kernel-3.2.fc16.new/include/linux/mm_types.h	2012-03-19 16:50:40.738168219 -0400
+@@ -300,6 +300,7 @@ struct mm_struct {
+ 	void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
+ #endif
+ 	unsigned long mmap_base;		/* base of mmap area */
++	unsigned long shlib_base;		/* base of lib map area (ASCII armour)*/
+ 	unsigned long task_size;		/* size of task vm space */
+ 	unsigned long cached_hole_size; 	/* if non-zero, the largest hole below free_area_cache */
+ 	unsigned long free_area_cache;		/* first hole of size cached_hole_size or larger */
+diff -uNrp kernel-3.2.fc16.orig/mm/mmap.c kernel-3.2.fc16.new/mm/mmap.c
+--- kernel-3.2.fc16.orig/mm/mmap.c	2012-03-19 16:46:15.791169274 -0400
++++ kernel-3.2.fc16.new/mm/mmap.c	2012-03-19 16:51:37.351166875 -0400
+@@ -1594,8 +1594,6 @@ static bool should_randomize(void)
+ 		!(current->personality & ADDR_NO_RANDOMIZE);
+ }
+ 
+-#define SHLIB_BASE	0x00110000
+-
+ unsigned long
+ arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
+ 		unsigned long len0, unsigned long pgoff, unsigned long flags)
+@@ -1612,8 +1610,8 @@ arch_get_unmapped_exec_area(struct file
+ 		return addr;
+ 
+ 	if (!addr)
+-		addr = !should_randomize() ? SHLIB_BASE :
+-			randomize_range(SHLIB_BASE, 0x01000000, len);
++		addr = !should_randomize() ? mm->shlib_base :
++			randomize_range(mm->shlib_base, 0x01000000, len);
+ 
+ 	if (addr) {
+ 		addr = PAGE_ALIGN(addr);
+@@ -1623,7 +1621,7 @@ arch_get_unmapped_exec_area(struct file
+ 			return addr;
+ 	}
+ 
+-	addr = SHLIB_BASE;
++	addr = mm->shlib_base;
+ 	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
+ 		/* At this point:  (!vma || addr < vma->vm_end). */
+ 		if (TASK_SIZE - len < addr)
diff --git a/kernel.spec b/kernel.spec
index fd5f607..e28ce92 100644
--- a/kernel.spec
+++ b/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 4
+%global baserelease 1
 %global fedora_build %{baserelease}
 
 # real_sublevel is the 3.x kernel version we're starting with
@@ -51,7 +51,7 @@ Summary: The Linux kernel
 %define fake_sublevel %(echo $((40 + %{real_sublevel})))
 
 # Do we have a -stable update to apply?
-%define stable_update 10
+%define stable_update 12
 # Is it a -stable RC?
 %define stable_rc 0
 # Set rpm version accordingly
@@ -639,6 +639,7 @@ Patch3500: jbd-jbd2-validate-sb-s_first-in-journal_get_superblo.patch
 # NFSv4
 Patch4000: NFSv4-Reduce-the-footprint-of-the-idmapper.patch
 Patch4001: NFSv4-Further-reduce-the-footprint-of-the-idmapper.patch
+Patch4003: NFSv4-Save-the-owner-group-name-string-when-doing-op.patch
 
 # patches headed upstream
 
@@ -703,7 +704,6 @@ Patch21092: e1000e-Avoid-wrong-check-on-TX-hang.patch
 
 #rhbz 754518
 #Patch21093: scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
-Patch21093: scsi-fix-sd_revalidate_disk-oops.patch
 
 #rhbz 771058
 Patch21100: msi-irq-sysfs-warning.patch
@@ -720,6 +720,9 @@ Patch21104: sony-laptop-Enable-keyboard-backlight-by-default.patch
 #rhbz 803809 CVE-2012-1179
 Patch21106: mm-thp-fix-pmd_bad-triggering.patch
 
+#rhbz 804947 CVE-2012-1568
+Patch21107: SHLIB_BASE-randomization.patch
+
 Patch21110: x86-ioapic-add-register-checks-for-bogus-io-apic-entries.patch
 
 Patch21200: unhandled-irqs-switch-to-polling.patch
@@ -1178,6 +1181,7 @@ ApplyPatch jbd-jbd2-validate-sb-s_first-in-journal_get_superblo.patch
 # NFSv4
 ApplyPatch NFSv4-Reduce-the-footprint-of-the-idmapper.patch
 ApplyPatch NFSv4-Further-reduce-the-footprint-of-the-idmapper.patch
+ApplyPatch NFSv4-Save-the-owner-group-name-string-when-doing-op.patch
  
 # USB
 
@@ -1323,7 +1327,6 @@ ApplyPatch e1000e-Avoid-wrong-check-on-TX-hang.patch
 
 #rhbz 754518
 #ApplyPatch scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
-ApplyPatch scsi-fix-sd_revalidate_disk-oops.patch
 
 # Remove overlap between bcma/b43 and brcmsmac and reenable bcm4331
 ApplyPatch bcma-brcmsmac-compat.patch
@@ -1343,6 +1346,9 @@ ApplyPatch x86-ioapic-add-register-checks-for-bogus-io-apic-entries.patch
 #rhbz 803809 CVE-2012-1179
 ApplyPatch mm-thp-fix-pmd_bad-triggering.patch
 
+#rhbz 804947 CVE-2012-1568
+ApplyPatch SHLIB_BASE-randomization.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -1990,6 +1996,13 @@ fi
 # and build.
 
 %changelog
+* Tue Mar 20 2012 Justin M. Forbes <jforbes at redhat.com> 2.6.42.12-1
+- Linux 3.2.10
+- CVE-2012-1568 SHLIB_BASE randomization (rhbz 804947)
+
+* Mon Mar 19 2012 Steve Dickson <steved at redhat.com>
+- NFSv4: Save the owner/group name string when doing open (bz 794780)
+
 * Fri Mar 16 2012 Justin M. Forbes <jforbes at redhat.com>
 - re-enable threading on hibernate compression/decompression
 
diff --git a/sources b/sources
index a003ef5..02f08ef 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
 364066fa18767ec0ae5f4e4abcf9dc51  linux-3.2.tar.xz
-7481fa09f2efda915ed19a9da33a2e59  patch-3.2.10.xz
+ee0ce13f2cb7f03a8cda0910fd0fa050  patch-3.2.12.xz


More information about the scm-commits mailing list