summary refs log tree commit diff
path: root/fs
diff options
context:
space:
mode:
authorPaulo Alcantara <pc@cjr.nz>2022-08-08 13:41:18 -0300
committerSteve French <stfrench@microsoft.com>2022-08-10 16:45:37 -0500
commit773891ffd4d628d05c4e22f34541e4779ee7a076 (patch)
tree42897134dfe5cec61591ce8bca1d8c5ba1266ef0 /fs
parent0d168a58fca34806b575c7cba87afb11208acb54 (diff)
downloadlinux-773891ffd4d628d05c4e22f34541e4779ee7a076.tar.gz
cifs: fix lock length calculation
The lock length was wrongly set to 0 when fl_end == OFFSET_MAX, thus
failing to lock the whole file when l_start=0 and l_len=0.

This fixes test 2 from cthon04.

Before patch:

$ ./cthon04/lock/tlocklfs -t 2 /mnt

Creating parent/child synchronization pipes.

Test #1 - Test regions of an unlocked file.
        Parent: 1.1  - F_TEST  [               0,               1] PASSED.
        Parent: 1.2  - F_TEST  [               0,          ENDING] PASSED.
        Parent: 1.3  - F_TEST  [               0,7fffffffffffffff] PASSED.
        Parent: 1.4  - F_TEST  [               1,               1] PASSED.
        Parent: 1.5  - F_TEST  [               1,          ENDING] PASSED.
        Parent: 1.6  - F_TEST  [               1,7fffffffffffffff] PASSED.
        Parent: 1.7  - F_TEST  [7fffffffffffffff,               1] PASSED.
        Parent: 1.8  - F_TEST  [7fffffffffffffff,          ENDING] PASSED.
        Parent: 1.9  - F_TEST  [7fffffffffffffff,7fffffffffffffff] PASSED.

Test #2 - Try to lock the whole file.
        Parent: 2.0  - F_TLOCK [               0,          ENDING] PASSED.
        Child:  2.1  - F_TEST  [               0,               1] FAILED!
        Child:  **** Expected EACCES, returned success...
        Child:  **** Probably implementation error.

**  CHILD pass 1 results: 0/0 pass, 0/0 warn, 1/1 fail (pass/total).
        Parent: Child died

** PARENT pass 1 results: 10/10 pass, 0/0 warn, 0/0 fail (pass/total).

After patch:

$ ./cthon04/lock/tlocklfs -t 2 /mnt

Creating parent/child synchronization pipes.

Test #2 - Try to lock the whole file.
        Parent: 2.0  - F_TLOCK [               0,          ENDING] PASSED.
        Child:  2.1  - F_TEST  [               0,               1] PASSED.
        Child:  2.2  - F_TEST  [               0,          ENDING] PASSED.
        Child:  2.3  - F_TEST  [               0,7fffffffffffffff] PASSED.
        Child:  2.4  - F_TEST  [               1,               1] PASSED.
        Child:  2.5  - F_TEST  [               1,          ENDING] PASSED.
        Child:  2.6  - F_TEST  [               1,7fffffffffffffff] PASSED.
        Child:  2.7  - F_TEST  [7fffffffffffffff,               1] PASSED.
        Child:  2.8  - F_TEST  [7fffffffffffffff,          ENDING] PASSED.
        Child:  2.9  - F_TEST  [7fffffffffffffff,7fffffffffffffff] PASSED.
        Parent: 2.10 - F_ULOCK [               0,          ENDING] PASSED.

** PARENT pass 1 results: 2/2 pass, 0/0 warn, 0/0 fail (pass/total).

**  CHILD pass 1 results: 9/9 pass, 0/0 warn, 0/0 fail (pass/total).

Fixes: d80c69846ddf ("cifs: fix signed integer overflow when fl_end is OFFSET_MAX")
Reported-by: Xiaoli Feng <xifeng@redhat.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifsglob.h4
-rw-r--r--fs/cifs/file.c6
2 files changed, 5 insertions, 5 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 3070407cafa7..a93024eaf251 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -2132,9 +2132,9 @@ static inline bool cifs_is_referral_server(struct cifs_tcon *tcon,
 	return is_tcon_dfs(tcon) || (ref && (ref->flags & DFSREF_REFERRAL_SERVER));
 }
 
-static inline u64 cifs_flock_len(struct file_lock *fl)
+static inline u64 cifs_flock_len(const struct file_lock *fl)
 {
-	return fl->fl_end == OFFSET_MAX ? 0 : fl->fl_end - fl->fl_start + 1;
+	return (u64)fl->fl_end - fl->fl_start + 1;
 }
 
 static inline size_t ntlmssp_workstation_name_size(const struct cifs_ses *ses)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 85f2abcb2795..09975bd7d860 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1936,9 +1936,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
 	rc = -EACCES;
 	xid = get_xid();
 
-	cifs_dbg(FYI, "Lock parm: 0x%x flockflags: 0x%x flocktype: 0x%x start: %lld end: %lld\n",
-		 cmd, flock->fl_flags, flock->fl_type,
-		 flock->fl_start, flock->fl_end);
+	cifs_dbg(FYI, "%s: %pD2 cmd=0x%x type=0x%x flags=0x%x r=%lld:%lld\n", __func__, file, cmd,
+		 flock->fl_flags, flock->fl_type, (long long)flock->fl_start,
+		 (long long)flock->fl_end);
 
 	cfile = (struct cifsFileInfo *)file->private_data;
 	tcon = tlink_tcon(cfile->tlink);