ten smb3 server fixes, including three for stable
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmP1kvMACgkQiiy9cAdy T1GwlQwAvFBHn8oUwDTj2bIlZRKsMMWGP61qdtgrsKPXcg2hZzw2jDmM6nk12MrS AqYCnT1YdjKzDnEgBhHnaPLe+q2M27feJ5Y+FTqv1Hb9VwNY9OJT4hH3II3cuHfm zLcnAAdVmtIh7FRYKrwGxqyESNik9N3g4evXcafKKq99sxaGnrnbTWQmOvTqM7kF 2AeBh6AHlHkoJNfd3BjlB8158Y/7Sfkul1AA7xXm6GWhgnWt2rmWNNqAEpTPXWyj xkcb3Jy0wez1D8IXRqyrZdqdFXIfri6mvJoun3zAll6f29T/xxz0CYZUDA881q6E EBANy/mLeMMKC4g3c2LPdEUB9ijwA9N+w8E7BSefCIMtN46cOQBTxYrbDfbCEs/m ElGo2AcOM25FrkMdl9XSX0Phru3OAOrOivVLCBqbGbHPa0lgBhIZOdy38HCK3ZGm 0eH6ttyE0p0Mpt1+kex1e6t8XfdyFkHk5gjPElWbsrhSQYK1AAWuBhETWZ79CSlx fCou/JZ1 =HBuN -----END PGP SIGNATURE----- Merge tag '6.3-rc-ksmbd-fixes' of git://git.samba.org/ksmbd Pull ksmbd server updates from Steve French: - Fix for memory leak - Two important fixes for frame length checks (which are also now stricter) - four minor cleanup fixes - Fix to clarify ksmbd/Kconfig to indent properl - Conversion of the channel list and rpc handle list to xarrays * tag '6.3-rc-ksmbd-fixes' of git://git.samba.org/ksmbd: ksmbd: fix possible memory leak in smb2_lock() ksmbd: do not allow the actual frame length to be smaller than the rfc1002 length ksmbd: fix wrong data area length for smb2 lock request ksmbd: Fix parameter name and comment mismatch ksmbd: Fix spelling mistake "excceed" -> "exceeded" ksmbd: update Kconfig to note Kerberos support and fix indentation ksmbd: Remove duplicated codes ksmbd: fix typo, syncronous->synchronous ksmbd: Implements sess->rpc_handle_list as xarray ksmbd: Implements sess->ksmbd_chann_list as xarray
This commit is contained in:
commit
25ac8c12ff
|
@ -33,14 +33,16 @@ config SMB_SERVER
|
|||
in ksmbd-tools, available from
|
||||
https://github.com/cifsd-team/ksmbd-tools.
|
||||
More detail about how to run the ksmbd kernel server is
|
||||
available via README file
|
||||
available via the README file
|
||||
(https://github.com/cifsd-team/ksmbd-tools/blob/master/README).
|
||||
|
||||
ksmbd kernel server includes support for auto-negotiation,
|
||||
Secure negotiate, Pre-authentication integrity, oplock/lease,
|
||||
compound requests, multi-credit, packet signing, RDMA(smbdirect),
|
||||
smb3 encryption, copy-offload, secure per-user session
|
||||
establishment via NTLM or NTLMv2.
|
||||
establishment via Kerberos or NTLMv2.
|
||||
|
||||
if SMB_SERVER
|
||||
|
||||
config SMB_SERVER_SMBDIRECT
|
||||
bool "Support for SMB Direct protocol"
|
||||
|
@ -54,6 +56,8 @@ config SMB_SERVER_SMBDIRECT
|
|||
SMB Direct allows transferring SMB packets over RDMA. If unsure,
|
||||
say N.
|
||||
|
||||
endif
|
||||
|
||||
config SMB_SERVER_CHECK_CAP_NET_ADMIN
|
||||
bool "Enable check network administration capability"
|
||||
depends on SMB_SERVER
|
||||
|
|
|
@ -208,9 +208,9 @@ int ksmbd_neg_token_init_mech_type(void *context, size_t hdrlen,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ksmbd_neg_token_init_mech_token(void *context, size_t hdrlen,
|
||||
unsigned char tag, const void *value,
|
||||
size_t vlen)
|
||||
static int ksmbd_neg_token_alloc(void *context, size_t hdrlen,
|
||||
unsigned char tag, const void *value,
|
||||
size_t vlen)
|
||||
{
|
||||
struct ksmbd_conn *conn = context;
|
||||
|
||||
|
@ -223,17 +223,16 @@ int ksmbd_neg_token_init_mech_token(void *context, size_t hdrlen,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ksmbd_neg_token_init_mech_token(void *context, size_t hdrlen,
|
||||
unsigned char tag, const void *value,
|
||||
size_t vlen)
|
||||
{
|
||||
return ksmbd_neg_token_alloc(context, hdrlen, tag, value, vlen);
|
||||
}
|
||||
|
||||
int ksmbd_neg_token_targ_resp_token(void *context, size_t hdrlen,
|
||||
unsigned char tag, const void *value,
|
||||
size_t vlen)
|
||||
{
|
||||
struct ksmbd_conn *conn = context;
|
||||
|
||||
conn->mechToken = kmalloc(vlen + 1, GFP_KERNEL);
|
||||
if (!conn->mechToken)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(conn->mechToken, value, vlen);
|
||||
conn->mechToken[vlen] = '\0';
|
||||
return 0;
|
||||
return ksmbd_neg_token_alloc(context, hdrlen, tag, value, vlen);
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ void ksmbd_conn_enqueue_request(struct ksmbd_work *work)
|
|||
|
||||
if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE) {
|
||||
requests_queue = &conn->requests;
|
||||
work->syncronous = true;
|
||||
work->synchronous = true;
|
||||
}
|
||||
|
||||
if (requests_queue) {
|
||||
|
@ -139,7 +139,7 @@ int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work)
|
|||
spin_lock(&conn->request_lock);
|
||||
if (!work->multiRsp) {
|
||||
list_del_init(&work->request_entry);
|
||||
if (work->syncronous == false)
|
||||
if (!work->synchronous)
|
||||
list_del_init(&work->async_request_entry);
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -312,7 +312,7 @@ int ksmbd_conn_handler_loop(void *p)
|
|||
max_allowed_pdu_size = SMB3_MAX_MSGSIZE;
|
||||
|
||||
if (pdu_size > max_allowed_pdu_size) {
|
||||
pr_err_ratelimited("PDU length(%u) excceed maximum allowed pdu size(%u) on connection(%d)\n",
|
||||
pr_err_ratelimited("PDU length(%u) exceeded maximum allowed pdu size(%u) on connection(%d)\n",
|
||||
pdu_size, max_allowed_pdu_size,
|
||||
conn->status);
|
||||
break;
|
||||
|
|
|
@ -68,7 +68,7 @@ struct ksmbd_work {
|
|||
/* Request is encrypted */
|
||||
bool encrypted:1;
|
||||
/* Is this SYNC or ASYNC ksmbd_work */
|
||||
bool syncronous:1;
|
||||
bool synchronous:1;
|
||||
bool need_invalidate_rkey:1;
|
||||
|
||||
unsigned int remote_key;
|
||||
|
|
|
@ -25,20 +25,19 @@ static DECLARE_RWSEM(sessions_table_lock);
|
|||
struct ksmbd_session_rpc {
|
||||
int id;
|
||||
unsigned int method;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static void free_channel_list(struct ksmbd_session *sess)
|
||||
{
|
||||
struct channel *chann, *tmp;
|
||||
struct channel *chann;
|
||||
unsigned long index;
|
||||
|
||||
write_lock(&sess->chann_lock);
|
||||
list_for_each_entry_safe(chann, tmp, &sess->ksmbd_chann_list,
|
||||
chann_list) {
|
||||
list_del(&chann->chann_list);
|
||||
xa_for_each(&sess->ksmbd_chann_list, index, chann) {
|
||||
xa_erase(&sess->ksmbd_chann_list, index);
|
||||
kfree(chann);
|
||||
}
|
||||
write_unlock(&sess->chann_lock);
|
||||
|
||||
xa_destroy(&sess->ksmbd_chann_list);
|
||||
}
|
||||
|
||||
static void __session_rpc_close(struct ksmbd_session *sess,
|
||||
|
@ -58,15 +57,14 @@ static void __session_rpc_close(struct ksmbd_session *sess,
|
|||
static void ksmbd_session_rpc_clear_list(struct ksmbd_session *sess)
|
||||
{
|
||||
struct ksmbd_session_rpc *entry;
|
||||
long index;
|
||||
|
||||
while (!list_empty(&sess->rpc_handle_list)) {
|
||||
entry = list_entry(sess->rpc_handle_list.next,
|
||||
struct ksmbd_session_rpc,
|
||||
list);
|
||||
|
||||
list_del(&entry->list);
|
||||
xa_for_each(&sess->rpc_handle_list, index, entry) {
|
||||
xa_erase(&sess->rpc_handle_list, index);
|
||||
__session_rpc_close(sess, entry);
|
||||
}
|
||||
|
||||
xa_destroy(&sess->rpc_handle_list);
|
||||
}
|
||||
|
||||
static int __rpc_method(char *rpc_name)
|
||||
|
@ -102,13 +100,13 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
|
|||
|
||||
entry = kzalloc(sizeof(struct ksmbd_session_rpc), GFP_KERNEL);
|
||||
if (!entry)
|
||||
return -EINVAL;
|
||||
return -ENOMEM;
|
||||
|
||||
list_add(&entry->list, &sess->rpc_handle_list);
|
||||
entry->method = method;
|
||||
entry->id = ksmbd_ipc_id_alloc();
|
||||
if (entry->id < 0)
|
||||
goto free_entry;
|
||||
xa_store(&sess->rpc_handle_list, entry->id, entry, GFP_KERNEL);
|
||||
|
||||
resp = ksmbd_rpc_open(sess, entry->id);
|
||||
if (!resp)
|
||||
|
@ -117,9 +115,9 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
|
|||
kvfree(resp);
|
||||
return entry->id;
|
||||
free_id:
|
||||
xa_erase(&sess->rpc_handle_list, entry->id);
|
||||
ksmbd_rpc_id_free(entry->id);
|
||||
free_entry:
|
||||
list_del(&entry->list);
|
||||
kfree(entry);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -128,24 +126,17 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id)
|
|||
{
|
||||
struct ksmbd_session_rpc *entry;
|
||||
|
||||
list_for_each_entry(entry, &sess->rpc_handle_list, list) {
|
||||
if (entry->id == id) {
|
||||
list_del(&entry->list);
|
||||
__session_rpc_close(sess, entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
entry = xa_erase(&sess->rpc_handle_list, id);
|
||||
if (entry)
|
||||
__session_rpc_close(sess, entry);
|
||||
}
|
||||
|
||||
int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
|
||||
{
|
||||
struct ksmbd_session_rpc *entry;
|
||||
|
||||
list_for_each_entry(entry, &sess->rpc_handle_list, list) {
|
||||
if (entry->id == id)
|
||||
return entry->method;
|
||||
}
|
||||
return 0;
|
||||
entry = xa_load(&sess->rpc_handle_list, id);
|
||||
return entry ? entry->method : 0;
|
||||
}
|
||||
|
||||
void ksmbd_session_destroy(struct ksmbd_session *sess)
|
||||
|
@ -190,21 +181,15 @@ int ksmbd_session_register(struct ksmbd_conn *conn,
|
|||
|
||||
static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess)
|
||||
{
|
||||
struct channel *chann, *tmp;
|
||||
struct channel *chann;
|
||||
|
||||
write_lock(&sess->chann_lock);
|
||||
list_for_each_entry_safe(chann, tmp, &sess->ksmbd_chann_list,
|
||||
chann_list) {
|
||||
if (chann->conn == conn) {
|
||||
list_del(&chann->chann_list);
|
||||
kfree(chann);
|
||||
write_unlock(&sess->chann_lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
write_unlock(&sess->chann_lock);
|
||||
chann = xa_erase(&sess->ksmbd_chann_list, (long)conn);
|
||||
if (!chann)
|
||||
return -ENOENT;
|
||||
|
||||
return -ENOENT;
|
||||
kfree(chann);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
|
||||
|
@ -234,7 +219,7 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
|
|||
return;
|
||||
|
||||
sess_destroy:
|
||||
if (list_empty(&sess->ksmbd_chann_list)) {
|
||||
if (xa_empty(&sess->ksmbd_chann_list)) {
|
||||
xa_erase(&conn->sessions, sess->id);
|
||||
ksmbd_session_destroy(sess);
|
||||
}
|
||||
|
@ -320,6 +305,9 @@ static struct ksmbd_session *__session_create(int protocol)
|
|||
struct ksmbd_session *sess;
|
||||
int ret;
|
||||
|
||||
if (protocol != CIFDS_SESSION_FLAG_SMB2)
|
||||
return NULL;
|
||||
|
||||
sess = kzalloc(sizeof(struct ksmbd_session), GFP_KERNEL);
|
||||
if (!sess)
|
||||
return NULL;
|
||||
|
@ -329,30 +317,20 @@ static struct ksmbd_session *__session_create(int protocol)
|
|||
|
||||
set_session_flag(sess, protocol);
|
||||
xa_init(&sess->tree_conns);
|
||||
INIT_LIST_HEAD(&sess->ksmbd_chann_list);
|
||||
INIT_LIST_HEAD(&sess->rpc_handle_list);
|
||||
xa_init(&sess->ksmbd_chann_list);
|
||||
xa_init(&sess->rpc_handle_list);
|
||||
sess->sequence_number = 1;
|
||||
rwlock_init(&sess->chann_lock);
|
||||
|
||||
switch (protocol) {
|
||||
case CIFDS_SESSION_FLAG_SMB2:
|
||||
ret = __init_smb2_session(sess);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = __init_smb2_session(sess);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ida_init(&sess->tree_conn_ida);
|
||||
|
||||
if (protocol == CIFDS_SESSION_FLAG_SMB2) {
|
||||
down_write(&sessions_table_lock);
|
||||
hash_add(sessions_table, &sess->hlist, sess->id);
|
||||
up_write(&sessions_table_lock);
|
||||
}
|
||||
down_write(&sessions_table_lock);
|
||||
hash_add(sessions_table, &sess->hlist, sess->id);
|
||||
up_write(&sessions_table_lock);
|
||||
|
||||
return sess;
|
||||
|
||||
error:
|
||||
|
|
|
@ -21,7 +21,6 @@ struct ksmbd_file_table;
|
|||
struct channel {
|
||||
__u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];
|
||||
struct ksmbd_conn *conn;
|
||||
struct list_head chann_list;
|
||||
};
|
||||
|
||||
struct preauth_session {
|
||||
|
@ -50,11 +49,10 @@ struct ksmbd_session {
|
|||
char sess_key[CIFS_KEY_SIZE];
|
||||
|
||||
struct hlist_node hlist;
|
||||
rwlock_t chann_lock;
|
||||
struct list_head ksmbd_chann_list;
|
||||
struct xarray ksmbd_chann_list;
|
||||
struct xarray tree_conns;
|
||||
struct ida tree_conn_ida;
|
||||
struct list_head rpc_handle_list;
|
||||
struct xarray rpc_handle_list;
|
||||
|
||||
__u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE];
|
||||
__u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE];
|
||||
|
|
|
@ -149,15 +149,11 @@ static int smb2_get_data_area_len(unsigned int *off, unsigned int *len,
|
|||
break;
|
||||
case SMB2_LOCK:
|
||||
{
|
||||
int lock_count;
|
||||
unsigned short lock_count;
|
||||
|
||||
/*
|
||||
* smb2_lock request size is 48 included single
|
||||
* smb2_lock_element structure size.
|
||||
*/
|
||||
lock_count = le16_to_cpu(((struct smb2_lock_req *)hdr)->LockCount) - 1;
|
||||
lock_count = le16_to_cpu(((struct smb2_lock_req *)hdr)->LockCount);
|
||||
if (lock_count > 0) {
|
||||
*off = __SMB2_HEADER_STRUCTURE_SIZE + 48;
|
||||
*off = offsetof(struct smb2_lock_req, locks);
|
||||
*len = sizeof(struct smb2_lock_element) * lock_count;
|
||||
}
|
||||
break;
|
||||
|
@ -412,20 +408,19 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
|
|||
goto validate_credit;
|
||||
|
||||
/*
|
||||
* windows client also pad up to 8 bytes when compounding.
|
||||
* If pad is longer than eight bytes, log the server behavior
|
||||
* (once), since may indicate a problem but allow it and
|
||||
* continue since the frame is parseable.
|
||||
* SMB2 NEGOTIATE request will be validated when message
|
||||
* handling proceeds.
|
||||
*/
|
||||
if (clc_len < len) {
|
||||
ksmbd_debug(SMB,
|
||||
"cli req padded more than expected. Length %d not %d for cmd:%d mid:%llu\n",
|
||||
len, clc_len, command,
|
||||
le64_to_cpu(hdr->MessageId));
|
||||
if (command == SMB2_NEGOTIATE_HE)
|
||||
goto validate_credit;
|
||||
}
|
||||
|
||||
ksmbd_debug(SMB,
|
||||
/*
|
||||
* Allow a message that padded to 8byte boundary.
|
||||
*/
|
||||
if (clc_len < len && (len - clc_len) < 8)
|
||||
goto validate_credit;
|
||||
|
||||
pr_err_ratelimited(
|
||||
"cli req too short, len %d not %d. cmd:%d mid:%llu\n",
|
||||
len, clc_len, command,
|
||||
le64_to_cpu(hdr->MessageId));
|
||||
|
|
|
@ -75,14 +75,7 @@ static inline bool check_session_id(struct ksmbd_conn *conn, u64 id)
|
|||
|
||||
struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn *conn)
|
||||
{
|
||||
struct channel *chann;
|
||||
|
||||
list_for_each_entry(chann, &sess->ksmbd_chann_list, chann_list) {
|
||||
if (chann->conn == conn)
|
||||
return chann;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return xa_load(&sess->ksmbd_chann_list, (long)conn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -506,7 +499,7 @@ int init_smb2_rsp_hdr(struct ksmbd_work *work)
|
|||
rsp_hdr->SessionId = rcv_hdr->SessionId;
|
||||
memcpy(rsp_hdr->Signature, rcv_hdr->Signature, 16);
|
||||
|
||||
work->syncronous = true;
|
||||
work->synchronous = true;
|
||||
if (work->async_id) {
|
||||
ksmbd_release_id(&conn->async_ida, work->async_id);
|
||||
work->async_id = 0;
|
||||
|
@ -596,6 +589,7 @@ static void destroy_previous_session(struct ksmbd_conn *conn,
|
|||
struct ksmbd_session *prev_sess = ksmbd_session_lookup_slowpath(id);
|
||||
struct ksmbd_user *prev_user;
|
||||
struct channel *chann;
|
||||
long index;
|
||||
|
||||
if (!prev_sess)
|
||||
return;
|
||||
|
@ -609,10 +603,8 @@ static void destroy_previous_session(struct ksmbd_conn *conn,
|
|||
return;
|
||||
|
||||
prev_sess->state = SMB2_SESSION_EXPIRED;
|
||||
write_lock(&prev_sess->chann_lock);
|
||||
list_for_each_entry(chann, &prev_sess->ksmbd_chann_list, chann_list)
|
||||
xa_for_each(&prev_sess->ksmbd_chann_list, index, chann)
|
||||
chann->conn->status = KSMBD_SESS_EXITING;
|
||||
write_unlock(&prev_sess->chann_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -653,7 +645,7 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg)
|
|||
pr_err("Failed to alloc async message id\n");
|
||||
return id;
|
||||
}
|
||||
work->syncronous = false;
|
||||
work->synchronous = false;
|
||||
work->async_id = id;
|
||||
rsp_hdr->Id.AsyncId = cpu_to_le64(id);
|
||||
|
||||
|
@ -1520,19 +1512,14 @@ static int ntlm_authenticate(struct ksmbd_work *work)
|
|||
|
||||
binding_session:
|
||||
if (conn->dialect >= SMB30_PROT_ID) {
|
||||
read_lock(&sess->chann_lock);
|
||||
chann = lookup_chann_list(sess, conn);
|
||||
read_unlock(&sess->chann_lock);
|
||||
if (!chann) {
|
||||
chann = kmalloc(sizeof(struct channel), GFP_KERNEL);
|
||||
if (!chann)
|
||||
return -ENOMEM;
|
||||
|
||||
chann->conn = conn;
|
||||
INIT_LIST_HEAD(&chann->chann_list);
|
||||
write_lock(&sess->chann_lock);
|
||||
list_add(&chann->chann_list, &sess->ksmbd_chann_list);
|
||||
write_unlock(&sess->chann_lock);
|
||||
xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1607,19 +1594,14 @@ static int krb5_authenticate(struct ksmbd_work *work)
|
|||
}
|
||||
|
||||
if (conn->dialect >= SMB30_PROT_ID) {
|
||||
read_lock(&sess->chann_lock);
|
||||
chann = lookup_chann_list(sess, conn);
|
||||
read_unlock(&sess->chann_lock);
|
||||
if (!chann) {
|
||||
chann = kmalloc(sizeof(struct channel), GFP_KERNEL);
|
||||
if (!chann)
|
||||
return -ENOMEM;
|
||||
|
||||
chann->conn = conn;
|
||||
INIT_LIST_HEAD(&chann->chann_list);
|
||||
write_lock(&sess->chann_lock);
|
||||
list_add(&chann->chann_list, &sess->ksmbd_chann_list);
|
||||
write_unlock(&sess->chann_lock);
|
||||
xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6645,7 +6627,7 @@ int smb2_cancel(struct ksmbd_work *work)
|
|||
struct ksmbd_conn *conn = work->conn;
|
||||
struct smb2_hdr *hdr = smb2_get_msg(work->request_buf);
|
||||
struct smb2_hdr *chdr;
|
||||
struct ksmbd_work *cancel_work = NULL, *iter;
|
||||
struct ksmbd_work *iter;
|
||||
struct list_head *command_list;
|
||||
|
||||
ksmbd_debug(SMB, "smb2 cancel called on mid %llu, async flags 0x%x\n",
|
||||
|
@ -6667,7 +6649,9 @@ int smb2_cancel(struct ksmbd_work *work)
|
|||
"smb2 with AsyncId %llu cancelled command = 0x%x\n",
|
||||
le64_to_cpu(hdr->Id.AsyncId),
|
||||
le16_to_cpu(chdr->Command));
|
||||
cancel_work = iter;
|
||||
iter->state = KSMBD_WORK_CANCELLED;
|
||||
if (iter->cancel_fn)
|
||||
iter->cancel_fn(iter->cancel_argv);
|
||||
break;
|
||||
}
|
||||
spin_unlock(&conn->request_lock);
|
||||
|
@ -6686,18 +6670,12 @@ int smb2_cancel(struct ksmbd_work *work)
|
|||
"smb2 with mid %llu cancelled command = 0x%x\n",
|
||||
le64_to_cpu(hdr->MessageId),
|
||||
le16_to_cpu(chdr->Command));
|
||||
cancel_work = iter;
|
||||
iter->state = KSMBD_WORK_CANCELLED;
|
||||
break;
|
||||
}
|
||||
spin_unlock(&conn->request_lock);
|
||||
}
|
||||
|
||||
if (cancel_work) {
|
||||
cancel_work->state = KSMBD_WORK_CANCELLED;
|
||||
if (cancel_work->cancel_fn)
|
||||
cancel_work->cancel_fn(cancel_work->cancel_argv);
|
||||
}
|
||||
|
||||
/* For SMB2_CANCEL command itself send no response*/
|
||||
work->send_no_response = 1;
|
||||
return 0;
|
||||
|
@ -7062,6 +7040,14 @@ skip:
|
|||
|
||||
ksmbd_vfs_posix_lock_wait(flock);
|
||||
|
||||
spin_lock(&work->conn->request_lock);
|
||||
spin_lock(&fp->f_lock);
|
||||
list_del(&work->fp_entry);
|
||||
work->cancel_fn = NULL;
|
||||
kfree(argv);
|
||||
spin_unlock(&fp->f_lock);
|
||||
spin_unlock(&work->conn->request_lock);
|
||||
|
||||
if (work->state != KSMBD_WORK_ACTIVE) {
|
||||
list_del(&smb_lock->llist);
|
||||
spin_lock(&work->conn->llist_lock);
|
||||
|
@ -7070,9 +7056,6 @@ skip:
|
|||
locks_free_lock(flock);
|
||||
|
||||
if (work->state == KSMBD_WORK_CANCELLED) {
|
||||
spin_lock(&fp->f_lock);
|
||||
list_del(&work->fp_entry);
|
||||
spin_unlock(&fp->f_lock);
|
||||
rsp->hdr.Status =
|
||||
STATUS_CANCELLED;
|
||||
kfree(smb_lock);
|
||||
|
@ -7094,9 +7077,6 @@ skip:
|
|||
list_del(&smb_lock->clist);
|
||||
spin_unlock(&work->conn->llist_lock);
|
||||
|
||||
spin_lock(&fp->f_lock);
|
||||
list_del(&work->fp_entry);
|
||||
spin_unlock(&fp->f_lock);
|
||||
goto retry;
|
||||
} else if (!rc) {
|
||||
spin_lock(&work->conn->llist_lock);
|
||||
|
@ -8410,14 +8390,11 @@ int smb3_check_sign_req(struct ksmbd_work *work)
|
|||
if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
|
||||
signing_key = work->sess->smb3signingkey;
|
||||
} else {
|
||||
read_lock(&work->sess->chann_lock);
|
||||
chann = lookup_chann_list(work->sess, conn);
|
||||
if (!chann) {
|
||||
read_unlock(&work->sess->chann_lock);
|
||||
return 0;
|
||||
}
|
||||
signing_key = chann->smb3signingkey;
|
||||
read_unlock(&work->sess->chann_lock);
|
||||
}
|
||||
|
||||
if (!signing_key) {
|
||||
|
@ -8477,14 +8454,11 @@ void smb3_set_sign_rsp(struct ksmbd_work *work)
|
|||
le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
|
||||
signing_key = work->sess->smb3signingkey;
|
||||
} else {
|
||||
read_lock(&work->sess->chann_lock);
|
||||
chann = lookup_chann_list(work->sess, work->conn);
|
||||
if (!chann) {
|
||||
read_unlock(&work->sess->chann_lock);
|
||||
return;
|
||||
}
|
||||
signing_key = chann->smb3signingkey;
|
||||
read_unlock(&work->sess->chann_lock);
|
||||
}
|
||||
|
||||
if (!signing_key)
|
||||
|
|
|
@ -952,9 +952,9 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,
|
|||
* ksmbd_vfs_setxattr() - vfs helper for smb set extended attributes value
|
||||
* @idmap: idmap of the relevant mount
|
||||
* @dentry: dentry to set XATTR at
|
||||
* @name: xattr name for setxattr
|
||||
* @value: xattr value to set
|
||||
* @size: size of xattr value
|
||||
* @attr_name: xattr name for setxattr
|
||||
* @attr_value: xattr value to set
|
||||
* @attr_size: size of xattr value
|
||||
* @flags: destination buffer length
|
||||
*
|
||||
* Return: 0 on success, otherwise error
|
||||
|
|
|
@ -365,12 +365,11 @@ static void __put_fd_final(struct ksmbd_work *work, struct ksmbd_file *fp)
|
|||
|
||||
static void set_close_state_blocked_works(struct ksmbd_file *fp)
|
||||
{
|
||||
struct ksmbd_work *cancel_work, *ctmp;
|
||||
struct ksmbd_work *cancel_work;
|
||||
|
||||
spin_lock(&fp->f_lock);
|
||||
list_for_each_entry_safe(cancel_work, ctmp, &fp->blocked_works,
|
||||
list_for_each_entry(cancel_work, &fp->blocked_works,
|
||||
fp_entry) {
|
||||
list_del(&cancel_work->fp_entry);
|
||||
cancel_work->state = KSMBD_WORK_CLOSED;
|
||||
cancel_work->cancel_fn(cancel_work->cancel_argv);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue