Commit 732f3069 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag '5.19-rc4-ksmbd-server-fixes' of git://git.samba.org/ksmbd

Pull ksmbd server fixes from Steve French:

 - seek null check (don't use f_seek op directly and blindly)

 - offset validation in FSCTL_SET_ZERO_DATA

 - fallocate fix (relates e.g. to xfstests generic/091 and 263)

 - two cleanup fixes

 - fix socket settings on some arch

* tag '5.19-rc4-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: use vfs_llseek instead of dereferencing NULL
  ksmbd: check invalid FileOffset and BeyondFinalZero in FSCTL_ZERO_DATA
  ksmbd: set the range of bytes to zero without extending file size in FSCTL_ZERO_DATA
  ksmbd: remove duplicate flag set in smb2_write
  ksmbd: smbd: Remove useless license text when SPDX-License-Identifier is already used
  ksmbd: use SOCK_NONBLOCK type for kernel_accept()
parents 941e3e79 067baa9a
...@@ -6490,6 +6490,7 @@ int smb2_write(struct ksmbd_work *work) ...@@ -6490,6 +6490,7 @@ int smb2_write(struct ksmbd_work *work)
goto out; goto out;
} }
ksmbd_debug(SMB, "flags %u\n", le32_to_cpu(req->Flags));
if (le32_to_cpu(req->Flags) & SMB2_WRITEFLAG_WRITE_THROUGH) if (le32_to_cpu(req->Flags) & SMB2_WRITEFLAG_WRITE_THROUGH)
writethrough = true; writethrough = true;
...@@ -6505,10 +6506,6 @@ int smb2_write(struct ksmbd_work *work) ...@@ -6505,10 +6506,6 @@ int smb2_write(struct ksmbd_work *work)
data_buf = (char *)(((char *)&req->hdr.ProtocolId) + data_buf = (char *)(((char *)&req->hdr.ProtocolId) +
le16_to_cpu(req->DataOffset)); le16_to_cpu(req->DataOffset));
ksmbd_debug(SMB, "flags %u\n", le32_to_cpu(req->Flags));
if (le32_to_cpu(req->Flags) & SMB2_WRITEFLAG_WRITE_THROUGH)
writethrough = true;
ksmbd_debug(SMB, "filename %pd, offset %lld, len %zu\n", ksmbd_debug(SMB, "filename %pd, offset %lld, len %zu\n",
fp->filp->f_path.dentry, offset, length); fp->filp->f_path.dentry, offset, length);
err = ksmbd_vfs_write(work, fp, data_buf, length, &offset, err = ksmbd_vfs_write(work, fp, data_buf, length, &offset,
...@@ -7703,7 +7700,7 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7703,7 +7700,7 @@ int smb2_ioctl(struct ksmbd_work *work)
{ {
struct file_zero_data_information *zero_data; struct file_zero_data_information *zero_data;
struct ksmbd_file *fp; struct ksmbd_file *fp;
loff_t off, len; loff_t off, len, bfz;
if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
...@@ -7720,19 +7717,26 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7720,19 +7717,26 @@ int smb2_ioctl(struct ksmbd_work *work)
zero_data = zero_data =
(struct file_zero_data_information *)&req->Buffer[0]; (struct file_zero_data_information *)&req->Buffer[0];
fp = ksmbd_lookup_fd_fast(work, id); off = le64_to_cpu(zero_data->FileOffset);
if (!fp) { bfz = le64_to_cpu(zero_data->BeyondFinalZero);
ret = -ENOENT; if (off > bfz) {
ret = -EINVAL;
goto out; goto out;
} }
off = le64_to_cpu(zero_data->FileOffset); len = bfz - off;
len = le64_to_cpu(zero_data->BeyondFinalZero) - off; if (len) {
fp = ksmbd_lookup_fd_fast(work, id);
if (!fp) {
ret = -ENOENT;
goto out;
}
ret = ksmbd_vfs_zero_data(work, fp, off, len); ret = ksmbd_vfs_zero_data(work, fp, off, len);
ksmbd_fd_put(work, fp); ksmbd_fd_put(work, fp);
if (ret < 0) if (ret < 0)
goto out; goto out;
}
break; break;
} }
case FSCTL_QUERY_ALLOCATED_RANGES: case FSCTL_QUERY_ALLOCATED_RANGES:
......
...@@ -5,16 +5,6 @@ ...@@ -5,16 +5,6 @@
* *
* Author(s): Long Li <longli@microsoft.com>, * Author(s): Long Li <longli@microsoft.com>,
* Hyunchul Lee <hyc.lee@gmail.com> * Hyunchul Lee <hyc.lee@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*/ */
#define SUBMOD_NAME "smb_direct" #define SUBMOD_NAME "smb_direct"
......
...@@ -230,7 +230,7 @@ static int ksmbd_kthread_fn(void *p) ...@@ -230,7 +230,7 @@ static int ksmbd_kthread_fn(void *p)
break; break;
} }
ret = kernel_accept(iface->ksmbd_socket, &client_sk, ret = kernel_accept(iface->ksmbd_socket, &client_sk,
O_NONBLOCK); SOCK_NONBLOCK);
mutex_unlock(&iface->sock_release_lock); mutex_unlock(&iface->sock_release_lock);
if (ret) { if (ret) {
if (ret == -EAGAIN) if (ret == -EAGAIN)
......
...@@ -1015,7 +1015,9 @@ int ksmbd_vfs_zero_data(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -1015,7 +1015,9 @@ int ksmbd_vfs_zero_data(struct ksmbd_work *work, struct ksmbd_file *fp,
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
off, len); off, len);
return vfs_fallocate(fp->filp, FALLOC_FL_ZERO_RANGE, off, len); return vfs_fallocate(fp->filp,
FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE,
off, len);
} }
int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
...@@ -1046,7 +1048,7 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, ...@@ -1046,7 +1048,7 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
*out_count = 0; *out_count = 0;
end = start + length; end = start + length;
while (start < end && *out_count < in_count) { while (start < end && *out_count < in_count) {
extent_start = f->f_op->llseek(f, start, SEEK_DATA); extent_start = vfs_llseek(f, start, SEEK_DATA);
if (extent_start < 0) { if (extent_start < 0) {
if (extent_start != -ENXIO) if (extent_start != -ENXIO)
ret = (int)extent_start; ret = (int)extent_start;
...@@ -1056,7 +1058,7 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, ...@@ -1056,7 +1058,7 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
if (extent_start >= end) if (extent_start >= end)
break; break;
extent_end = f->f_op->llseek(f, extent_start, SEEK_HOLE); extent_end = vfs_llseek(f, extent_start, SEEK_HOLE);
if (extent_end < 0) { if (extent_end < 0) {
if (extent_end != -ENXIO) if (extent_end != -ENXIO)
ret = (int)extent_end; ret = (int)extent_end;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment