Skip to content

Commit db3fada

Browse files
borkmannkuba-moo
authored andcommitted
packet: Move reference count in packet_sock to atomic_long_t
In some potential instances the reference count on struct packet_sock could be saturated and cause overflows which gets the kernel a bit confused. To prevent this, move to a 64-bit atomic reference count on 64-bit architectures to prevent the possibility of this type to overflow. Because we can not handle saturation, using refcount_t is not possible in this place. Maybe someday in the future if it changes it could be used. Also, instead of using plain atomic64_t, use atomic_long_t instead. 32-bit machines tend to be memory-limited (i.e. anything that increases a reference uses so much memory that you can't actually get to 2**32 references). 32-bit architectures also tend to have serious problems with 64-bit atomics. Hence, atomic_long_t is the more natural solution. Reported-by: "The UK's National Cyber Security Centre (NCSC)" <[email protected]> Co-developed-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: [email protected] Reviewed-by: Willem de Bruijn <[email protected]> Reviewed-by: Eric Dumazet <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 79321a7 commit db3fada

File tree

2 files changed

+9
-9
lines changed

2 files changed

+9
-9
lines changed

net/packet/af_packet.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4300,7 +4300,7 @@ static void packet_mm_open(struct vm_area_struct *vma)
43004300
struct sock *sk = sock->sk;
43014301

43024302
if (sk)
4303-
atomic_inc(&pkt_sk(sk)->mapped);
4303+
atomic_long_inc(&pkt_sk(sk)->mapped);
43044304
}
43054305

43064306
static void packet_mm_close(struct vm_area_struct *vma)
@@ -4310,7 +4310,7 @@ static void packet_mm_close(struct vm_area_struct *vma)
43104310
struct sock *sk = sock->sk;
43114311

43124312
if (sk)
4313-
atomic_dec(&pkt_sk(sk)->mapped);
4313+
atomic_long_dec(&pkt_sk(sk)->mapped);
43144314
}
43154315

43164316
static const struct vm_operations_struct packet_mmap_ops = {
@@ -4405,7 +4405,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
44054405

44064406
err = -EBUSY;
44074407
if (!closing) {
4408-
if (atomic_read(&po->mapped))
4408+
if (atomic_long_read(&po->mapped))
44094409
goto out;
44104410
if (packet_read_pending(rb))
44114411
goto out;
@@ -4508,7 +4508,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
45084508

45094509
err = -EBUSY;
45104510
mutex_lock(&po->pg_vec_lock);
4511-
if (closing || atomic_read(&po->mapped) == 0) {
4511+
if (closing || atomic_long_read(&po->mapped) == 0) {
45124512
err = 0;
45134513
spin_lock_bh(&rb_queue->lock);
45144514
swap(rb->pg_vec, pg_vec);
@@ -4526,9 +4526,9 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
45264526
po->prot_hook.func = (po->rx_ring.pg_vec) ?
45274527
tpacket_rcv : packet_rcv;
45284528
skb_queue_purge(rb_queue);
4529-
if (atomic_read(&po->mapped))
4530-
pr_err("packet_mmap: vma is busy: %d\n",
4531-
atomic_read(&po->mapped));
4529+
if (atomic_long_read(&po->mapped))
4530+
pr_err("packet_mmap: vma is busy: %ld\n",
4531+
atomic_long_read(&po->mapped));
45324532
}
45334533
mutex_unlock(&po->pg_vec_lock);
45344534

@@ -4606,7 +4606,7 @@ static int packet_mmap(struct file *file, struct socket *sock,
46064606
}
46074607
}
46084608

4609-
atomic_inc(&po->mapped);
4609+
atomic_long_inc(&po->mapped);
46104610
vma->vm_ops = &packet_mmap_ops;
46114611
err = 0;
46124612

net/packet/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ struct packet_sock {
122122
__be16 num;
123123
struct packet_rollover *rollover;
124124
struct packet_mclist *mclist;
125-
atomic_t mapped;
125+
atomic_long_t mapped;
126126
enum tpacket_versions tp_version;
127127
unsigned int tp_hdrlen;
128128
unsigned int tp_reserve;

0 commit comments

Comments
 (0)