Skip to content

Commit

Permalink
net: Remove redundant calls of sk_tx_queue_clear().
Browse files Browse the repository at this point in the history
The commit 41b14fb ("net: Do not clear the sock TX queue in
sk_set_socket()") removes sk_tx_queue_clear() from sk_set_socket() and adds
it instead in sk_alloc() and sk_clone_lock() to fix an issue introduced in
the commit e022f0b ("net: Introduce sk_tx_queue_mapping"). On the
other hand, the original commit had already put sk_tx_queue_clear() in
sk_prot_alloc(): the callee of sk_alloc() and sk_clone_lock(). Thus
sk_tx_queue_clear() is called twice in each path.

If we remove sk_tx_queue_clear() in sk_alloc() and sk_clone_lock(), it
currently works well because (i) sk_tx_queue_mapping is defined between
sk_dontcopy_begin and sk_dontcopy_end, and (ii) sock_copy() called after
sk_prot_alloc() in sk_clone_lock() does not overwrite sk_tx_queue_mapping.
However, if we move sk_tx_queue_mapping out of the no copy area, it
introduces a bug unintentionally.

Therefore, this patch adds a compile-time check to take care of the order
of sock_copy() and sk_tx_queue_clear() and removes sk_tx_queue_clear() from
sk_prot_alloc() so that it does the only allocation and its callers
initialize fields.

CC: Boris Pismenny <[email protected]>
Signed-off-by: Kuniyuki Iwashima <[email protected]>
Acked-by: Tariq Toukan <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
q2ven authored and kuba-moo committed Jan 30, 2021
1 parent 77609b1 commit df610cd
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion net/core/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1657,6 +1657,16 @@ static void sock_copy(struct sock *nsk, const struct sock *osk)
#ifdef CONFIG_SECURITY_NETWORK
void *sptr = nsk->sk_security;
#endif

/* If we move sk_tx_queue_mapping out of the private section,
* we must check if sk_tx_queue_clear() is called after
* sock_copy() in sk_clone_lock().
*/
BUILD_BUG_ON(offsetof(struct sock, sk_tx_queue_mapping) <
offsetof(struct sock, sk_dontcopy_begin) ||
offsetof(struct sock, sk_tx_queue_mapping) >=
offsetof(struct sock, sk_dontcopy_end));

memcpy(nsk, osk, offsetof(struct sock, sk_dontcopy_begin));

memcpy(&nsk->sk_dontcopy_end, &osk->sk_dontcopy_end,
Expand Down Expand Up @@ -1690,7 +1700,6 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,

if (!try_module_get(prot->owner))
goto out_free_sec;
sk_tx_queue_clear(sk);
}

return sk;
Expand Down

0 comments on commit df610cd

Please sign in to comment.