FileOffset should not be greater than BeyondFinalZero in FSCTL_ZERO_DATA. And don't call ksmbd_vfs_zero_data() if length is zero.
Unified · Split
| @@ -7700,7 +7700,7 @@ int smb2_ioctl(struct ksmbd_work *work) · 7699 unmodified lines | ||
| 7700 | 7700 | { |
| 7701 | 7701 | struct file_zero_data_information *zero_data; |
| 7702 | 7702 | struct ksmbd_file *fp; |
| 7703 | − loff_t off, len; | |
| 7703 | + loff_t off, len, bfz; | |
| 7704 | 7704 | |
| 7705 | 7705 | if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { |
| 7706 | 7706 | ksmbd_debug(SMB, |
| @@ -7717,19 +7717,26 @@ int smb2_ioctl(struct ksmbd_work *work) · 10 unmodified lines | ||
| 7717 | 7717 | zero_data = |
| 7718 | 7718 | (struct file_zero_data_information *)&req->Buffer[0]; |
| 7719 | 7719 | |
| 7720 | − fp = ksmbd_lookup_fd_fast(work, id); | |
| 7721 | − if (!fp) { | |
| 7722 | − ret = -ENOENT; | |
| 7720 | + off = le64_to_cpu(zero_data->FileOffset); | |
| 7721 | + bfz = le64_to_cpu(zero_data->BeyondFinalZero); | |
| 7722 | + if (off > bfz) { | |
| 7723 | + ret = -EINVAL; | |
| 7723 | 7724 | goto out; |
| 7724 | 7725 | } |
| 7725 | 7726 | |
| 7726 | − off = le64_to_cpu(zero_data->FileOffset); | |
| 7727 | − len = le64_to_cpu(zero_data->BeyondFinalZero) - off; | |
| 7727 | + len = bfz - off; | |
| 7728 | + if (len) { | |
| 7729 | + fp = ksmbd_lookup_fd_fast(work, id); | |
| 7730 | + if (!fp) { | |
| 7731 | + ret = -ENOENT; | |
| 7732 | + goto out; | |
| 7733 | + } | |
| 7728 | 7734 | |
| 7729 | − ret = ksmbd_vfs_zero_data(work, fp, off, len); | |
| 7730 | − ksmbd_fd_put(work, fp); | |
| 7731 | − if (ret < 0) | |
| 7732 | − goto out; | |
| 7735 | + ret = ksmbd_vfs_zero_data(work, fp, off, len); | |
| 7736 | + ksmbd_fd_put(work, fp); | |
| 7737 | + if (ret < 0) | |
| 7738 | + goto out; | |
| 7739 | + } | |
| 7733 | 7740 | break; |
| 7734 | 7741 | } |
| 7735 | 7742 | case FSCTL_QUERY_ALLOCATED_RANGES: |