|
123 |
return group ? 1 << (group - 1) : 0; |
123 |
return group ? 1 << (group - 1) : 0; |
124 |
} |
124 |
} |
125 |
|
125 |
|
126 |
static struct sk_buff *netlink_to_full_skb(const struct sk_buff *skb, |
|
|
127 |
gfp_t gfp_mask) |
128 |
{ |
129 |
unsigned int len = skb_end_offset(skb); |
130 |
struct sk_buff *new; |
131 |
|
132 |
new = alloc_skb(len, gfp_mask); |
133 |
if (new == NULL) |
134 |
return NULL; |
135 |
|
136 |
NETLINK_CB(new).portid = NETLINK_CB(skb).portid; |
137 |
NETLINK_CB(new).dst_group = NETLINK_CB(skb).dst_group; |
138 |
NETLINK_CB(new).creds = NETLINK_CB(skb).creds; |
139 |
|
140 |
memcpy(skb_put(new, len), skb->data, len); |
141 |
return new; |
142 |
} |
143 |
|
144 |
int netlink_add_tap(struct netlink_tap *nt) |
126 |
int netlink_add_tap(struct netlink_tap *nt) |
145 |
{ |
127 |
{ |
146 |
if (unlikely(nt->dev->type != ARPHRD_NETLINK)) |
128 |
if (unlikely(nt->dev->type != ARPHRD_NETLINK)) |
|
222 |
int ret = -ENOMEM; |
204 |
int ret = -ENOMEM; |
223 |
|
205 |
|
224 |
dev_hold(dev); |
206 |
dev_hold(dev); |
225 |
|
207 |
nskb = skb_clone(skb, GFP_ATOMIC); |
226 |
if (netlink_skb_is_mmaped(skb) || is_vmalloc_addr(skb->head)) |
|
|
227 |
nskb = netlink_to_full_skb(skb, GFP_ATOMIC); |
228 |
else |
229 |
nskb = skb_clone(skb, GFP_ATOMIC); |
230 |
if (nskb) { |
208 |
if (nskb) { |
231 |
nskb->dev = dev; |
209 |
nskb->dev = dev; |
232 |
nskb->protocol = htons((u16) sk->sk_protocol); |
210 |
nskb->protocol = htons((u16) sk->sk_protocol); |
|
298 |
} |
276 |
} |
299 |
|
277 |
|
300 |
#ifdef CONFIG_NETLINK_MMAP |
278 |
#ifdef CONFIG_NETLINK_MMAP |
|
|
279 |
static bool netlink_skb_is_mmaped(const struct sk_buff *skb) |
280 |
{ |
281 |
return NETLINK_CB(skb).flags & NETLINK_SKB_MMAPED; |
282 |
} |
283 |
|
301 |
static bool netlink_rx_is_mmaped(struct sock *sk) |
284 |
static bool netlink_rx_is_mmaped(struct sock *sk) |
302 |
{ |
285 |
{ |
303 |
return nlk_sk(sk)->rx_ring.pg_vec != NULL; |
286 |
return nlk_sk(sk)->rx_ring.pg_vec != NULL; |
|
372 |
return NULL; |
355 |
return NULL; |
373 |
} |
356 |
} |
374 |
|
357 |
|
375 |
|
|
|
376 |
static void |
377 |
__netlink_set_ring(struct sock *sk, struct nl_mmap_req *req, bool tx_ring, void **pg_vec, |
378 |
unsigned int order) |
379 |
{ |
380 |
struct netlink_sock *nlk = nlk_sk(sk); |
381 |
struct sk_buff_head *queue; |
382 |
struct netlink_ring *ring; |
383 |
|
384 |
queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue; |
385 |
ring = tx_ring ? &nlk->tx_ring : &nlk->rx_ring; |
386 |
|
387 |
spin_lock_bh(&queue->lock); |
388 |
|
389 |
ring->frame_max = req->nm_frame_nr - 1; |
390 |
ring->head = 0; |
391 |
ring->frame_size = req->nm_frame_size; |
392 |
ring->pg_vec_pages = req->nm_block_size / PAGE_SIZE; |
393 |
|
394 |
swap(ring->pg_vec_len, req->nm_block_nr); |
395 |
swap(ring->pg_vec_order, order); |
396 |
swap(ring->pg_vec, pg_vec); |
397 |
|
398 |
__skb_queue_purge(queue); |
399 |
spin_unlock_bh(&queue->lock); |
400 |
|
401 |
WARN_ON(atomic_read(&nlk->mapped)); |
402 |
|
403 |
if (pg_vec) |
404 |
free_pg_vec(pg_vec, order, req->nm_block_nr); |
405 |
} |
406 |
|
407 |
static int netlink_set_ring(struct sock *sk, struct nl_mmap_req *req, |
358 |
static int netlink_set_ring(struct sock *sk, struct nl_mmap_req *req, |
408 |
bool tx_ring) |
359 |
bool closing, bool tx_ring) |
409 |
{ |
360 |
{ |
410 |
struct netlink_sock *nlk = nlk_sk(sk); |
361 |
struct netlink_sock *nlk = nlk_sk(sk); |
411 |
struct netlink_ring *ring; |
362 |
struct netlink_ring *ring; |
|
|
363 |
struct sk_buff_head *queue; |
412 |
void **pg_vec = NULL; |
364 |
void **pg_vec = NULL; |
413 |
unsigned int order = 0; |
365 |
unsigned int order = 0; |
|
|
366 |
int err; |
414 |
|
367 |
|
415 |
ring = tx_ring ? &nlk->tx_ring : &nlk->rx_ring; |
368 |
ring = tx_ring ? &nlk->tx_ring : &nlk->rx_ring; |
|
|
369 |
queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue; |
416 |
|
370 |
|
417 |
if (atomic_read(&nlk->mapped)) |
371 |
if (!closing) { |
418 |
return -EBUSY; |
372 |
if (atomic_read(&nlk->mapped)) |
419 |
if (atomic_read(&ring->pending)) |
373 |
return -EBUSY; |
420 |
return -EBUSY; |
374 |
if (atomic_read(&ring->pending)) |
|
|
375 |
return -EBUSY; |
376 |
} |
421 |
|
377 |
|
422 |
if (req->nm_block_nr) { |
378 |
if (req->nm_block_nr) { |
423 |
if (ring->pg_vec != NULL) |
379 |
if (ring->pg_vec != NULL) |
|
449 |
return -EINVAL; |
405 |
return -EINVAL; |
450 |
} |
406 |
} |
451 |
|
407 |
|
|
|
408 |
err = -EBUSY; |
452 |
mutex_lock(&nlk->pg_vec_lock); |
409 |
mutex_lock(&nlk->pg_vec_lock); |
453 |
if (atomic_read(&nlk->mapped) == 0) { |
410 |
if (closing || atomic_read(&nlk->mapped) == 0) { |
454 |
__netlink_set_ring(sk, req, tx_ring, pg_vec, order); |
411 |
err = 0; |
455 |
mutex_unlock(&nlk->pg_vec_lock); |
412 |
spin_lock_bh(&queue->lock); |
456 |
return 0; |
413 |
|
457 |
} |
414 |
ring->frame_max = req->nm_frame_nr - 1; |
|
|
415 |
ring->head = 0; |
416 |
ring->frame_size = req->nm_frame_size; |
417 |
ring->pg_vec_pages = req->nm_block_size / PAGE_SIZE; |
418 |
|
419 |
swap(ring->pg_vec_len, req->nm_block_nr); |
420 |
swap(ring->pg_vec_order, order); |
421 |
swap(ring->pg_vec, pg_vec); |
422 |
|
423 |
__skb_queue_purge(queue); |
424 |
spin_unlock_bh(&queue->lock); |
458 |
|
425 |
|
|
|
426 |
WARN_ON(atomic_read(&nlk->mapped)); |
427 |
} |
459 |
mutex_unlock(&nlk->pg_vec_lock); |
428 |
mutex_unlock(&nlk->pg_vec_lock); |
460 |
|
429 |
|
461 |
if (pg_vec) |
430 |
if (pg_vec) |
462 |
free_pg_vec(pg_vec, order, req->nm_block_nr); |
431 |
free_pg_vec(pg_vec, order, req->nm_block_nr); |
463 |
|
432 |
return err; |
464 |
return -EBUSY; |
|
|
465 |
} |
433 |
} |
466 |
|
434 |
|
467 |
static void netlink_mm_open(struct vm_area_struct *vma) |
435 |
static void netlink_mm_open(struct vm_area_struct *vma) |
|
849 |
} |
817 |
} |
850 |
|
818 |
|
851 |
#else /* CONFIG_NETLINK_MMAP */ |
819 |
#else /* CONFIG_NETLINK_MMAP */ |
|
|
820 |
#define netlink_skb_is_mmaped(skb) false |
852 |
#define netlink_rx_is_mmaped(sk) false |
821 |
#define netlink_rx_is_mmaped(sk) false |
853 |
#define netlink_tx_is_mmaped(sk) false |
822 |
#define netlink_tx_is_mmaped(sk) false |
854 |
#define netlink_mmap sock_no_mmap |
823 |
#define netlink_mmap sock_no_mmap |
|
929 |
|
898 |
|
930 |
memset(&req, 0, sizeof(req)); |
899 |
memset(&req, 0, sizeof(req)); |
931 |
if (nlk->rx_ring.pg_vec) |
900 |
if (nlk->rx_ring.pg_vec) |
932 |
__netlink_set_ring(sk, &req, false, NULL, 0); |
901 |
netlink_set_ring(sk, &req, true, false); |
933 |
memset(&req, 0, sizeof(req)); |
902 |
memset(&req, 0, sizeof(req)); |
934 |
if (nlk->tx_ring.pg_vec) |
903 |
if (nlk->tx_ring.pg_vec) |
935 |
__netlink_set_ring(sk, &req, true, NULL, 0); |
904 |
netlink_set_ring(sk, &req, true, true); |
936 |
} |
905 |
} |
937 |
#endif /* CONFIG_NETLINK_MMAP */ |
906 |
#endif /* CONFIG_NETLINK_MMAP */ |
938 |
|
907 |
|
|
1096 |
|
1065 |
|
1097 |
lock_sock(sk); |
1066 |
lock_sock(sk); |
1098 |
|
1067 |
|
1099 |
err = nlk_sk(sk)->portid == portid ? 0 : -EBUSY; |
1068 |
err = -EBUSY; |
1100 |
if (nlk_sk(sk)->bound) |
1069 |
if (nlk_sk(sk)->portid) |
1101 |
goto err; |
1070 |
goto err; |
1102 |
|
1071 |
|
1103 |
err = -ENOMEM; |
1072 |
err = -ENOMEM; |
|
1110 |
|
1079 |
|
1111 |
err = __netlink_insert(table, sk); |
1080 |
err = __netlink_insert(table, sk); |
1112 |
if (err) { |
1081 |
if (err) { |
1113 |
/* In case the hashtable backend returns with -EBUSY |
|
|
1114 |
* from here, it must not escape to the caller. |
1115 |
*/ |
1116 |
if (unlikely(err == -EBUSY)) |
1117 |
err = -EOVERFLOW; |
1118 |
if (err == -EEXIST) |
1082 |
if (err == -EEXIST) |
1119 |
err = -EADDRINUSE; |
1083 |
err = -EADDRINUSE; |
|
|
1084 |
nlk_sk(sk)->portid = 0; |
1120 |
sock_put(sk); |
1085 |
sock_put(sk); |
1121 |
} |
1086 |
} |
1122 |
|
1087 |
|
1123 |
/* We need to ensure that the socket is hashed and visible. */ |
|
|
1124 |
smp_wmb(); |
1125 |
nlk_sk(sk)->bound = portid; |
1126 |
|
1127 |
err: |
1088 |
err: |
1128 |
release_sock(sk); |
1089 |
release_sock(sk); |
1129 |
return err; |
1090 |
return err; |
|
1503 |
struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; |
1464 |
struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; |
1504 |
int err; |
1465 |
int err; |
1505 |
long unsigned int groups = nladdr->nl_groups; |
1466 |
long unsigned int groups = nladdr->nl_groups; |
1506 |
bool bound; |
|
|
1507 |
|
1467 |
|
1508 |
if (addr_len < sizeof(struct sockaddr_nl)) |
1468 |
if (addr_len < sizeof(struct sockaddr_nl)) |
1509 |
return -EINVAL; |
1469 |
return -EINVAL; |
|
1520 |
return err; |
1480 |
return err; |
1521 |
} |
1481 |
} |
1522 |
|
1482 |
|
1523 |
bound = nlk->bound; |
1483 |
if (nlk->portid) |
1524 |
if (bound) { |
|
|
1525 |
/* Ensure nlk->portid is up-to-date. */ |
1526 |
smp_rmb(); |
1527 |
|
1528 |
if (nladdr->nl_pid != nlk->portid) |
1484 |
if (nladdr->nl_pid != nlk->portid) |
1529 |
return -EINVAL; |
1485 |
return -EINVAL; |
1530 |
} |
|
|
1531 |
|
1486 |
|
1532 |
if (nlk->netlink_bind && groups) { |
1487 |
if (nlk->netlink_bind && groups) { |
1533 |
int group; |
1488 |
int group; |
|
1543 |
} |
1498 |
} |
1544 |
} |
1499 |
} |
1545 |
|
1500 |
|
1546 |
/* No need for barriers here as we return to user-space without |
1501 |
if (!nlk->portid) { |
1547 |
* using any of the bound attributes. |
|
|
1548 |
*/ |
1549 |
if (!bound) { |
1550 |
err = nladdr->nl_pid ? |
1502 |
err = nladdr->nl_pid ? |
1551 |
netlink_insert(sk, nladdr->nl_pid) : |
1503 |
netlink_insert(sk, nladdr->nl_pid) : |
1552 |
netlink_autobind(sock); |
1504 |
netlink_autobind(sock); |
|
1594 |
!netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) |
1546 |
!netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) |
1595 |
return -EPERM; |
1547 |
return -EPERM; |
1596 |
|
1548 |
|
1597 |
/* No need for barriers here as we return to user-space without |
1549 |
if (!nlk->portid) |
1598 |
* using any of the bound attributes. |
|
|
1599 |
*/ |
1600 |
if (!nlk->bound) |
1601 |
err = netlink_autobind(sock); |
1550 |
err = netlink_autobind(sock); |
1602 |
|
1551 |
|
1603 |
if (err == 0) { |
1552 |
if (err == 0) { |
|
2248 |
return -EINVAL; |
2197 |
return -EINVAL; |
2249 |
if (copy_from_user(&req, optval, sizeof(req))) |
2198 |
if (copy_from_user(&req, optval, sizeof(req))) |
2250 |
return -EFAULT; |
2199 |
return -EFAULT; |
2251 |
err = netlink_set_ring(sk, &req, |
2200 |
err = netlink_set_ring(sk, &req, false, |
2252 |
optname == NETLINK_TX_RING); |
2201 |
optname == NETLINK_TX_RING); |
2253 |
break; |
2202 |
break; |
2254 |
} |
2203 |
} |
|
2354 |
dst_group = nlk->dst_group; |
2303 |
dst_group = nlk->dst_group; |
2355 |
} |
2304 |
} |
2356 |
|
2305 |
|
2357 |
if (!nlk->bound) { |
2306 |
if (!nlk->portid) { |
2358 |
err = netlink_autobind(sock); |
2307 |
err = netlink_autobind(sock); |
2359 |
if (err) |
2308 |
if (err) |
2360 |
goto out; |
2309 |
goto out; |
2361 |
} else { |
|
|
2362 |
/* Ensure nlk is hashed and visible. */ |
2363 |
smp_rmb(); |
2364 |
} |
2310 |
} |
2365 |
|
2311 |
|
2366 |
/* It's a really convoluted way for userland to ask for mmaped |
2312 |
/* It's a really convoluted way for userland to ask for mmaped |
|
2683 |
struct sk_buff *skb = NULL; |
2629 |
struct sk_buff *skb = NULL; |
2684 |
struct nlmsghdr *nlh; |
2630 |
struct nlmsghdr *nlh; |
2685 |
int len, err = -ENOBUFS; |
2631 |
int len, err = -ENOBUFS; |
2686 |
int alloc_min_size; |
|
|
2687 |
int alloc_size; |
2632 |
int alloc_size; |
2688 |
|
2633 |
|
2689 |
mutex_lock(nlk->cb_mutex); |
2634 |
mutex_lock(nlk->cb_mutex); |
|
2692 |
goto errout_skb; |
2637 |
goto errout_skb; |
2693 |
} |
2638 |
} |
2694 |
|
2639 |
|
|
|
2640 |
cb = &nlk->cb; |
2641 |
alloc_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE); |
2642 |
|
2695 |
if (!netlink_rx_is_mmaped(sk) && |
2643 |
if (!netlink_rx_is_mmaped(sk) && |
2696 |
atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) |
2644 |
atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) |
2697 |
goto errout_skb; |
2645 |
goto errout_skb; |
|
2701 |
* to reduce number of system calls on dump operations, if user |
2649 |
* to reduce number of system calls on dump operations, if user |
2702 |
* ever provided a big enough buffer. |
2650 |
* ever provided a big enough buffer. |
2703 |
*/ |
2651 |
*/ |
2704 |
cb = &nlk->cb; |
2652 |
if (alloc_size < nlk->max_recvmsg_len) { |
2705 |
alloc_min_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE); |
2653 |
skb = netlink_alloc_skb(sk, |
2706 |
|
2654 |
nlk->max_recvmsg_len, |
2707 |
if (alloc_min_size < nlk->max_recvmsg_len) { |
2655 |
nlk->portid, |
2708 |
alloc_size = nlk->max_recvmsg_len; |
|
|
2709 |
skb = netlink_alloc_skb(sk, alloc_size, nlk->portid, |
2710 |
GFP_KERNEL | |
2656 |
GFP_KERNEL | |
2711 |
__GFP_NOWARN | |
2657 |
__GFP_NOWARN | |
2712 |
__GFP_NORETRY); |
2658 |
__GFP_NORETRY); |
|
|
2659 |
/* available room should be exact amount to avoid MSG_TRUNC */ |
2660 |
if (skb) |
2661 |
skb_reserve(skb, skb_tailroom(skb) - |
2662 |
nlk->max_recvmsg_len); |
2713 |
} |
2663 |
} |
2714 |
if (!skb) { |
2664 |
if (!skb) |
2715 |
alloc_size = alloc_min_size; |
|
|
2716 |
skb = netlink_alloc_skb(sk, alloc_size, nlk->portid, |
2665 |
skb = netlink_alloc_skb(sk, alloc_size, nlk->portid, |
2717 |
GFP_KERNEL); |
2666 |
GFP_KERNEL); |
2718 |
} |
|
|
2719 |
if (!skb) |
2667 |
if (!skb) |
2720 |
goto errout_skb; |
2668 |
goto errout_skb; |
2721 |
|
|
|
2722 |
/* Trim skb to allocated size. User is expected to provide buffer as |
2723 |
* large as max(min_dump_alloc, 16KiB (mac_recvmsg_len capped at |
2724 |
* netlink_recvmsg())). dump will pack as many smaller messages as |
2725 |
* could fit within the allocated skb. skb is typically allocated |
2726 |
* with larger space than required (could be as much as near 2x the |
2727 |
* requested size with align to next power of 2 approach). Allowing |
2728 |
* dump to use the excess space makes it difficult for a user to have a |
2729 |
* reasonable static buffer based on the expected largest dump of a |
2730 |
* single netdev. The outcome is MSG_TRUNC error. |
2731 |
*/ |
2732 |
skb_reserve(skb, skb_tailroom(skb) - alloc_size); |
2733 |
netlink_skb_set_owner_r(skb, sk); |
2669 |
netlink_skb_set_owner_r(skb, sk); |
2734 |
|
2670 |
|
2735 |
len = cb->dump(skb, cb); |
2671 |
len = cb->dump(skb, cb); |