Skip to content

Commit 6504d82

Browse files
committed
Merge tag 'nfs-for-5.20-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes from Trond Myklebust: - Fix SUNRPC call completion races with call_decode() that trigger a WARN_ON() - NFSv4.0 cannot support open-by-filehandle and NFS re-export - Revert "SUNRPC: Remove unreachable error condition" to allow handling of error conditions - Update suid/sgid mode bits after ALLOCATE and DEALLOCATE * tag 'nfs-for-5.20-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: Revert "SUNRPC: Remove unreachable error condition" NFSv4.2: Update mode bits after ALLOCATE and DEALLOCATE NFSv4: Turn off open-by-filehandle and NFS re-export for NFSv4.0 SUNRPC: Fix call completion races with call_decode()
2 parents 62d1cea + 13bd901 commit 6504d82

File tree

6 files changed

+57
-40
lines changed

6 files changed

+57
-40
lines changed

fs/nfs/internal.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,31 @@ static inline gfp_t nfs_io_gfp_mask(void)
606606
return GFP_KERNEL;
607607
}
608608

609+
/*
610+
* Special version of should_remove_suid() that ignores capabilities.
611+
*/
612+
static inline int nfs_should_remove_suid(const struct inode *inode)
613+
{
614+
umode_t mode = inode->i_mode;
615+
int kill = 0;
616+
617+
/* suid always must be killed */
618+
if (unlikely(mode & S_ISUID))
619+
kill = ATTR_KILL_SUID;
620+
621+
/*
622+
* sgid without any exec bits is just a mandatory locking mark; leave
623+
* it alone. If some exec bits are set, it's a real sgid; kill it.
624+
*/
625+
if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
626+
kill |= ATTR_KILL_SGID;
627+
628+
if (unlikely(kill && S_ISREG(mode)))
629+
return kill;
630+
631+
return 0;
632+
}
633+
609634
/* unlink.c */
610635
extern struct rpc_task *
611636
nfs_async_rename(struct inode *old_dir, struct inode *new_dir,

fs/nfs/nfs42proc.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,15 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
7878

7979
status = nfs4_call_sync(server->client, server, msg,
8080
&args.seq_args, &res.seq_res, 0);
81-
if (status == 0)
81+
if (status == 0) {
82+
if (nfs_should_remove_suid(inode)) {
83+
spin_lock(&inode->i_lock);
84+
nfs_set_cache_invalid(inode, NFS_INO_INVALID_MODE);
85+
spin_unlock(&inode->i_lock);
86+
}
8287
status = nfs_post_op_update_inode_force_wcc(inode,
8388
res.falloc_fattr);
84-
89+
}
8590
if (msg->rpc_proc == &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE])
8691
trace_nfs4_fallocate(inode, &args, status);
8792
else

fs/nfs/super.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,22 +1051,31 @@ static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx)
10511051
if (ctx->bsize)
10521052
sb->s_blocksize = nfs_block_size(ctx->bsize, &sb->s_blocksize_bits);
10531053

1054-
if (server->nfs_client->rpc_ops->version != 2) {
1055-
/* The VFS shouldn't apply the umask to mode bits. We will do
1056-
* so ourselves when necessary.
1054+
switch (server->nfs_client->rpc_ops->version) {
1055+
case 2:
1056+
sb->s_time_gran = 1000;
1057+
sb->s_time_min = 0;
1058+
sb->s_time_max = U32_MAX;
1059+
break;
1060+
case 3:
1061+
/*
1062+
* The VFS shouldn't apply the umask to mode bits.
1063+
* We will do so ourselves when necessary.
10571064
*/
10581065
sb->s_flags |= SB_POSIXACL;
10591066
sb->s_time_gran = 1;
1060-
sb->s_export_op = &nfs_export_ops;
1061-
} else
1062-
sb->s_time_gran = 1000;
1063-
1064-
if (server->nfs_client->rpc_ops->version != 4) {
10651067
sb->s_time_min = 0;
10661068
sb->s_time_max = U32_MAX;
1067-
} else {
1069+
sb->s_export_op = &nfs_export_ops;
1070+
break;
1071+
case 4:
1072+
sb->s_flags |= SB_POSIXACL;
1073+
sb->s_time_gran = 1;
10681074
sb->s_time_min = S64_MIN;
10691075
sb->s_time_max = S64_MAX;
1076+
if (server->caps & NFS_CAP_ATOMIC_OPEN_V1)
1077+
sb->s_export_op = &nfs_export_ops;
1078+
break;
10701079
}
10711080

10721081
sb->s_magic = NFS_SUPER_MAGIC;

fs/nfs/write.c

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,31 +1496,6 @@ void nfs_commit_prepare(struct rpc_task *task, void *calldata)
14961496
NFS_PROTO(data->inode)->commit_rpc_prepare(task, data);
14971497
}
14981498

1499-
/*
1500-
* Special version of should_remove_suid() that ignores capabilities.
1501-
*/
1502-
static int nfs_should_remove_suid(const struct inode *inode)
1503-
{
1504-
umode_t mode = inode->i_mode;
1505-
int kill = 0;
1506-
1507-
/* suid always must be killed */
1508-
if (unlikely(mode & S_ISUID))
1509-
kill = ATTR_KILL_SUID;
1510-
1511-
/*
1512-
* sgid without any exec bits is just a mandatory locking mark; leave
1513-
* it alone. If some exec bits are set, it's a real sgid; kill it.
1514-
*/
1515-
if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
1516-
kill |= ATTR_KILL_SGID;
1517-
1518-
if (unlikely(kill && S_ISREG(mode)))
1519-
return kill;
1520-
1521-
return 0;
1522-
}
1523-
15241499
static void nfs_writeback_check_extend(struct nfs_pgio_header *hdr,
15251500
struct nfs_fattr *fattr)
15261501
{

net/sunrpc/clnt.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2873,6 +2873,9 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
28732873

28742874
task = rpc_call_null_helper(clnt, xprt, NULL, RPC_TASK_ASYNC,
28752875
&rpc_cb_add_xprt_call_ops, data);
2876+
if (IS_ERR(task))
2877+
return PTR_ERR(task);
2878+
28762879
data->xps->xps_nunique_destaddr_xprts++;
28772880
rpc_put_task(task);
28782881
success:

net/sunrpc/xprt.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,11 +1179,8 @@ xprt_request_dequeue_receive_locked(struct rpc_task *task)
11791179
{
11801180
struct rpc_rqst *req = task->tk_rqstp;
11811181

1182-
if (test_and_clear_bit(RPC_TASK_NEED_RECV, &task->tk_runstate)) {
1182+
if (test_and_clear_bit(RPC_TASK_NEED_RECV, &task->tk_runstate))
11831183
xprt_request_rb_remove(req->rq_xprt, req);
1184-
xdr_free_bvec(&req->rq_rcv_buf);
1185-
req->rq_private_buf.bvec = NULL;
1186-
}
11871184
}
11881185

11891186
/**
@@ -1221,6 +1218,8 @@ void xprt_complete_rqst(struct rpc_task *task, int copied)
12211218

12221219
xprt->stat.recvs++;
12231220

1221+
xdr_free_bvec(&req->rq_rcv_buf);
1222+
req->rq_private_buf.bvec = NULL;
12241223
req->rq_private_buf.len = copied;
12251224
/* Ensure all writes are done before we update */
12261225
/* req->rq_reply_bytes_recvd */
@@ -1453,6 +1452,7 @@ xprt_request_dequeue_xprt(struct rpc_task *task)
14531452
xprt_request_dequeue_transmit_locked(task);
14541453
xprt_request_dequeue_receive_locked(task);
14551454
spin_unlock(&xprt->queue_lock);
1455+
xdr_free_bvec(&req->rq_rcv_buf);
14561456
}
14571457
}
14581458

0 commit comments

Comments
 (0)