As found by syzkaller, malicious users can set whatever tx_queue_len on a tun device and eventually crash the kernel. Lets remove the ALIGN(XXX, SMP_CACHE_BYTES) thing since a small ring buffer is not fast anyway.
Unified · Split
| @@ -436,9 +436,9 @@ static inline int ptr_ring_consume_batched_bh(struct ptr_ring *r, · 435 unmodified lines | |||
| 436 | __PTR_RING_PEEK_CALL_v; \ | 436 | __PTR_RING_PEEK_CALL_v; \ |
| 437 | }) | 437 | }) |
| 438 | 438 | ||
| 439 | static inline void **__ptr_ring_init_queue_alloc(int size, gfp_t gfp) | 439 | static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp) |
| 440 | { | 440 | { |
| 441 | return kzalloc(ALIGN(size * sizeof(void *), SMP_CACHE_BYTES), gfp); | 441 | return kcalloc(size, sizeof(void *), gfp); |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | static inline void __ptr_ring_set_size(struct ptr_ring *r, int size) | 444 | static inline void __ptr_ring_set_size(struct ptr_ring *r, int size) |
| @@ -582,7 +582,8 @@ static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp, · 137 unmodified lines | |||
| 582 | * In particular if you consume ring in interrupt or BH context, you must | 582 | * In particular if you consume ring in interrupt or BH context, you must |
| 583 | * disable interrupts/BH when doing so. | 583 | * disable interrupts/BH when doing so. |
| 584 | */ | 584 | */ |
| 585 | static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings, | 585 | static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, |
| 586 | unsigned int nrings, | ||
| 586 | int size, | 587 | int size, |
| 587 | gfp_t gfp, void (*destroy)(void *)) | 588 | gfp_t gfp, void (*destroy)(void *)) |
| 588 | { | 589 | { |
| @@ -590,7 +591,7 @@ static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings, · 1 unmodified line | |||
| 590 | void ***queues; | 591 | void ***queues; |
| 591 | int i; | 592 | int i; |
| 592 | 593 | ||
| 593 | queues = kmalloc(nrings * sizeof *queues, gfp); | 594 | queues = kmalloc_array(nrings, sizeof(*queues), gfp); |
| 594 | if (!queues) | 595 | if (!queues) |
| 595 | goto noqueues; | 596 | goto noqueues; |
| 596 | 597 | ||
| @@ -193,7 +193,8 @@ static inline int skb_array_resize(struct skb_array *a, int size, gfp_t gfp) · 192 unmodified lines | |||
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static inline int skb_array_resize_multiple(struct skb_array **rings, | 195 | static inline int skb_array_resize_multiple(struct skb_array **rings, |
| 196 | int nrings, int size, gfp_t gfp) | 196 | int nrings, unsigned int size, |
| 197 | gfp_t gfp) | ||
| 197 | { | 198 | { |
| 198 | BUILD_BUG_ON(offsetof(struct skb_array, ring)); | 199 | BUILD_BUG_ON(offsetof(struct skb_array, ring)); |
| 199 | return ptr_ring_resize_multiple((struct ptr_ring **)rings, | 200 | return ptr_ring_resize_multiple((struct ptr_ring **)rings, |