summaryrefslogtreecommitdiff
path: root/fs/smb/server/smb2pdu.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/smb/server/smb2pdu.c')
-rw-r--r--fs/smb/server/smb2pdu.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 95901a78951c..9c44e71e3c3b 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -4,6 +4,7 @@
* Copyright (C) 2018 Samsung Electronics Co., Ltd.
*/
+#include <crypto/utils.h>
#include <linux/inetdevice.h>
#include <net/addrconf.h>
#include <linux/syscalls.h>
@@ -125,6 +126,8 @@ int smb2_get_ksmbd_tcon(struct ksmbd_work *work)
pr_err("The first operation in the compound does not have tcon\n");
return -EINVAL;
}
+ if (work->tcon->t_state != TREE_CONNECTED)
+ return -ENOENT;
if (tree_id != UINT_MAX && work->tcon->id != tree_id) {
pr_err("tree id(%u) is different with id(%u) in first operation\n",
tree_id, work->tcon->id);
@@ -1947,6 +1950,7 @@ out_err:
}
}
smb2_set_err_rsp(work);
+ conn->binding = false;
} else {
unsigned int iov_len;
@@ -2827,7 +2831,11 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
goto out;
}
- dh_info->fp->conn = conn;
+ if (dh_info->fp->conn) {
+ ksmbd_put_durable_fd(dh_info->fp);
+ err = -EBADF;
+ goto out;
+ }
dh_info->reconnected = true;
goto out;
}
@@ -3011,13 +3019,14 @@ int smb2_open(struct ksmbd_work *work)
goto err_out2;
}
+ fp = dh_info.fp;
+
if (ksmbd_override_fsids(work)) {
rc = -ENOMEM;
ksmbd_put_durable_fd(dh_info.fp);
goto err_out2;
}
- fp = dh_info.fp;
file_info = FILE_OPENED;
rc = ksmbd_vfs_getattr(&fp->filp->f_path, &stat);
@@ -3615,10 +3624,8 @@ int smb2_open(struct ksmbd_work *work)
reconnected_fp:
rsp->StructureSize = cpu_to_le16(89);
- rcu_read_lock();
- opinfo = rcu_dereference(fp->f_opinfo);
+ opinfo = opinfo_get(fp);
rsp->OplockLevel = opinfo != NULL ? opinfo->level : 0;
- rcu_read_unlock();
rsp->Flags = 0;
rsp->CreateAction = cpu_to_le32(file_info);
rsp->CreationTime = cpu_to_le64(fp->create_time);
@@ -3659,6 +3666,7 @@ reconnected_fp:
next_ptr = &lease_ccontext->Next;
next_off = conn->vals->create_lease_size;
}
+ opinfo_put(opinfo);
if (maximal_access_ctxt) {
struct create_context *mxac_ccontext;
@@ -5451,7 +5459,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
struct smb2_query_info_req *req,
struct smb2_query_info_rsp *rsp)
{
- struct ksmbd_session *sess = work->sess;
struct ksmbd_conn *conn = work->conn;
struct ksmbd_share_config *share = work->tcon->share_conf;
int fsinfoclass = 0;
@@ -5588,10 +5595,11 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info = (struct object_id_info *)(rsp->Buffer);
- if (!user_guest(sess->user))
- memcpy(info->objid, user_passkey(sess->user), 16);
+ if (path.mnt->mnt_sb->s_uuid_len == 16)
+ memcpy(info->objid, path.mnt->mnt_sb->s_uuid.b,
+ path.mnt->mnt_sb->s_uuid_len);
else
- memset(info->objid, 0, 16);
+ memcpy(info->objid, &stfs.f_fsid, sizeof(stfs.f_fsid));
info->extended_info.magic = cpu_to_le32(EXTENDED_INFO_MAGIC);
info->extended_info.version = cpu_to_le32(1);
@@ -8880,7 +8888,7 @@ int smb2_check_sign_req(struct ksmbd_work *work)
ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, 1,
signature);
- if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
+ if (crypto_memneq(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
pr_err("bad smb2 signature\n");
return 0;
}
@@ -8968,7 +8976,7 @@ int smb3_check_sign_req(struct ksmbd_work *work)
if (ksmbd_sign_smb3_pdu(conn, signing_key, iov, 1, signature))
return 0;
- if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
+ if (crypto_memneq(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
pr_err("bad smb2 signature\n");
return 0;
}