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: git-fixes
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.
Acked-by: NeilBrown <neilb@suse.com>
Signed-off-by: Neil Brown <neilb@suse.com>
---
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
@@ -2862,10 +2862,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);
@@ -2972,7 +2973,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) {
if (!S_ISDIR(inode->i_mode))
@@ -2982,7 +2984,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
@@ -223,8 +223,7 @@ static int nfs3_proc_lookupp(struct inod
task_flags);
}
-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),
@@ -235,7 +234,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
@@ -2662,7 +2662,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)
@@ -4514,13 +4515,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
@@ -56,12 +56,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 {
@@ -390,7 +396,7 @@ extern int nfs_post_op_update_inode_forc
extern int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_getattr(struct user_namespace *, 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 user_namespace *, struct inode *, int);
extern int nfs_open(struct inode *, struct file *);
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1747,7 +1747,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 *,