]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
smb3: fix broken cached reads when posix locks
authorSteve French <stfrench@microsoft.com>
Thu, 15 Aug 2024 23:31:36 +0000 (18:31 -0500)
committerSteve French <stfrench@microsoft.com>
Sun, 18 Aug 2024 22:01:06 +0000 (17:01 -0500)
Mandatory locking is enforced for cached reads, which violates
default posix semantics, and also it is enforced inconsistently.
This affected recent versions of libreoffice, and can be
demonstrated by opening a file twice from the same client,
locking it from handle one and trying to read from it from
handle two (which fails, returning EACCES).

There is already a mount option "forcemandatorylock"
(which defaults to off), so with this change only when the user
intentionally specifies "forcemandatorylock" on mount will we
break posix semantics on read to a locked range (ie we will
only fail in this case, if the user mounts with
"forcemandatorylock").

An earlier patch fixed the write path.

Fixes: 85160e03a79e ("CIFS: Implement caching mechanism for mandatory brlocks")
Cc: stable@vger.kernel.org
Cc: Pavel Shilovsky <piastryyy@gmail.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Reported-by: abartlet@samba.org
Reported-by: Kevin Ottens <kevin.ottens@enioka.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/file.c

index 1fc66bcf49eb45dd35a56b1dc408d01c92afb6bc..f9b302cb8233cfe7f547a813e2133fa34c70aa7b 100644 (file)
@@ -2912,9 +2912,7 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to)
        if (!CIFS_CACHE_READ(cinode))
                return netfs_unbuffered_read_iter(iocb, to);
 
-       if (cap_unix(tcon->ses) &&
-           (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
-           ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) {
+       if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) {
                if (iocb->ki_flags & IOCB_DIRECT)
                        return netfs_unbuffered_read_iter(iocb, to);
                return netfs_buffered_read_iter(iocb, to);