Skip to content

Commit

Permalink
ksmbd: throttle session setup failures to avoid dictionary attacks
Browse files Browse the repository at this point in the history
To avoid dictionary attacks (repeated session setups rapidly sent) to
connect to server, ksmbd make a delay of a 5 seconds on session setup
failure to make it harder to send enough random connection requests
to break into a server if a user insert the wrong password 10 times
in a row.

Signed-off-by: Namjae Jeon <[email protected]>
Signed-off-by: Steve French <[email protected]>
  • Loading branch information
namjaejeon authored and Steve French committed Oct 20, 2021
1 parent 34061d6 commit 621be84
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 6 deletions.
2 changes: 2 additions & 0 deletions fs/ksmbd/ksmbd_netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ struct ksmbd_tree_disconnect_request {
*/
struct ksmbd_logout_request {
__s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */
__u32 account_flags;
};

/*
Expand Down Expand Up @@ -317,6 +318,7 @@ enum KSMBD_TREE_CONN_STATUS {
#define KSMBD_USER_FLAG_BAD_UID BIT(2)
#define KSMBD_USER_FLAG_BAD_USER BIT(3)
#define KSMBD_USER_FLAG_GUEST_ACCOUNT BIT(4)
#define KSMBD_USER_FLAG_DELAY_SESSION BIT(5)

/*
* Share config flags.
Expand Down
2 changes: 1 addition & 1 deletion fs/ksmbd/mgmt/user_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp)

void ksmbd_free_user(struct ksmbd_user *user)
{
ksmbd_ipc_logout_request(user->name);
ksmbd_ipc_logout_request(user->name, user->flags);
kfree(user->name);
kfree(user->passkey);
kfree(user);
Expand Down
1 change: 1 addition & 0 deletions fs/ksmbd/mgmt/user_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct ksmbd_user {

size_t passkey_sz;
char *passkey;
unsigned int failed_login_count;
};

static inline bool user_guest(struct ksmbd_user *user)
Expand Down
27 changes: 24 additions & 3 deletions fs/ksmbd/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1779,9 +1779,30 @@ int smb2_sess_setup(struct ksmbd_work *work)
conn->mechToken = NULL;
}

if (rc < 0 && sess) {
ksmbd_session_destroy(sess);
work->sess = NULL;
if (rc < 0) {
/*
* SecurityBufferOffset should be set to zero
* in session setup error response.
*/
rsp->SecurityBufferOffset = 0;

if (sess) {
bool try_delay = false;

/*
* To avoid dictionary attacks (repeated session setups rapidly sent) to
* connect to server, ksmbd make a delay of a 5 seconds on session setup
* failure to make it harder to send enough random connection requests
* to break into a server.
*/
if (sess->user && sess->user->flags & KSMBD_USER_FLAG_DELAY_SESSION)
try_delay = true;

ksmbd_session_destroy(sess);
work->sess = NULL;
if (try_delay)
ssleep(5);
}
}

return rc;
Expand Down
3 changes: 2 additions & 1 deletion fs/ksmbd/transport_ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id,
return ret;
}

int ksmbd_ipc_logout_request(const char *account)
int ksmbd_ipc_logout_request(const char *account, int flags)
{
struct ksmbd_ipc_msg *msg;
struct ksmbd_logout_request *req;
Expand All @@ -616,6 +616,7 @@ int ksmbd_ipc_logout_request(const char *account)

msg->type = KSMBD_EVENT_LOGOUT_REQUEST;
req = (struct ksmbd_logout_request *)msg->payload;
req->account_flags = flags;
strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ);

ret = ipc_msg_send(msg);
Expand Down
2 changes: 1 addition & 1 deletion fs/ksmbd/transport_ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess,
struct sockaddr *peer_addr);
int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id,
unsigned long long connect_id);
int ksmbd_ipc_logout_request(const char *account);
int ksmbd_ipc_logout_request(const char *account, int flags);
struct ksmbd_share_config_response *
ksmbd_ipc_share_config_request(const char *name);
struct ksmbd_spnego_authen_response *
Expand Down

0 comments on commit 621be84

Please sign in to comment.