nfsd: Pass 'cred' instead of 'rqstp' to some functions.

nfsd_permission(), exp_rdonly(), nfsd_setuser(), and nfsexp_flags()
only ever need the cred out of rqstp, so pass it explicitly instead of
the whole rqstp.

This makes the interfaces cleaner.

Signed-off-by: NeilBrown <neilb@suse.de>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
NeilBrown 2024-07-26 12:21:31 +10:00 committed by Chuck Lever
parent c55aeef776
commit 9fd45c16f3
8 changed files with 34 additions and 28 deletions

View File

@ -5,26 +5,26 @@
#include "nfsd.h" #include "nfsd.h"
#include "auth.h" #include "auth.h"
int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp) int nfsexp_flags(struct svc_cred *cred, struct svc_export *exp)
{ {
struct exp_flavor_info *f; struct exp_flavor_info *f;
struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors; struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors;
for (f = exp->ex_flavors; f < end; f++) { for (f = exp->ex_flavors; f < end; f++) {
if (f->pseudoflavor == rqstp->rq_cred.cr_flavor) if (f->pseudoflavor == cred->cr_flavor)
return f->flags; return f->flags;
} }
return exp->ex_flags; return exp->ex_flags;
} }
int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) int nfsd_setuser(struct svc_cred *cred, struct svc_export *exp)
{ {
struct group_info *rqgi; struct group_info *rqgi;
struct group_info *gi; struct group_info *gi;
struct cred *new; struct cred *new;
int i; int i;
int flags = nfsexp_flags(rqstp, exp); int flags = nfsexp_flags(cred, exp);
/* discard any old override before preparing the new set */ /* discard any old override before preparing the new set */
revert_creds(get_cred(current_real_cred())); revert_creds(get_cred(current_real_cred()));
@ -32,10 +32,10 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
if (!new) if (!new)
return -ENOMEM; return -ENOMEM;
new->fsuid = rqstp->rq_cred.cr_uid; new->fsuid = cred->cr_uid;
new->fsgid = rqstp->rq_cred.cr_gid; new->fsgid = cred->cr_gid;
rqgi = rqstp->rq_cred.cr_group_info; rqgi = cred->cr_group_info;
if (flags & NFSEXP_ALLSQUASH) { if (flags & NFSEXP_ALLSQUASH) {
new->fsuid = exp->ex_anon_uid; new->fsuid = exp->ex_anon_uid;

View File

@ -12,6 +12,6 @@
* Set the current process's fsuid/fsgid etc to those of the NFS * Set the current process's fsuid/fsgid etc to those of the NFS
* client user * client user
*/ */
int nfsd_setuser(struct svc_rqst *, struct svc_export *); int nfsd_setuser(struct svc_cred *cred, struct svc_export *exp);
#endif /* LINUX_NFSD_AUTH_H */ #endif /* LINUX_NFSD_AUTH_H */

View File

@ -99,7 +99,8 @@ struct svc_expkey {
#define EX_NOHIDE(exp) ((exp)->ex_flags & NFSEXP_NOHIDE) #define EX_NOHIDE(exp) ((exp)->ex_flags & NFSEXP_NOHIDE)
#define EX_WGATHER(exp) ((exp)->ex_flags & NFSEXP_GATHERED_WRITES) #define EX_WGATHER(exp) ((exp)->ex_flags & NFSEXP_GATHERED_WRITES)
int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp); struct svc_cred;
int nfsexp_flags(struct svc_cred *cred, struct svc_export *exp);
__be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp); __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp);
/* /*

View File

@ -6891,7 +6891,8 @@ nfs4_check_file(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfs4_stid *s,
nf = nfs4_find_file(s, flags); nf = nfs4_find_file(s, flags);
if (nf) { if (nf) {
status = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, status = nfsd_permission(&rqstp->rq_cred,
fhp->fh_export, fhp->fh_dentry,
acc | NFSD_MAY_OWNER_OVERRIDE); acc | NFSD_MAY_OWNER_OVERRIDE);
if (status) { if (status) {
nfsd_file_put(nf); nfsd_file_put(nf);

View File

@ -102,7 +102,7 @@ static bool nfsd_originating_port_ok(struct svc_rqst *rqstp, int flags)
static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
struct svc_export *exp) struct svc_export *exp)
{ {
int flags = nfsexp_flags(rqstp, exp); int flags = nfsexp_flags(&rqstp->rq_cred, exp);
/* Check if the request originated from a secure port. */ /* Check if the request originated from a secure port. */
if (!nfsd_originating_port_ok(rqstp, flags)) { if (!nfsd_originating_port_ok(rqstp, flags)) {
@ -113,7 +113,7 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
} }
/* Set user creds for this exportpoint */ /* Set user creds for this exportpoint */
return nfserrno(nfsd_setuser(rqstp, exp)); return nfserrno(nfsd_setuser(&rqstp->rq_cred, exp));
} }
static inline __be32 check_pseudo_root(struct svc_rqst *rqstp, static inline __be32 check_pseudo_root(struct svc_rqst *rqstp,
@ -394,7 +394,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access)
skip_pseudoflavor_check: skip_pseudoflavor_check:
/* Finally, check access permissions. */ /* Finally, check access permissions. */
error = nfsd_permission(rqstp, exp, dentry, access); error = nfsd_permission(&rqstp->rq_cred, exp, dentry, access);
out: out:
trace_nfsd_fh_verify_err(rqstp, fhp, type, access, error); trace_nfsd_fh_verify_err(rqstp, fhp, type, access, error);
if (error == nfserr_stale) if (error == nfserr_stale)

View File

@ -331,10 +331,11 @@ nfsd_proc_create(struct svc_rqst *rqstp)
* echo thing > device-special-file-or-pipe * echo thing > device-special-file-or-pipe
* by doing a CREATE with type==0 * by doing a CREATE with type==0
*/ */
resp->status = nfsd_permission(rqstp, resp->status = nfsd_permission(
newfhp->fh_export, &rqstp->rq_cred,
newfhp->fh_dentry, newfhp->fh_export,
NFSD_MAY_WRITE|NFSD_MAY_LOCAL_ACCESS); newfhp->fh_dentry,
NFSD_MAY_WRITE|NFSD_MAY_LOCAL_ACCESS);
if (resp->status && resp->status != nfserr_rofs) if (resp->status && resp->status != nfserr_rofs)
goto out_unlock; goto out_unlock;
} }

View File

@ -421,8 +421,9 @@ nfsd_get_write_access(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (iap->ia_size < inode->i_size) { if (iap->ia_size < inode->i_size) {
__be32 err; __be32 err;
err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, err = nfsd_permission(&rqstp->rq_cred,
NFSD_MAY_TRUNC | NFSD_MAY_OWNER_OVERRIDE); fhp->fh_export, fhp->fh_dentry,
NFSD_MAY_TRUNC | NFSD_MAY_OWNER_OVERRIDE);
if (err) if (err)
return err; return err;
} }
@ -814,7 +815,8 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor
sresult |= map->access; sresult |= map->access;
err2 = nfsd_permission(rqstp, export, dentry, map->how); err2 = nfsd_permission(&rqstp->rq_cred, export,
dentry, map->how);
switch (err2) { switch (err2) {
case nfs_ok: case nfs_ok:
result |= map->access; result |= map->access;
@ -1475,7 +1477,8 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
dirp = d_inode(dentry); dirp = d_inode(dentry);
dchild = dget(resfhp->fh_dentry); dchild = dget(resfhp->fh_dentry);
err = nfsd_permission(rqstp, fhp->fh_export, dentry, NFSD_MAY_CREATE); err = nfsd_permission(&rqstp->rq_cred, fhp->fh_export, dentry,
NFSD_MAY_CREATE);
if (err) if (err)
goto out; goto out;
@ -2255,9 +2258,9 @@ nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, in
return err; return err;
} }
static int exp_rdonly(struct svc_rqst *rqstp, struct svc_export *exp) static int exp_rdonly(struct svc_cred *cred, struct svc_export *exp)
{ {
return nfsexp_flags(rqstp, exp) & NFSEXP_READONLY; return nfsexp_flags(cred, exp) & NFSEXP_READONLY;
} }
#ifdef CONFIG_NFSD_V4 #ifdef CONFIG_NFSD_V4
@ -2501,8 +2504,8 @@ out_unlock:
* Check for a user's access permissions to this inode. * Check for a user's access permissions to this inode.
*/ */
__be32 __be32
nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, nfsd_permission(struct svc_cred *cred, struct svc_export *exp,
struct dentry *dentry, int acc) struct dentry *dentry, int acc)
{ {
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
int err; int err;
@ -2533,7 +2536,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
*/ */
if (!(acc & NFSD_MAY_LOCAL_ACCESS)) if (!(acc & NFSD_MAY_LOCAL_ACCESS))
if (acc & (NFSD_MAY_WRITE | NFSD_MAY_SATTR | NFSD_MAY_TRUNC)) { if (acc & (NFSD_MAY_WRITE | NFSD_MAY_SATTR | NFSD_MAY_TRUNC)) {
if (exp_rdonly(rqstp, exp) || if (exp_rdonly(cred, exp) ||
__mnt_is_readonly(exp->ex_path.mnt)) __mnt_is_readonly(exp->ex_path.mnt))
return nfserr_rofs; return nfserr_rofs;
if (/* (acc & NFSD_MAY_WRITE) && */ IS_IMMUTABLE(inode)) if (/* (acc & NFSD_MAY_WRITE) && */ IS_IMMUTABLE(inode))

View File

@ -153,8 +153,8 @@ __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
struct kstatfs *, int access); struct kstatfs *, int access);
__be32 nfsd_permission(struct svc_rqst *, struct svc_export *, __be32 nfsd_permission(struct svc_cred *cred, struct svc_export *exp,
struct dentry *, int); struct dentry *dentry, int acc);
void nfsd_filp_close(struct file *fp); void nfsd_filp_close(struct file *fp);