Linux 3.2.12
This commit is contained in:
parent
262c908385
commit
a5904b156a
5 changed files with 692 additions and 121 deletions
605
NFSv4-Save-the-owner-group-name-string-when-doing-op.patch
Normal file
605
NFSv4-Save-the-owner-group-name-string-when-doing-op.patch
Normal file
|
|
@ -0,0 +1,605 @@
|
|||
ommit 6926afd1925a54a13684ebe05987868890665e2b
|
||||
Author: Trond Myklebust <Trond.Myklebust@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@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;
|
||||
69
SHLIB_BASE-randomization.patch
Normal file
69
SHLIB_BASE-randomization.patch
Normal file
|
|
@ -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)
|
||||
21
kernel.spec
21
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@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@redhat.com>
|
||||
- NFSv4: Save the owner/group name string when doing open (bz 794780)
|
||||
|
||||
* Fri Mar 16 2012 Justin M. Forbes <jforbes@redhat.com>
|
||||
- re-enable threading on hibernate compression/decompression
|
||||
|
||||
|
|
|
|||
|
|
@ -1,116 +0,0 @@
|
|||
--- linux-2.6.42.noarch/fs/partitions/check.c~ 2012-02-20 18:32:55.314253719 -0500
|
||||
+++ linux-2.6.42.noarch/fs/partitions/check.c 2012-02-20 18:34:46.509859745 -0500
|
||||
@@ -539,17 +539,11 @@ static bool disk_unlock_native_capacity(
|
||||
}
|
||||
}
|
||||
|
||||
-int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
|
||||
+static int drop_partitions(struct gendisk *disk, struct block_device *bdev)
|
||||
{
|
||||
- struct parsed_partitions *state = NULL;
|
||||
struct disk_part_iter piter;
|
||||
struct hd_struct *part;
|
||||
- int p, highest, res;
|
||||
-rescan:
|
||||
- if (state && !IS_ERR(state)) {
|
||||
- kfree(state);
|
||||
- state = NULL;
|
||||
- }
|
||||
+ int res;
|
||||
|
||||
if (bdev->bd_part_count)
|
||||
return -EBUSY;
|
||||
@@ -562,6 +556,24 @@ rescan:
|
||||
delete_partition(disk, part->partno);
|
||||
disk_part_iter_exit(&piter);
|
||||
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
|
||||
+{
|
||||
+ struct parsed_partitions *state = NULL;
|
||||
+ struct hd_struct *part;
|
||||
+ int p, highest, res;
|
||||
+rescan:
|
||||
+ if (state && !IS_ERR(state)) {
|
||||
+ kfree(state);
|
||||
+ state = NULL;
|
||||
+ }
|
||||
+
|
||||
+ res = drop_partitions(disk, bdev);
|
||||
+ if (res)
|
||||
+ return res;
|
||||
+
|
||||
if (disk->fops->revalidate_disk)
|
||||
disk->fops->revalidate_disk(disk);
|
||||
check_disk_size_change(disk, bdev);
|
||||
@@ -665,6 +677,26 @@ rescan:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int invalidate_partitions(struct gendisk *disk, struct block_device *bdev)
|
||||
+{
|
||||
+ int res;
|
||||
+
|
||||
+ if (!bdev->bd_invalidated)
|
||||
+ return 0;
|
||||
+
|
||||
+ res = drop_partitions(disk, bdev);
|
||||
+ if (res)
|
||||
+ return res;
|
||||
+
|
||||
+ set_capacity(disk, 0);
|
||||
+ check_disk_size_change(disk, bdev);
|
||||
+ bdev->bd_invalidated = 0;
|
||||
+ /* tell userspace that the media / partition table may have changed */
|
||||
+ kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p)
|
||||
{
|
||||
struct address_space *mapping = bdev->bd_inode->i_mapping;
|
||||
--- linux-2.6.42.noarch/include/linux/genhd.h~ 2012-02-20 18:35:02.777802107 -0500
|
||||
+++ linux-2.6.42.noarch/include/linux/genhd.h 2012-02-20 18:35:13.873762792 -0500
|
||||
@@ -596,6 +596,7 @@ extern char *disk_name (struct gendisk *
|
||||
|
||||
extern int disk_expand_part_tbl(struct gendisk *disk, int target);
|
||||
extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
|
||||
+extern int invalidate_partitions(struct gendisk *disk, struct block_device *bdev);
|
||||
extern struct hd_struct * __must_check add_partition(struct gendisk *disk,
|
||||
int partno, sector_t start,
|
||||
sector_t len, int flags,
|
||||
--- linux-2.6.42.noarch/fs/block_dev.c~ 2012-02-20 18:35:24.890723757 -0500
|
||||
+++ linux-2.6.42.noarch/fs/block_dev.c 2012-02-20 18:36:25.166510197 -0500
|
||||
@@ -1159,8 +1159,12 @@ static int __blkdev_get(struct block_dev
|
||||
* The latter is necessary to prevent ghost
|
||||
* partitions on a removed medium.
|
||||
*/
|
||||
- if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
|
||||
- rescan_partitions(disk, bdev);
|
||||
+ if (bdev->bd_invalidated) {
|
||||
+ if (!ret)
|
||||
+ rescan_partitions(disk, bdev);
|
||||
+ else if (ret == -ENOMEDIUM)
|
||||
+ invalidate_partitions(disk, bdev);
|
||||
+ }
|
||||
if (ret)
|
||||
goto out_clear;
|
||||
} else {
|
||||
@@ -1190,8 +1194,12 @@ static int __blkdev_get(struct block_dev
|
||||
if (bdev->bd_disk->fops->open)
|
||||
ret = bdev->bd_disk->fops->open(bdev, mode);
|
||||
/* the same as first opener case, read comment there */
|
||||
- if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
|
||||
- rescan_partitions(bdev->bd_disk, bdev);
|
||||
+ if (bdev->bd_invalidated) {
|
||||
+ if (!ret)
|
||||
+ rescan_partitions(bdev->bd_disk, bdev);
|
||||
+ else if (ret == -ENOMEDIUM)
|
||||
+ invalidate_partitions(bdev->bd_disk, bdev);
|
||||
+ }
|
||||
if (ret)
|
||||
goto out_unlock_bdev;
|
||||
}
|
||||
2
sources
2
sources
|
|
@ -1,2 +1,2 @@
|
|||
364066fa18767ec0ae5f4e4abcf9dc51 linux-3.2.tar.xz
|
||||
7481fa09f2efda915ed19a9da33a2e59 patch-3.2.10.xz
|
||||
ee0ce13f2cb7f03a8cda0910fd0fa050 patch-3.2.12.xz
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue