From: NeilBrown <neilb@suse.de>
Date: Mon, 27 Sep 2021 11:51:37 +1000
Subject: [PATCH] Restore kabi after NFS: pass cred explicitly for access tests
Patch-mainline: Never, kabi
References: bsc#1190746 bsc#1191172
Changing nfs_access_entry, and paassing the cred around differently breaks kabi.
So revert back to passing the cred around in nfs_access_entry,
overloading the group_info field, and hide the struct change from kabi.
No other module ever allocates these or looks in them, so this should be safe.
---
fs/nfs/dir.c | 10 ++++++----
fs/nfs/nfs3proc.c | 5 ++---
fs/nfs/nfs4proc.c | 7 ++++---
include/linux/nfs_fs.h | 12 +++++++++---
include/linux/nfs_xdr.h | 2 +-
5 files changed, 22 insertions(+), 14 deletions(-)
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2505,10 +2505,11 @@ found:
nfs_access_free_entry(entry);
}
-void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set,
- const struct cred *cred)
+void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
{
struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL);
+ struct cred *cred = (void*)set->group_info;
+
if (cache == NULL)
return;
RB_CLEAR_NODE(&cache->rb_node);
@@ -2613,7 +2614,8 @@ static int nfs_do_access(struct inode *i
cache.mask |= NFS_ACCESS_DELETE | NFS_ACCESS_LOOKUP;
else
cache.mask |= NFS_ACCESS_EXECUTE;
- status = NFS_PROTO(inode)->access(inode, &cache, cred);
+ cache.group_info = (void*)cred;
+ status = NFS_PROTO(inode)->access(inode, &cache);
if (status != 0) {
if (status == -ESTALE) {
nfs_zap_caches(inode);
@@ -2622,7 +2624,7 @@ static int nfs_do_access(struct inode *i
}
goto out;
}
- nfs_access_add_cache(inode, &cache, cred);
+ nfs_access_add_cache(inode, &cache);
out_cached:
cache_mask = nfs_access_calc_mask(cache.mask, inode->i_mode);
if ((mask & ~cache_mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -188,8 +188,7 @@ nfs3_proc_lookup(struct inode *dir, cons
return status;
}
-static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry,
- const struct cred *cred)
+static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
{
struct nfs3_accessargs arg = {
.fh = NFS_FH(inode),
@@ -200,7 +199,7 @@ static int nfs3_proc_access(struct inode
.rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS],
.rpc_argp = &arg,
.rpc_resp = &res,
- .rpc_cred = cred,
+ .rpc_cred = (void*)entry->group_info,
};
int status = -ENOMEM;
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2586,7 +2586,8 @@ static int nfs4_opendata_access(const st
mask = NFS4_ACCESS_READ;
nfs_access_set_mask(&cache, opendata->o_res.access_result);
- nfs_access_add_cache(state->inode, &cache, cred);
+ cache.group_info = (void*)cred;
+ nfs_access_add_cache(state->inode, &cache);
flags = NFS4_ACCESS_READ | NFS4_ACCESS_EXECUTE | NFS4_ACCESS_LOOKUP;
if ((mask & ~cache.mask & flags) == 0)
@@ -4410,13 +4411,13 @@ static int _nfs4_proc_access(struct inod
return status;
}
-static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry,
- const struct cred *cred)
+static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
{
struct nfs4_exception exception = {
.interruptible = true,
};
int err;
+ const struct cred *cred = (void*)entry->group_info;
do {
err = _nfs4_proc_access(inode, entry, cred);
trace_nfs4_access(inode, err);
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -51,12 +51,18 @@
struct nfs_access_entry {
struct rb_node rb_node;
struct list_head lru;
- kuid_t fsuid;
- kgid_t fsgid;
+#ifdef __GENKSYMS__
+ const struct cred *cred;
+#else
struct group_info *group_info;
+#endif
__u32 mask;
struct rcu_head rcu_head;
+#ifndef __GENKSYMS__
+ kuid_t fsuid;
+ kgid_t fsgid;
unsigned long jiffies;
+#endif
};
struct nfs_lock_context {
@@ -380,7 +386,7 @@ extern int nfs_post_op_update_inode(stru
extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_getattr(const struct path *, struct kstat *, u32, unsigned int);
-extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *, const struct cred *);
+extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *);
extern void nfs_access_set_mask(struct nfs_access_entry *, u32);
extern int nfs_permission(struct inode *, int);
extern int nfs_open(struct inode *, struct file *);
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1652,7 +1652,7 @@ struct nfs_rpc_ops {
struct nfs4_label *);
int (*lookupp) (struct inode *, struct nfs_fh *,
struct nfs_fattr *, struct nfs4_label *);
- int (*access) (struct inode *, struct nfs_access_entry *, const struct cred *);
+ int (*access) (struct inode *, struct nfs_access_entry *);
int (*readlink)(struct inode *, struct page *, unsigned int,
unsigned int);
int (*create) (struct inode *, struct dentry *,