diff options
Diffstat (limited to 'fs/nfs/proc.c')
-rw-r--r-- | fs/nfs/proc.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 03599bfe81cf..5c35b02857f3 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
@@ -598,6 +598,29 @@ nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
598 | return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl); | 598 | return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl); |
599 | } | 599 | } |
600 | 600 | ||
601 | /* Helper functions for NFS lock bounds checking */ | ||
602 | #define NFS_LOCK32_OFFSET_MAX ((__s32)0x7fffffffUL) | ||
603 | static int nfs_lock_check_bounds(const struct file_lock *fl) | ||
604 | { | ||
605 | __s32 start, end; | ||
606 | |||
607 | start = (__s32)fl->fl_start; | ||
608 | if ((loff_t)start != fl->fl_start) | ||
609 | goto out_einval; | ||
610 | |||
611 | if (fl->fl_end != OFFSET_MAX) { | ||
612 | end = (__s32)fl->fl_end; | ||
613 | if ((loff_t)end != fl->fl_end) | ||
614 | goto out_einval; | ||
615 | } else | ||
616 | end = NFS_LOCK32_OFFSET_MAX; | ||
617 | |||
618 | if (start < 0 || start > end) | ||
619 | goto out_einval; | ||
620 | return 0; | ||
621 | out_einval: | ||
622 | return -EINVAL; | ||
623 | } | ||
601 | 624 | ||
602 | const struct nfs_rpc_ops nfs_v2_clientops = { | 625 | const struct nfs_rpc_ops nfs_v2_clientops = { |
603 | .version = 2, /* protocol version */ | 626 | .version = 2, /* protocol version */ |
@@ -633,4 +656,5 @@ const struct nfs_rpc_ops nfs_v2_clientops = { | |||
633 | .file_open = nfs_open, | 656 | .file_open = nfs_open, |
634 | .file_release = nfs_release, | 657 | .file_release = nfs_release, |
635 | .lock = nfs_proc_lock, | 658 | .lock = nfs_proc_lock, |
659 | .lock_check_bounds = nfs_lock_check_bounds, | ||
636 | }; | 660 | }; |