diff options
-rw-r--r-- | fs/ksmbd/smb2pdu.c | 82 |
1 files changed, 45 insertions, 37 deletions
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 7e6e3d8c20e8..209e32e61a75 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -2768,8 +2768,13 @@ int smb2_open(struct ksmbd_work *work) if (!file_present) { rc = smb2_creat(work, &path, name, open_flags, posix_mode, req->CreateOptions & FILE_DIRECTORY_FILE_LE); - if (rc) + if (rc) { + if (rc == -ENOENT) { + rc = -EIO; + rsp->hdr.Status = STATUS_OBJECT_PATH_NOT_FOUND; + } goto err_out; + } created = true; user_ns = mnt_user_ns(path.mnt); @@ -6582,7 +6587,7 @@ int smb2_lock(struct ksmbd_work *work) int lock_count; int flags = 0; int cmd = 0; - int err = 0, i; + int err = -EIO, i, rc = 0; u64 lock_start, lock_length; struct ksmbd_lock *smb_lock = NULL, *cmp_lock, *tmp, *tmp2; struct ksmbd_conn *conn; @@ -6598,7 +6603,7 @@ int smb2_lock(struct ksmbd_work *work) if (!fp) { ksmbd_debug(SMB, "Invalid file id for lock : %llu\n", le64_to_cpu(req->VolatileFileId)); - rsp->hdr.Status = STATUS_FILE_CLOSED; + err = -ENOENT; goto out2; } @@ -6608,7 +6613,7 @@ int smb2_lock(struct ksmbd_work *work) ksmbd_debug(SMB, "lock count is %d\n", lock_count); if (!lock_count) { - rsp->hdr.Status = STATUS_INVALID_PARAMETER; + err = -EINVAL; goto out2; } @@ -6616,10 +6621,8 @@ int smb2_lock(struct ksmbd_work *work) flags = le32_to_cpu(lock_ele[i].Flags); flock = smb_flock_init(filp); - if (!flock) { - rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; + if (!flock) goto out; - } cmd = smb2_set_flock_flags(flock, flags); @@ -6657,8 +6660,7 @@ int smb2_lock(struct ksmbd_work *work) if (cmp_lock->fl->fl_type != F_UNLCK && flock->fl_type != F_UNLCK) { pr_err("conflict two locks in one request\n"); - rsp->hdr.Status = - STATUS_INVALID_PARAMETER; + err = -EINVAL; goto out; } } @@ -6666,19 +6668,19 @@ int smb2_lock(struct ksmbd_work *work) smb_lock = smb2_lock_init(flock, cmd, flags, &lock_list); if (!smb_lock) { - rsp->hdr.Status = STATUS_INVALID_PARAMETER; + err = -EINVAL; goto out; } } list_for_each_entry_safe(smb_lock, tmp, &lock_list, llist) { if (smb_lock->cmd < 0) { - rsp->hdr.Status = STATUS_INVALID_PARAMETER; + err = -EINVAL; goto out; } if (!(smb_lock->flags & SMB2_LOCKFLAG_MASK)) { - rsp->hdr.Status = STATUS_INVALID_PARAMETER; + err = -EINVAL; goto out; } @@ -6686,7 +6688,7 @@ int smb2_lock(struct ksmbd_work *work) smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) || (prior_lock == SMB2_LOCKFLAG_UNLOCK && !(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK))) { - rsp->hdr.Status = STATUS_INVALID_PARAMETER; + err = -EINVAL; goto out; } @@ -6739,8 +6741,7 @@ int smb2_lock(struct ksmbd_work *work) spin_unlock(&conn->llist_lock); read_unlock(&conn_list_lock); pr_err("previous lock conflict with zero byte lock range\n"); - rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; - goto out; + goto out; } if (smb_lock->zero_len && !cmp_lock->zero_len && @@ -6749,8 +6750,7 @@ int smb2_lock(struct ksmbd_work *work) spin_unlock(&conn->llist_lock); read_unlock(&conn_list_lock); pr_err("current lock conflict with zero byte lock range\n"); - rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; - goto out; + goto out; } if (((cmp_lock->start <= smb_lock->start && @@ -6761,8 +6761,6 @@ int smb2_lock(struct ksmbd_work *work) spin_unlock(&conn->llist_lock); read_unlock(&conn_list_lock); pr_err("Not allow lock operation on exclusive lock range\n"); - rsp->hdr.Status = - STATUS_LOCK_NOT_GRANTED; goto out; } } @@ -6785,19 +6783,19 @@ no_check_cl: flock = smb_lock->fl; list_del(&smb_lock->llist); retry: - err = vfs_lock_file(filp, smb_lock->cmd, flock, NULL); + rc = vfs_lock_file(filp, smb_lock->cmd, flock, NULL); skip: if (flags & SMB2_LOCKFLAG_UNLOCK) { - if (!err) { + if (!rc) { ksmbd_debug(SMB, "File unlocked\n"); - } else if (err == -ENOENT) { + } else if (rc == -ENOENT) { rsp->hdr.Status = STATUS_NOT_LOCKED; goto out; } locks_free_lock(flock); kfree(smb_lock); } else { - if (err == FILE_LOCK_DEFERRED) { + if (rc == FILE_LOCK_DEFERRED) { void **argv; ksmbd_debug(SMB, @@ -6815,12 +6813,11 @@ skip: } argv[0] = flock; - err = setup_async_work(work, - smb2_remove_blocked_lock, - argv); - if (err) { - rsp->hdr.Status = - STATUS_INSUFFICIENT_RESOURCES; + rc = setup_async_work(work, + smb2_remove_blocked_lock, + argv); + if (rc) { + err = -ENOMEM; goto out; } spin_lock(&fp->f_lock); @@ -6867,7 +6864,7 @@ skip: list_del(&work->fp_entry); spin_unlock(&fp->f_lock); goto retry; - } else if (!err) { + } else if (!rc) { spin_lock(&work->conn->llist_lock); list_add_tail(&smb_lock->clist, &work->conn->lock_list); @@ -6877,7 +6874,6 @@ skip: list_add(&smb_lock->llist, &rollback_list); ksmbd_debug(SMB, "successful in taking lock\n"); } else { - rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; } } @@ -6903,7 +6899,6 @@ out: list_for_each_entry_safe(smb_lock, tmp, &rollback_list, llist) { struct file_lock *rlock = NULL; - int rc; rlock = smb_flock_init(filp); rlock->fl_type = F_UNLCK; @@ -6926,7 +6921,19 @@ out: kfree(smb_lock); } out2: - ksmbd_debug(SMB, "failed in taking lock(flags : %x)\n", flags); + ksmbd_debug(SMB, "failed in taking lock(flags : %x), err : %d\n", flags, err); + + if (!rsp->hdr.Status) { + if (err == -EINVAL) + rsp->hdr.Status = STATUS_INVALID_PARAMETER; + else if (err == -ENOMEM) + rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; + else if (err == -ENOENT) + rsp->hdr.Status = STATUS_FILE_CLOSED; + else + rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; + } + smb2_set_err_rsp(work); ksmbd_fd_put(work, fp); return err; @@ -7071,6 +7078,7 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, struct sockaddr_storage_rsp *sockaddr_storage; unsigned int flags; unsigned long long speed; + struct sockaddr_in6 *csin6 = (struct sockaddr_in6 *)&conn->peer_addr; rtnl_lock(); for_each_netdev(&init_net, netdev) { @@ -7086,8 +7094,6 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, nii_rsp->IfIndex = cpu_to_le32(netdev->ifindex); nii_rsp->Capability = 0; - if (netdev->num_tx_queues > 1) - nii_rsp->Capability |= cpu_to_le32(RSS_CAPABLE); if (ksmbd_rdma_capable_netdev(netdev)) nii_rsp->Capability |= cpu_to_le32(RDMA_CAPABLE); @@ -7112,7 +7118,8 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, nii_rsp->SockAddr_Storage; memset(sockaddr_storage, 0, 128); - if (conn->peer_addr.ss_family == PF_INET) { + if (conn->peer_addr.ss_family == PF_INET || + ipv6_addr_v4mapped(&csin6->sin6_addr)) { struct in_device *idev; sockaddr_storage->Family = cpu_to_le16(INTERNETWORK); @@ -8147,7 +8154,8 @@ void smb3_set_sign_rsp(struct ksmbd_work *work) len = ALIGN(len, 8); } - if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) { + if (conn->binding == false && + le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) { signing_key = work->sess->smb3signingkey; } else { chann = lookup_chann_list(work->sess, work->conn); |