Skip to content

Commit 4dcb31d

Browse files
Eric Dumazetdavem330
authored andcommitted
net: use skb_to_full_sk() in skb_update_prio()
Andrei Vagin reported a KASAN: slab-out-of-bounds error in skb_update_prio() Since SYNACK might be attached to a request socket, we need to get back to the listener socket. Since this listener is manipulated without locks, add const qualifiers to sock_cgroup_prioidx() so that the const can also be used in skb_update_prio() Also add the const qualifier to sock_cgroup_classid() for consistency. Fixes: ca6fb06 ("tcp: attach SYNACK messages to request sockets instead of listener") Signed-off-by: Eric Dumazet <[email protected]> Reported-by: Andrei Vagin <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f89782c commit 4dcb31d

File tree

2 files changed

+17
-9
lines changed

2 files changed

+17
-9
lines changed

include/linux/cgroup-defs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -755,13 +755,13 @@ struct sock_cgroup_data {
755755
* updaters and return part of the previous pointer as the prioidx or
756756
* classid. Such races are short-lived and the result isn't critical.
757757
*/
758-
static inline u16 sock_cgroup_prioidx(struct sock_cgroup_data *skcd)
758+
static inline u16 sock_cgroup_prioidx(const struct sock_cgroup_data *skcd)
759759
{
760760
/* fallback to 1 which is always the ID of the root cgroup */
761761
return (skcd->is_data & 1) ? skcd->prioidx : 1;
762762
}
763763

764-
static inline u32 sock_cgroup_classid(struct sock_cgroup_data *skcd)
764+
static inline u32 sock_cgroup_classid(const struct sock_cgroup_data *skcd)
765765
{
766766
/* fallback to 0 which is the unconfigured default classid */
767767
return (skcd->is_data & 1) ? skcd->classid : 0;

net/core/dev.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3278,15 +3278,23 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
32783278
#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
32793279
static void skb_update_prio(struct sk_buff *skb)
32803280
{
3281-
struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap);
3281+
const struct netprio_map *map;
3282+
const struct sock *sk;
3283+
unsigned int prioidx;
32823284

3283-
if (!skb->priority && skb->sk && map) {
3284-
unsigned int prioidx =
3285-
sock_cgroup_prioidx(&skb->sk->sk_cgrp_data);
3285+
if (skb->priority)
3286+
return;
3287+
map = rcu_dereference_bh(skb->dev->priomap);
3288+
if (!map)
3289+
return;
3290+
sk = skb_to_full_sk(skb);
3291+
if (!sk)
3292+
return;
32863293

3287-
if (prioidx < map->priomap_len)
3288-
skb->priority = map->priomap[prioidx];
3289-
}
3294+
prioidx = sock_cgroup_prioidx(&sk->sk_cgrp_data);
3295+
3296+
if (prioidx < map->priomap_len)
3297+
skb->priority = map->priomap[prioidx];
32903298
}
32913299
#else
32923300
#define skb_update_prio(skb)

0 commit comments

Comments
 (0)