Skip to content

Commit

Permalink
ksmbd: fix race condition between session lookup and expire
Browse files Browse the repository at this point in the history
 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 <rootlab@huawei.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
  • Loading branch information
Namjae Jeon authored and Steve French committed Oct 5, 2023
1 parent 8a749fd commit 53ff5cf
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 3 deletions.
2 changes: 2 additions & 0 deletions fs/smb/server/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
spin_lock_init(&conn->llist_lock);
INIT_LIST_HEAD(&conn->lock_list);

init_rwsem(&conn->session_lock);

down_write(&conn_list_lock);
list_add(&conn->conns_list, &conn_list);
up_write(&conn_list_lock);
Expand Down
1 change: 1 addition & 0 deletions fs/smb/server/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ struct ksmbd_conn {
struct nls_table *local_nls;
struct unicode_map *um;
struct list_head conns_list;
struct rw_semaphore session_lock;
/* smb session 1 per user */
struct xarray sessions;
unsigned long last_active;
Expand Down
10 changes: 7 additions & 3 deletions fs/smb/server/mgmt/user_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn)
unsigned long id;
struct ksmbd_session *sess;

down_write(&sessions_table_lock);
down_write(&conn->session_lock);
xa_for_each(&conn->sessions, id, sess) {
if (sess->state != SMB2_SESSION_VALID ||
time_after(jiffies,
Expand All @@ -185,7 +185,7 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn)
continue;
}
}
up_write(&sessions_table_lock);
up_write(&conn->session_lock);
}

int ksmbd_session_register(struct ksmbd_conn *conn,
Expand Down Expand Up @@ -227,7 +227,9 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
}
}
}
up_write(&sessions_table_lock);

down_write(&conn->session_lock);
xa_for_each(&conn->sessions, id, sess) {
unsigned long chann_id;
struct channel *chann;
Expand All @@ -244,17 +246,19 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
ksmbd_session_destroy(sess);
}
}
up_write(&sessions_table_lock);
up_write(&conn->session_lock);
}

struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
unsigned long long id)
{
struct ksmbd_session *sess;

down_read(&conn->session_lock);
sess = xa_load(&conn->sessions, id);
if (sess)
sess->last_active = jiffies;
up_read(&conn->session_lock);
return sess;
}

Expand Down

0 comments on commit 53ff5cf

Please sign in to comment.