forked from Minki/linux
kcm: fix strp_init() order and cleanup
strp_init() is called just a few lines above this csk->sk_user_data check, it also initializes strp->work etc., therefore, it is unnecessary to call strp_done() to cancel the freshly initialized work. And if sk_user_data is already used by KCM, psock->strp should not be touched, particularly strp->work state, so we need to move strp_init() after the csk->sk_user_data check. This also makes a lockdep warning reported by syzbot go away. Reported-and-tested-by: syzbot+9fc084a4348493ef65d2@syzkaller.appspotmail.com Reported-by: syzbot+e696806ef96cdd2d87cd@syzkaller.appspotmail.com Fixes:e557124023
("kcm: Check if sk_user_data already set in kcm_attach") Fixes:dff8baa261
("kcm: Call strp_stop before strp_done in kcm_attach") Cc: Tom Herbert <tom@herbertland.com> Signed-off-by: Cong Wang <cong.wang@bytedance.com> Link: https://lore.kernel.org/r/20220827181314.193710-1-xiyou.wangcong@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
3a1a274e93
commit
8fc29ff391
@ -1412,12 +1412,6 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
|
||||
psock->sk = csk;
|
||||
psock->bpf_prog = prog;
|
||||
|
||||
err = strp_init(&psock->strp, csk, &cb);
|
||||
if (err) {
|
||||
kmem_cache_free(kcm_psockp, psock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
write_lock_bh(&csk->sk_callback_lock);
|
||||
|
||||
/* Check if sk_user_data is already by KCM or someone else.
|
||||
@ -1425,13 +1419,18 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
|
||||
*/
|
||||
if (csk->sk_user_data) {
|
||||
write_unlock_bh(&csk->sk_callback_lock);
|
||||
strp_stop(&psock->strp);
|
||||
strp_done(&psock->strp);
|
||||
kmem_cache_free(kcm_psockp, psock);
|
||||
err = -EALREADY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = strp_init(&psock->strp, csk, &cb);
|
||||
if (err) {
|
||||
write_unlock_bh(&csk->sk_callback_lock);
|
||||
kmem_cache_free(kcm_psockp, psock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
psock->save_data_ready = csk->sk_data_ready;
|
||||
psock->save_write_space = csk->sk_write_space;
|
||||
psock->save_state_change = csk->sk_state_change;
|
||||
|
Loading…
Reference in New Issue
Block a user