Merge branch 'for-4.1' of git://linux-nfs.org/~bfields/linux

Pull nfsd updates from Bruce Fields:
 "A quiet cycle this time; this is basically entirely bugfixes.

  The few that aren't cc'd to stable are cleanup or seemed unlikely to
  affect anyone much"

* 'for-4.1' of git://linux-nfs.org/~bfields/linux:
  uapi: Remove kernel internal declaration
  nfsd: fix nsfd startup race triggering BUG_ON
  nfsd: eliminate NFSD_DEBUG
  nfsd4: fix READ permission checking
  nfsd4: disallow SEEK with special stateids
  nfsd4: disallow ALLOCATE with special stateids
  nfsd: add NFSEXP_PNFS to the exflags array
  nfsd: Remove duplicate macro define for max sec label length
  nfsd: allow setting acls with unenforceable DENYs
  nfsd: NFSD_FAULT_INJECTION depends on DEBUG_FS
  nfsd: remove unused status arg to nfsd4_cleanup_open_state
  nfsd: remove bogus setting of status in nfsd4_process_open2
  NFSD: Use correct reply size calculating function
  NFSD: Using path_equal() for checking two paths
This commit is contained in:
Linus Torvalds 2015-04-24 07:46:05 -07:00
commit 860448cf76
14 changed files with 45 additions and 92 deletions

View File

@ -31,7 +31,7 @@
static struct hlist_head nlm_files[FILE_NRHASH];
static DEFINE_MUTEX(nlm_file_mutex);
#ifdef NFSD_DEBUG
#ifdef CONFIG_SUNRPC_DEBUG
static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)
{
u32 *fhp = (u32*)f->data;

View File

@ -108,7 +108,7 @@ config NFSD_V4_SECURITY_LABEL
config NFSD_FAULT_INJECTION
bool "NFS server manual fault injection"
depends on NFSD_V4 && DEBUG_KERNEL
depends on NFSD_V4 && DEBUG_KERNEL && DEBUG_FS
help
This option enables support for manually injecting faults
into the NFS server. This is intended to be used for

View File

@ -691,8 +691,7 @@ static int svc_export_match(struct cache_head *a, struct cache_head *b)
struct svc_export *orig = container_of(a, struct svc_export, h);
struct svc_export *new = container_of(b, struct svc_export, h);
return orig->ex_client == new->ex_client &&
orig->ex_path.dentry == new->ex_path.dentry &&
orig->ex_path.mnt == new->ex_path.mnt;
path_equal(&orig->ex_path, &new->ex_path);
}
static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
@ -1159,6 +1158,7 @@ static struct flags {
{ NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
{ NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
{ NFSEXP_V4ROOT, {"v4root", ""}},
{ NFSEXP_PNFS, {"pnfs", ""}},
{ 0, {"", ""}}
};

View File

@ -499,43 +499,13 @@ static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_s
state->mask.allow |= astate->allow;
}
/*
* Certain bits (SYNCHRONIZE, DELETE, WRITE_OWNER, READ/WRITE_NAMED_ATTRS,
* READ_ATTRIBUTES, READ_ACL) are currently unenforceable and don't translate
* to traditional read/write/execute permissions.
*
* It's problematic to reject acls that use certain mode bits, because it
* places the burden on users to learn the rules about which bits one
* particular server sets, without giving the user a lot of help--we return an
* error that could mean any number of different things. To make matters
* worse, the problematic bits might be introduced by some application that's
* automatically mapping from some other acl model.
*
* So wherever possible we accept anything, possibly erring on the side of
* denying more permissions than necessary.
*
* However we do reject *explicit* DENY's of a few bits representing
* permissions we could never deny:
*/
static inline int check_deny(u32 mask, int isowner)
{
if (mask & (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL))
return -EINVAL;
if (!isowner)
return 0;
if (mask & (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL))
return -EINVAL;
return 0;
}
static struct posix_acl *
posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
{
struct posix_acl_entry *pace;
struct posix_acl *pacl;
int nace;
int i, error = 0;
int i;
/*
* ACLs with no ACEs are treated differently in the inheritable
@ -560,17 +530,11 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
pace = pacl->a_entries;
pace->e_tag = ACL_USER_OBJ;
error = check_deny(state->owner.deny, 1);
if (error)
goto out_err;
low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags);
for (i=0; i < state->users->n; i++) {
pace++;
pace->e_tag = ACL_USER;
error = check_deny(state->users->aces[i].perms.deny, 0);
if (error)
goto out_err;
low_mode_from_nfs4(state->users->aces[i].perms.allow,
&pace->e_perm, flags);
pace->e_uid = state->users->aces[i].uid;
@ -579,18 +543,12 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
pace++;
pace->e_tag = ACL_GROUP_OBJ;
error = check_deny(state->group.deny, 0);
if (error)
goto out_err;
low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags);
add_to_mask(state, &state->group);
for (i=0; i < state->groups->n; i++) {
pace++;
pace->e_tag = ACL_GROUP;
error = check_deny(state->groups->aces[i].perms.deny, 0);
if (error)
goto out_err;
low_mode_from_nfs4(state->groups->aces[i].perms.allow,
&pace->e_perm, flags);
pace->e_gid = state->groups->aces[i].gid;
@ -605,15 +563,9 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
pace++;
pace->e_tag = ACL_OTHER;
error = check_deny(state->other.deny, 0);
if (error)
goto out_err;
low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags);
return pacl;
out_err:
posix_acl_release(pacl);
return ERR_PTR(error);
}
static inline void allow_bits(struct posix_ace_state *astate, u32 mask)

View File

@ -470,7 +470,7 @@ out:
fh_put(resfh);
kfree(resfh);
}
nfsd4_cleanup_open_state(cstate, open, status);
nfsd4_cleanup_open_state(cstate, open);
nfsd4_bump_seqid(cstate, status);
return status;
}
@ -1030,6 +1030,8 @@ nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n");
return status;
}
if (!file)
return nfserr_bad_stateid;
status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, file,
fallocate->falloc_offset,
@ -1069,6 +1071,8 @@ nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n");
return status;
}
if (!file)
return nfserr_bad_stateid;
switch (seek->seek_whence) {
case NFS4_CONTENT_DATA:
@ -1815,7 +1819,7 @@ static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp,
bmap0 &= ~FATTR4_WORD0_FILEHANDLE;
}
if (bmap2 & FATTR4_WORD2_SECURITY_LABEL) {
ret += NFSD4_MAX_SEC_LABEL_LEN + 12;
ret += NFS4_MAXLABELLEN + 12;
bmap2 &= ~FATTR4_WORD2_SECURITY_LABEL;
}
/*
@ -2282,13 +2286,13 @@ static struct nfsd4_operation nfsd4_ops[] = {
.op_func = (nfsd4op_func)nfsd4_allocate,
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
.op_name = "OP_ALLOCATE",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
},
[OP_DEALLOCATE] = {
.op_func = (nfsd4op_func)nfsd4_deallocate,
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
.op_name = "OP_DEALLOCATE",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
},
[OP_SEEK] = {
.op_func = (nfsd4op_func)nfsd4_seek,

View File

@ -1139,7 +1139,7 @@ hash_sessionid(struct nfs4_sessionid *sessionid)
return sid->sequence % SESSION_HASH_SIZE;
}
#ifdef NFSD_DEBUG
#ifdef CONFIG_SUNRPC_DEBUG
static inline void
dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
{
@ -4049,7 +4049,6 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
status = nfserr_bad_stateid;
if (nfsd4_is_deleg_cur(open))
goto out;
status = nfserr_jukebox;
}
/*
@ -4118,7 +4117,7 @@ out:
}
void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
struct nfsd4_open *open, __be32 status)
struct nfsd4_open *open)
{
if (open->op_openowner) {
struct nfs4_stateowner *so = &open->op_openowner->oo_owner;

View File

@ -424,7 +424,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
len += 4;
dummy32 = be32_to_cpup(p++);
READ_BUF(dummy32);
if (dummy32 > NFSD4_MAX_SEC_LABEL_LEN)
if (dummy32 > NFS4_MAXLABELLEN)
return nfserr_badlabel;
len += (XDR_QUADLEN(dummy32) << 2);
READMEM(buf, dummy32);
@ -2020,7 +2020,7 @@ static __be32 nfsd4_encode_path(struct xdr_stream *xdr,
* dentries/path components in an array.
*/
for (;;) {
if (cur.dentry == root->dentry && cur.mnt == root->mnt)
if (path_equal(&cur, root))
break;
if (cur.dentry == cur.mnt->mnt_root) {
if (follow_up(&cur))
@ -3422,6 +3422,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
unsigned long maxcount;
struct xdr_stream *xdr = &resp->xdr;
struct file *file = read->rd_filp;
struct svc_fh *fhp = read->rd_fhp;
int starting_len = xdr->buf->len;
struct raparms *ra;
__be32 *p;
@ -3445,12 +3446,15 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len));
maxcount = min_t(unsigned long, maxcount, read->rd_length);
if (!read->rd_filp) {
if (read->rd_filp)
err = nfsd_permission(resp->rqstp, fhp->fh_export,
fhp->fh_dentry,
NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
else
err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp,
&file, &ra);
if (err)
goto err_truncate;
}
if (err)
goto err_truncate;
if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
err = nfsd4_encode_splice_read(resp, read, file, maxcount);

View File

@ -1250,15 +1250,15 @@ static int __init init_nfsd(void)
int retval;
printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
retval = register_cld_notifier();
if (retval)
return retval;
retval = register_pernet_subsys(&nfsd_net_ops);
if (retval < 0)
goto out_unregister_notifier;
retval = nfsd4_init_slabs();
return retval;
retval = register_cld_notifier();
if (retval)
goto out_unregister_pernet;
retval = nfsd4_init_slabs();
if (retval)
goto out_unregister_notifier;
retval = nfsd4_init_pnfs();
if (retval)
goto out_free_slabs;
@ -1290,10 +1290,10 @@ out_exit_pnfs:
nfsd4_exit_pnfs();
out_free_slabs:
nfsd4_free_slabs();
out_unregister_pernet:
unregister_pernet_subsys(&nfsd_net_ops);
out_unregister_notifier:
unregister_cld_notifier();
out_unregister_pernet:
unregister_pernet_subsys(&nfsd_net_ops);
return retval;
}
@ -1308,8 +1308,8 @@ static void __exit exit_nfsd(void)
nfsd4_exit_pnfs();
nfsd_fault_inject_cleanup();
unregister_filesystem(&nfsd_fs_type);
unregister_pernet_subsys(&nfsd_net_ops);
unregister_cld_notifier();
unregister_pernet_subsys(&nfsd_net_ops);
}
MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");

View File

@ -24,7 +24,7 @@
#include "export.h"
#undef ifdebug
#ifdef NFSD_DEBUG
#ifdef CONFIG_SUNRPC_DEBUG
# define ifdebug(flag) if (nfsd_debug & NFSDDBG_##flag)
#else
# define ifdebug(flag) if (0)

View File

@ -40,7 +40,6 @@
#include "state.h"
#include "nfsd.h"
#define NFSD4_MAX_SEC_LABEL_LEN 2048
#define NFSD4_MAX_TAGLEN 128
#define XDR_LEN(n) (((n) + 3) & ~3)
@ -683,7 +682,7 @@ extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
struct svc_fh *current_fh, struct nfsd4_open *open);
extern void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate);
extern void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
struct nfsd4_open *open, __be32 status);
struct nfsd4_open *open);
extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc);
extern __be32 nfsd4_close(struct svc_rqst *rqstp,

View File

@ -16,6 +16,13 @@
#include <linux/uidgid.h>
#include <uapi/linux/nfs4.h>
enum nfs4_acl_whotype {
NFS4_ACL_WHO_NAMED = 0,
NFS4_ACL_WHO_OWNER,
NFS4_ACL_WHO_GROUP,
NFS4_ACL_WHO_EVERYONE,
};
struct nfs4_ace {
uint32_t type;
uint32_t flag;

View File

@ -162,13 +162,6 @@
*/
#define NFS4_MAX_BACK_CHANNEL_OPS 2
enum nfs4_acl_whotype {
NFS4_ACL_WHO_NAMED = 0,
NFS4_ACL_WHO_OWNER,
NFS4_ACL_WHO_GROUP,
NFS4_ACL_WHO_EVERYONE,
};
#endif /* _UAPI_LINUX_NFS4_H */
/*

View File

@ -11,14 +11,6 @@
#include <linux/sunrpc/debug.h>
/*
* Enable debugging for nfsd.
* Requires RPC_DEBUG.
*/
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
# define NFSD_DEBUG 1
#endif
/*
* knfsd debug flags
*/

View File

@ -21,6 +21,9 @@
/*
* Export flags.
*
* Please update the expflags[] array in fs/nfsd/export.c when adding
* a new flag.
*/
#define NFSEXP_READONLY 0x0001
#define NFSEXP_INSECURE_PORT 0x0002