Skip to content

Commit 53ff5cf

Browse files
namjaejeonSteve French
authored andcommitted
ksmbd: fix race condition between session lookup and expire
Thread A + Thread B ksmbd_session_lookup | smb2_sess_setup sess = xa_load | | | xa_erase(&conn->sessions, sess->id); | | ksmbd_session_destroy(sess) --> kfree(sess) | // UAF! | sess->last_active = jiffies | + This patch add rwsem to fix race condition between ksmbd_session_lookup and ksmbd_expire_session. Reported-by: luosili <[email protected]> Signed-off-by: Namjae Jeon <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 8a749fd commit 53ff5cf

File tree

3 files changed

+10
-3
lines changed

3 files changed

+10
-3
lines changed

fs/smb/server/connection.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
8484
spin_lock_init(&conn->llist_lock);
8585
INIT_LIST_HEAD(&conn->lock_list);
8686

87+
init_rwsem(&conn->session_lock);
88+
8789
down_write(&conn_list_lock);
8890
list_add(&conn->conns_list, &conn_list);
8991
up_write(&conn_list_lock);

fs/smb/server/connection.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct ksmbd_conn {
5050
struct nls_table *local_nls;
5151
struct unicode_map *um;
5252
struct list_head conns_list;
53+
struct rw_semaphore session_lock;
5354
/* smb session 1 per user */
5455
struct xarray sessions;
5556
unsigned long last_active;

fs/smb/server/mgmt/user_session.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn)
174174
unsigned long id;
175175
struct ksmbd_session *sess;
176176

177-
down_write(&sessions_table_lock);
177+
down_write(&conn->session_lock);
178178
xa_for_each(&conn->sessions, id, sess) {
179179
if (sess->state != SMB2_SESSION_VALID ||
180180
time_after(jiffies,
@@ -185,7 +185,7 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn)
185185
continue;
186186
}
187187
}
188-
up_write(&sessions_table_lock);
188+
up_write(&conn->session_lock);
189189
}
190190

191191
int ksmbd_session_register(struct ksmbd_conn *conn,
@@ -227,7 +227,9 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
227227
}
228228
}
229229
}
230+
up_write(&sessions_table_lock);
230231

232+
down_write(&conn->session_lock);
231233
xa_for_each(&conn->sessions, id, sess) {
232234
unsigned long chann_id;
233235
struct channel *chann;
@@ -244,17 +246,19 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
244246
ksmbd_session_destroy(sess);
245247
}
246248
}
247-
up_write(&sessions_table_lock);
249+
up_write(&conn->session_lock);
248250
}
249251

250252
struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
251253
unsigned long long id)
252254
{
253255
struct ksmbd_session *sess;
254256

257+
down_read(&conn->session_lock);
255258
sess = xa_load(&conn->sessions, id);
256259
if (sess)
257260
sess->last_active = jiffies;
261+
up_read(&conn->session_lock);
258262
return sess;
259263
}
260264

0 commit comments

Comments
 (0)