Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lockd: don't allow locking on reexported NFSv2/3

Since commit 9254c8ae9b81 ("nfsd: disallow file locking and delegations
for NFSv4 reexport"), file locking when reexporting an NFS mount via
NFSv4 is expressly prohibited by nfsd. Do the same in lockd:

Add a new nlmsvc_file_cannot_lock() helper that will test whether file
locking is allowed for a given file, and return nlm_lck_denied_nolocks
if it isn't.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Olga Kornievskaia <okorniev@redhat.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

authored by

Jeff Layton and committed by
Chuck Lever
898f9446 f6dcad1d

+26 -1
+12
fs/lockd/svclock.c
··· 495 495 (long long)lock->fl.fl_end, 496 496 wait); 497 497 498 + if (nlmsvc_file_cannot_lock(file)) 499 + return nlm_lck_denied_nolocks; 500 + 498 501 if (!locks_can_async_lock(nlmsvc_file_file(file)->f_op)) { 499 502 async_block = wait; 500 503 wait = 0; ··· 624 621 (long long)lock->fl.fl_start, 625 622 (long long)lock->fl.fl_end); 626 623 624 + if (nlmsvc_file_cannot_lock(file)) 625 + return nlm_lck_denied_nolocks; 626 + 627 627 if (locks_in_grace(SVC_NET(rqstp))) { 628 628 ret = nlm_lck_denied_grace_period; 629 629 goto out; ··· 684 678 (long long)lock->fl.fl_start, 685 679 (long long)lock->fl.fl_end); 686 680 681 + if (nlmsvc_file_cannot_lock(file)) 682 + return nlm_lck_denied_nolocks; 683 + 687 684 /* First, cancel any lock that might be there */ 688 685 nlmsvc_cancel_blocked(net, file, lock); 689 686 ··· 723 714 lock->fl.c.flc_pid, 724 715 (long long)lock->fl.fl_start, 725 716 (long long)lock->fl.fl_end); 717 + 718 + if (nlmsvc_file_cannot_lock(file)) 719 + return nlm_lck_denied_nolocks; 726 720 727 721 if (locks_in_grace(net)) 728 722 return nlm_lck_denied_grace_period;
+6
fs/lockd/svcshare.c
··· 32 32 struct xdr_netobj *oh = &argp->lock.oh; 33 33 u8 *ohdata; 34 34 35 + if (nlmsvc_file_cannot_lock(file)) 36 + return nlm_lck_denied_nolocks; 37 + 35 38 for (share = file->f_shares; share; share = share->s_next) { 36 39 if (share->s_host == host && nlm_cmp_owner(share, oh)) 37 40 goto update; ··· 74 71 { 75 72 struct nlm_share *share, **shpp; 76 73 struct xdr_netobj *oh = &argp->lock.oh; 74 + 75 + if (nlmsvc_file_cannot_lock(file)) 76 + return nlm_lck_denied_nolocks; 77 77 78 78 for (shpp = &file->f_shares; (share = *shpp) != NULL; 79 79 shpp = &share->s_next) {
+8 -1
include/linux/lockd/lockd.h
··· 12 12 13 13 /* XXX: a lot of this should really be under fs/lockd. */ 14 14 15 + #include <linux/exportfs.h> 15 16 #include <linux/in.h> 16 17 #include <linux/in6.h> 17 18 #include <net/ipv6.h> ··· 308 307 int nlmsvc_unlock_all_by_sb(struct super_block *sb); 309 308 int nlmsvc_unlock_all_by_ip(struct sockaddr *server_addr); 310 309 311 - static inline struct file *nlmsvc_file_file(struct nlm_file *file) 310 + static inline struct file *nlmsvc_file_file(const struct nlm_file *file) 312 311 { 313 312 return file->f_file[O_RDONLY] ? 314 313 file->f_file[O_RDONLY] : file->f_file[O_WRONLY]; ··· 317 316 static inline struct inode *nlmsvc_file_inode(struct nlm_file *file) 318 317 { 319 318 return file_inode(nlmsvc_file_file(file)); 319 + } 320 + 321 + static inline bool 322 + nlmsvc_file_cannot_lock(const struct nlm_file *file) 323 + { 324 + return exportfs_cannot_lock(nlmsvc_file_file(file)->f_path.dentry->d_sb->s_export_op); 320 325 } 321 326 322 327 static inline int __nlm_privileged_request4(const struct sockaddr *sap)