mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 01:53:29 +02:00
4 ksmbd SMB3 server fixes, most also for stable
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmgPw1IACgkQiiy9cAdy T1Fl4AwAlbLrqQHArI03OEUNhS6iV7Q13ZeXrMpi3jIzdKpLmMlc6ze+HcfB58QX PM1vQm+/1htfempeRxCHVM0XWLv3Y4Oya1Qk3AsvT9Uv0zqq3hwqG4FybG39VVfd 4lxmsT1mzHBE/nT2gtb8iU1XqOVvJ8FM7lPubslPWMdCYpFMjmKretBUpzQOeh9J IYQdWjd/gDjAZ10DnX8BPlJlW7pnXoRf7QMNlj6GD79Bs0ZwBWcytNN3bO1f04hD q03X9LQBuXqOm+yxBRMojK+QF6XOa1xbZBrk3LcPEVWWgzfOhcyTDTP15Dw90Sgs 3GGMxP52agHnNf1hKMM00qaWHeEIyGdD5mfWcbTbquPI9cYdZ+wVcWP3qGDYEGfI 9e0J+o09kWj13WW65VA44k2qFQdxiO6JyFzOrDSY1KTd0ud4wG64UUAhOiq9nY7X sLxzCk8G1rVgefcfqL7WJL7EPaq1a5ESFqYIi7uK6nrK/8nH9FTyF9+q1qcS+I00 nOgRymu0 =jTh7 -----END PGP SIGNATURE----- Merge tag 'v6.15-rc4-ksmbd-server-fixes' of git://git.samba.org/ksmbd Pull smb server fixes from Steve French: - Fix three potential use after frees: in session logoff, in krb5 auth, and in RPC open - Fix missing rc check in session setup authentication * tag 'v6.15-rc4-ksmbd-server-fixes' of git://git.samba.org/ksmbd: ksmbd: fix use-after-free in session logoff ksmbd: fix use-after-free in kerberos authentication ksmbd: fix use-after-free in ksmbd_session_rpc_open smb: server: smb2pdu: check return value of xa_store()
This commit is contained in:
commit
ca91b95001
|
|
@ -550,7 +550,19 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
|
|||
retval = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
sess->user = user;
|
||||
|
||||
if (!sess->user) {
|
||||
/* First successful authentication */
|
||||
sess->user = user;
|
||||
} else {
|
||||
if (!ksmbd_compare_user(sess->user, user)) {
|
||||
ksmbd_debug(AUTH, "different user tried to reuse session\n");
|
||||
retval = -EPERM;
|
||||
ksmbd_free_user(user);
|
||||
goto out;
|
||||
}
|
||||
ksmbd_free_user(user);
|
||||
}
|
||||
|
||||
memcpy(sess->sess_key, resp->payload, resp->session_key_len);
|
||||
memcpy(out_blob, resp->payload + resp->session_key_len,
|
||||
|
|
|
|||
|
|
@ -59,10 +59,12 @@ static void ksmbd_session_rpc_clear_list(struct ksmbd_session *sess)
|
|||
struct ksmbd_session_rpc *entry;
|
||||
long index;
|
||||
|
||||
down_write(&sess->rpc_lock);
|
||||
xa_for_each(&sess->rpc_handle_list, index, entry) {
|
||||
xa_erase(&sess->rpc_handle_list, index);
|
||||
__session_rpc_close(sess, entry);
|
||||
}
|
||||
up_write(&sess->rpc_lock);
|
||||
|
||||
xa_destroy(&sess->rpc_handle_list);
|
||||
}
|
||||
|
|
@ -92,7 +94,7 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
|
|||
{
|
||||
struct ksmbd_session_rpc *entry, *old;
|
||||
struct ksmbd_rpc_command *resp;
|
||||
int method;
|
||||
int method, id;
|
||||
|
||||
method = __rpc_method(rpc_name);
|
||||
if (!method)
|
||||
|
|
@ -102,26 +104,29 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
|
|||
if (!entry)
|
||||
return -ENOMEM;
|
||||
|
||||
down_read(&sess->rpc_lock);
|
||||
entry->method = method;
|
||||
entry->id = ksmbd_ipc_id_alloc();
|
||||
if (entry->id < 0)
|
||||
entry->id = id = ksmbd_ipc_id_alloc();
|
||||
if (id < 0)
|
||||
goto free_entry;
|
||||
old = xa_store(&sess->rpc_handle_list, entry->id, entry, KSMBD_DEFAULT_GFP);
|
||||
old = xa_store(&sess->rpc_handle_list, id, entry, KSMBD_DEFAULT_GFP);
|
||||
if (xa_is_err(old))
|
||||
goto free_id;
|
||||
|
||||
resp = ksmbd_rpc_open(sess, entry->id);
|
||||
resp = ksmbd_rpc_open(sess, id);
|
||||
if (!resp)
|
||||
goto erase_xa;
|
||||
|
||||
up_read(&sess->rpc_lock);
|
||||
kvfree(resp);
|
||||
return entry->id;
|
||||
return id;
|
||||
erase_xa:
|
||||
xa_erase(&sess->rpc_handle_list, entry->id);
|
||||
free_id:
|
||||
ksmbd_rpc_id_free(entry->id);
|
||||
free_entry:
|
||||
kfree(entry);
|
||||
up_read(&sess->rpc_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -129,9 +134,11 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id)
|
|||
{
|
||||
struct ksmbd_session_rpc *entry;
|
||||
|
||||
down_write(&sess->rpc_lock);
|
||||
entry = xa_erase(&sess->rpc_handle_list, id);
|
||||
if (entry)
|
||||
__session_rpc_close(sess, entry);
|
||||
up_write(&sess->rpc_lock);
|
||||
}
|
||||
|
||||
int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
|
||||
|
|
@ -439,6 +446,7 @@ static struct ksmbd_session *__session_create(int protocol)
|
|||
sess->sequence_number = 1;
|
||||
rwlock_init(&sess->tree_conns_lock);
|
||||
atomic_set(&sess->refcnt, 2);
|
||||
init_rwsem(&sess->rpc_lock);
|
||||
|
||||
ret = __init_smb2_session(sess);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ struct ksmbd_session {
|
|||
rwlock_t tree_conns_lock;
|
||||
|
||||
atomic_t refcnt;
|
||||
struct rw_semaphore rpc_lock;
|
||||
};
|
||||
|
||||
static inline int test_session_flag(struct ksmbd_session *sess, int bit)
|
||||
|
|
|
|||
|
|
@ -1445,7 +1445,7 @@ static int ntlm_authenticate(struct ksmbd_work *work,
|
|||
{
|
||||
struct ksmbd_conn *conn = work->conn;
|
||||
struct ksmbd_session *sess = work->sess;
|
||||
struct channel *chann = NULL;
|
||||
struct channel *chann = NULL, *old;
|
||||
struct ksmbd_user *user;
|
||||
u64 prev_id;
|
||||
int sz, rc;
|
||||
|
|
@ -1557,7 +1557,12 @@ static int ntlm_authenticate(struct ksmbd_work *work,
|
|||
return -ENOMEM;
|
||||
|
||||
chann->conn = conn;
|
||||
xa_store(&sess->ksmbd_chann_list, (long)conn, chann, KSMBD_DEFAULT_GFP);
|
||||
old = xa_store(&sess->ksmbd_chann_list, (long)conn, chann,
|
||||
KSMBD_DEFAULT_GFP);
|
||||
if (xa_is_err(old)) {
|
||||
kfree(chann);
|
||||
return xa_err(old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1602,11 +1607,6 @@ static int krb5_authenticate(struct ksmbd_work *work,
|
|||
if (prev_sess_id && prev_sess_id != sess->id)
|
||||
destroy_previous_session(conn, sess->user, prev_sess_id);
|
||||
|
||||
if (sess->state == SMB2_SESSION_VALID) {
|
||||
ksmbd_free_user(sess->user);
|
||||
sess->user = NULL;
|
||||
}
|
||||
|
||||
retval = ksmbd_krb5_authenticate(sess, in_blob, in_len,
|
||||
out_blob, &out_len);
|
||||
if (retval) {
|
||||
|
|
@ -2249,10 +2249,6 @@ int smb2_session_logoff(struct ksmbd_work *work)
|
|||
sess->state = SMB2_SESSION_EXPIRED;
|
||||
up_write(&conn->session_lock);
|
||||
|
||||
if (sess->user) {
|
||||
ksmbd_free_user(sess->user);
|
||||
sess->user = NULL;
|
||||
}
|
||||
ksmbd_all_conn_set_status(sess_id, KSMBD_SESS_NEED_SETUP);
|
||||
|
||||
rsp->StructureSize = cpu_to_le16(4);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user