blob: 205865292ba342ad67b0288ef1c398681e55f9cc [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * NETLINK Kernel-user communication protocol.
3 *
Alan Cox113aa832008-10-13 19:01:08 -07004 * Authors: Alan Cox <alan@lxorguk.ukuu.org.uk>
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Patrick McHardycd1df522013-04-17 06:47:05 +00006 * Patrick McHardy <kaber@trash.net>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +090012 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 * Tue Jun 26 14:36:48 MEST 2001 Herbert "herp" Rosmanith
14 * added netlink_proto_exit
15 * Tue Jan 22 18:32:44 BRST 2002 Arnaldo C. de Melo <acme@conectiva.com.br>
16 * use nlk_sk, as sk->protinfo is on a diet 8)
Harald Welte4fdb3bb2005-08-09 19:40:55 -070017 * Fri Jul 22 19:51:12 MEST 2005 Harald Welte <laforge@gnumonks.org>
18 * - inc module use count of module that owns
19 * the kernel socket in case userspace opens
20 * socket of same protocol
21 * - remove all module support, since netlink is
22 * mandatory if CONFIG_NET=y these days
Linus Torvalds1da177e2005-04-16 15:20:36 -070023 */
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <linux/module.h>
26
Randy Dunlap4fc268d2006-01-11 12:17:47 -080027#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/kernel.h>
29#include <linux/init.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030#include <linux/signal.h>
31#include <linux/sched.h>
32#include <linux/errno.h>
33#include <linux/string.h>
34#include <linux/stat.h>
35#include <linux/socket.h>
36#include <linux/un.h>
37#include <linux/fcntl.h>
38#include <linux/termios.h>
39#include <linux/sockios.h>
40#include <linux/net.h>
41#include <linux/fs.h>
42#include <linux/slab.h>
43#include <asm/uaccess.h>
44#include <linux/skbuff.h>
45#include <linux/netdevice.h>
46#include <linux/rtnetlink.h>
47#include <linux/proc_fs.h>
48#include <linux/seq_file.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <linux/notifier.h>
50#include <linux/security.h>
51#include <linux/jhash.h>
52#include <linux/jiffies.h>
53#include <linux/random.h>
54#include <linux/bitops.h>
55#include <linux/mm.h>
56#include <linux/types.h>
Andrew Morton54e0f522005-04-30 07:07:04 +010057#include <linux/audit.h>
Patrick McHardyaf65bdf2007-04-20 14:14:21 -070058#include <linux/mutex.h>
Patrick McHardyccdfcc32013-04-17 06:47:01 +000059#include <linux/vmalloc.h>
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +020060#include <linux/if_arp.h>
Thomas Grafe3416942014-08-02 11:47:45 +020061#include <linux/rhashtable.h>
Patrick McHardy9652e932013-04-17 06:47:02 +000062#include <asm/cacheflush.h>
Thomas Grafe3416942014-08-02 11:47:45 +020063#include <linux/hash.h>
Johannes Bergee1c24422015-01-16 11:37:14 +010064#include <linux/genetlink.h>
Jeremy Cline67f0a282018-07-31 21:13:16 +000065#include <linux/nospec.h>
Andrew Morton54e0f522005-04-30 07:07:04 +010066
Eric W. Biederman457c4cb2007-09-12 12:01:34 +020067#include <net/net_namespace.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070068#include <net/sock.h>
69#include <net/scm.h>
Thomas Graf82ace472005-11-10 02:25:53 +010070#include <net/netlink.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070071
Andrey Vagin0f29c762013-03-21 20:33:47 +040072#include "af_netlink.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
Eric Dumazet5c398dc2010-10-24 04:27:10 +000074struct listeners {
75 struct rcu_head rcu;
76 unsigned long masks[0];
Johannes Berg6c04bb12009-07-10 09:51:32 +000077};
78
Patrick McHardycd967e02013-04-17 06:46:56 +000079/* state bits */
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +020080#define NETLINK_S_CONGESTED 0x0
Patrick McHardycd967e02013-04-17 06:46:56 +000081
82/* flags */
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +020083#define NETLINK_F_KERNEL_SOCKET 0x1
84#define NETLINK_F_RECV_PKTINFO 0x2
85#define NETLINK_F_BROADCAST_SEND_ERROR 0x4
86#define NETLINK_F_RECV_NO_ENOBUFS 0x8
Nicolas Dichtel59324cf2015-05-07 11:02:53 +020087#define NETLINK_F_LISTEN_ALL_NSID 0x10
Christophe Ricard0a6a3a22015-08-28 07:07:48 +020088#define NETLINK_F_CAP_ACK 0x20
Patrick McHardy77247bb2005-08-14 19:27:13 -070089
David S. Miller035c4c12011-12-23 17:33:03 -050090static inline int netlink_is_kernel(struct sock *sk)
Denis V. Lunevaed81562007-10-10 21:14:32 -070091{
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +020092 return nlk_sk(sk)->flags & NETLINK_F_KERNEL_SOCKET;
Denis V. Lunevaed81562007-10-10 21:14:32 -070093}
94
Eric Dumazet91dd93f2015-05-12 17:24:50 -070095struct netlink_table *nl_table __read_mostly;
Andrey Vagin0f29c762013-03-21 20:33:47 +040096EXPORT_SYMBOL_GPL(nl_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
98static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
99
Herbert Xu7ff28d32017-03-14 18:25:57 +0800100static struct lock_class_key nlk_cb_mutex_keys[MAX_LINKS];
101
102static const char *const nlk_cb_mutex_key_strings[MAX_LINKS + 1] = {
103 "nlk_cb_mutex-ROUTE",
104 "nlk_cb_mutex-1",
105 "nlk_cb_mutex-USERSOCK",
106 "nlk_cb_mutex-FIREWALL",
107 "nlk_cb_mutex-SOCK_DIAG",
108 "nlk_cb_mutex-NFLOG",
109 "nlk_cb_mutex-XFRM",
110 "nlk_cb_mutex-SELINUX",
111 "nlk_cb_mutex-ISCSI",
112 "nlk_cb_mutex-AUDIT",
113 "nlk_cb_mutex-FIB_LOOKUP",
114 "nlk_cb_mutex-CONNECTOR",
115 "nlk_cb_mutex-NETFILTER",
116 "nlk_cb_mutex-IP6_FW",
117 "nlk_cb_mutex-DNRTMSG",
118 "nlk_cb_mutex-KOBJECT_UEVENT",
119 "nlk_cb_mutex-GENERIC",
120 "nlk_cb_mutex-17",
121 "nlk_cb_mutex-SCSITRANSPORT",
122 "nlk_cb_mutex-ECRYPTFS",
123 "nlk_cb_mutex-RDMA",
124 "nlk_cb_mutex-CRYPTO",
125 "nlk_cb_mutex-SMC",
126 "nlk_cb_mutex-23",
127 "nlk_cb_mutex-24",
128 "nlk_cb_mutex-25",
129 "nlk_cb_mutex-26",
130 "nlk_cb_mutex-27",
131 "nlk_cb_mutex-28",
132 "nlk_cb_mutex-29",
133 "nlk_cb_mutex-30",
134 "nlk_cb_mutex-31",
135 "nlk_cb_mutex-MAX_LINKS"
136};
137
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138static int netlink_dump(struct sock *sk);
Patrick McHardy9652e932013-04-17 06:47:02 +0000139static void netlink_skb_destructor(struct sk_buff *skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
Thomas Graf78fd1d02014-10-21 22:05:38 +0200141/* nl_table locking explained:
Thomas Graf21e49022015-01-02 23:00:22 +0100142 * Lookup and traversal are protected with an RCU read-side lock. Insertion
Ying Xuec5adde92015-01-12 14:52:23 +0800143 * and removal are protected with per bucket lock while using RCU list
Thomas Graf21e49022015-01-02 23:00:22 +0100144 * modification primitives and may run in parallel to RCU protected lookups.
145 * Destruction of the Netlink socket may only occur *after* nl_table_lock has
146 * been acquired * either during or after the socket has been removed from
147 * the list and after an RCU grace period.
Thomas Graf78fd1d02014-10-21 22:05:38 +0200148 */
Andrey Vagin0f29c762013-03-21 20:33:47 +0400149DEFINE_RWLOCK(nl_table_lock);
150EXPORT_SYMBOL_GPL(nl_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151static atomic_t nl_table_users = ATOMIC_INIT(0);
152
Eric Dumazet6d772ac2012-10-18 03:21:55 +0000153#define nl_deref_protected(X) rcu_dereference_protected(X, lockdep_is_held(&nl_table_lock));
154
Alan Sterne041c682006-03-27 01:16:30 -0800155static ATOMIC_NOTIFIER_HEAD(netlink_chain);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200157static DEFINE_SPINLOCK(netlink_tap_lock);
158static struct list_head netlink_tap_all __read_mostly;
159
Herbert Xuc428ecd2015-03-20 21:57:01 +1100160static const struct rhashtable_params netlink_rhashtable_params;
161
stephen hemmingerb57ef81f2011-12-22 08:52:02 +0000162static inline u32 netlink_group_mask(u32 group)
Patrick McHardyd629b832005-08-14 19:27:50 -0700163{
164 return group ? 1 << (group - 1) : 0;
165}
166
Daniel Borkmann1853c942015-09-10 20:05:46 +0200167static struct sk_buff *netlink_to_full_skb(const struct sk_buff *skb,
168 gfp_t gfp_mask)
169{
170 unsigned int len = skb_end_offset(skb);
171 struct sk_buff *new;
172
173 new = alloc_skb(len, gfp_mask);
174 if (new == NULL)
175 return NULL;
176
177 NETLINK_CB(new).portid = NETLINK_CB(skb).portid;
178 NETLINK_CB(new).dst_group = NETLINK_CB(skb).dst_group;
179 NETLINK_CB(new).creds = NETLINK_CB(skb).creds;
180
181 memcpy(skb_put(new, len), skb->data, len);
182 return new;
183}
184
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200185int netlink_add_tap(struct netlink_tap *nt)
186{
187 if (unlikely(nt->dev->type != ARPHRD_NETLINK))
188 return -EINVAL;
189
190 spin_lock(&netlink_tap_lock);
191 list_add_rcu(&nt->list, &netlink_tap_all);
192 spin_unlock(&netlink_tap_lock);
193
Markus Elfringfcd4d352014-11-18 21:03:13 +0100194 __module_get(nt->module);
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200195
196 return 0;
197}
198EXPORT_SYMBOL_GPL(netlink_add_tap);
199
stephen hemminger2173f8d2013-12-30 10:49:22 -0800200static int __netlink_remove_tap(struct netlink_tap *nt)
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200201{
202 bool found = false;
203 struct netlink_tap *tmp;
204
205 spin_lock(&netlink_tap_lock);
206
207 list_for_each_entry(tmp, &netlink_tap_all, list) {
208 if (nt == tmp) {
209 list_del_rcu(&nt->list);
210 found = true;
211 goto out;
212 }
213 }
214
215 pr_warn("__netlink_remove_tap: %p not found\n", nt);
216out:
217 spin_unlock(&netlink_tap_lock);
218
Markus Elfring92b80eb2015-07-02 18:38:12 +0200219 if (found)
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200220 module_put(nt->module);
221
222 return found ? 0 : -ENODEV;
223}
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200224
225int netlink_remove_tap(struct netlink_tap *nt)
226{
227 int ret;
228
229 ret = __netlink_remove_tap(nt);
230 synchronize_net();
231
232 return ret;
233}
234EXPORT_SYMBOL_GPL(netlink_remove_tap);
235
Daniel Borkmann5ffd5cd2013-09-05 17:48:47 +0200236static bool netlink_filter_tap(const struct sk_buff *skb)
237{
238 struct sock *sk = skb->sk;
Daniel Borkmann5ffd5cd2013-09-05 17:48:47 +0200239
240 /* We take the more conservative approach and
241 * whitelist socket protocols that may pass.
242 */
243 switch (sk->sk_protocol) {
244 case NETLINK_ROUTE:
245 case NETLINK_USERSOCK:
246 case NETLINK_SOCK_DIAG:
247 case NETLINK_NFLOG:
248 case NETLINK_XFRM:
249 case NETLINK_FIB_LOOKUP:
250 case NETLINK_NETFILTER:
251 case NETLINK_GENERIC:
Varka Bhadram498044b2014-07-16 10:59:47 +0530252 return true;
Daniel Borkmann5ffd5cd2013-09-05 17:48:47 +0200253 }
254
Varka Bhadram498044b2014-07-16 10:59:47 +0530255 return false;
Daniel Borkmann5ffd5cd2013-09-05 17:48:47 +0200256}
257
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200258static int __netlink_deliver_tap_skb(struct sk_buff *skb,
259 struct net_device *dev)
260{
261 struct sk_buff *nskb;
Daniel Borkmann5ffd5cd2013-09-05 17:48:47 +0200262 struct sock *sk = skb->sk;
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200263 int ret = -ENOMEM;
264
Kevin Cernekee0b187822017-12-06 12:12:27 -0800265 if (!net_eq(dev_net(dev), sock_net(sk)))
266 return 0;
267
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200268 dev_hold(dev);
Daniel Borkmann1853c942015-09-10 20:05:46 +0200269
Florian Westphald1b4c682016-02-18 15:03:24 +0100270 if (is_vmalloc_addr(skb->head))
Daniel Borkmann1853c942015-09-10 20:05:46 +0200271 nskb = netlink_to_full_skb(skb, GFP_ATOMIC);
272 else
273 nskb = skb_clone(skb, GFP_ATOMIC);
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200274 if (nskb) {
275 nskb->dev = dev;
Daniel Borkmann5ffd5cd2013-09-05 17:48:47 +0200276 nskb->protocol = htons((u16) sk->sk_protocol);
Daniel Borkmann604d13c2013-12-23 14:35:56 +0100277 nskb->pkt_type = netlink_is_kernel(sk) ?
278 PACKET_KERNEL : PACKET_USER;
Daniel Borkmann4e48ed82014-08-07 22:22:47 +0200279 skb_reset_network_header(nskb);
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200280 ret = dev_queue_xmit(nskb);
281 if (unlikely(ret > 0))
282 ret = net_xmit_errno(ret);
283 }
284
285 dev_put(dev);
286 return ret;
287}
288
289static void __netlink_deliver_tap(struct sk_buff *skb)
290{
291 int ret;
292 struct netlink_tap *tmp;
293
Daniel Borkmann5ffd5cd2013-09-05 17:48:47 +0200294 if (!netlink_filter_tap(skb))
295 return;
296
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +0200297 list_for_each_entry_rcu(tmp, &netlink_tap_all, list) {
298 ret = __netlink_deliver_tap_skb(skb, tmp->dev);
299 if (unlikely(ret))
300 break;
301 }
302}
303
304static void netlink_deliver_tap(struct sk_buff *skb)
305{
306 rcu_read_lock();
307
308 if (unlikely(!list_empty(&netlink_tap_all)))
309 __netlink_deliver_tap(skb);
310
311 rcu_read_unlock();
312}
313
Daniel Borkmann73bfd372013-12-23 14:35:55 +0100314static void netlink_deliver_tap_kernel(struct sock *dst, struct sock *src,
315 struct sk_buff *skb)
316{
317 if (!(netlink_is_kernel(dst) && netlink_is_kernel(src)))
318 netlink_deliver_tap(skb);
319}
320
Patrick McHardycd1df522013-04-17 06:47:05 +0000321static void netlink_overrun(struct sock *sk)
322{
323 struct netlink_sock *nlk = nlk_sk(sk);
324
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +0200325 if (!(nlk->flags & NETLINK_F_RECV_NO_ENOBUFS)) {
326 if (!test_and_set_bit(NETLINK_S_CONGESTED,
327 &nlk_sk(sk)->state)) {
Patrick McHardycd1df522013-04-17 06:47:05 +0000328 sk->sk_err = ENOBUFS;
329 sk->sk_error_report(sk);
330 }
331 }
332 atomic_inc(&sk->sk_drops);
333}
334
335static void netlink_rcv_wake(struct sock *sk)
336{
337 struct netlink_sock *nlk = nlk_sk(sk);
338
339 if (skb_queue_empty(&sk->sk_receive_queue))
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +0200340 clear_bit(NETLINK_S_CONGESTED, &nlk->state);
341 if (!test_bit(NETLINK_S_CONGESTED, &nlk->state))
Patrick McHardycd1df522013-04-17 06:47:05 +0000342 wake_up_interruptible(&nlk->wait);
343}
344
Patrick McHardycf0a0182013-04-17 06:47:00 +0000345static void netlink_skb_destructor(struct sk_buff *skb)
346{
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +0000347 if (is_vmalloc_addr(skb->head)) {
Pablo Neira3a365152013-06-28 03:04:23 +0200348 if (!skb->cloned ||
349 !atomic_dec_return(&(skb_shinfo(skb)->dataref)))
350 vfree(skb->head);
351
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +0000352 skb->head = NULL;
353 }
Patrick McHardy9652e932013-04-17 06:47:02 +0000354 if (skb->sk != NULL)
355 sock_rfree(skb);
Patrick McHardycf0a0182013-04-17 06:47:00 +0000356}
357
358static void netlink_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
359{
360 WARN_ON(skb->sk != NULL);
361 skb->sk = sk;
362 skb->destructor = netlink_skb_destructor;
363 atomic_add(skb->truesize, &sk->sk_rmem_alloc);
364 sk_mem_charge(sk, skb->truesize);
365}
366
Herbert Xued5d7782016-12-05 15:28:21 +0800367static void netlink_sock_destruct(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368{
Herbert Xu3f660d62007-05-03 03:17:14 -0700369 struct netlink_sock *nlk = nlk_sk(sk);
370
Pravin B Shelar16b304f2013-08-15 15:31:06 -0700371 if (nlk->cb_running) {
Herbert Xued5d7782016-12-05 15:28:21 +0800372 if (nlk->cb.done)
373 nlk->cb.done(&nlk->cb);
Pravin B Shelar16b304f2013-08-15 15:31:06 -0700374 module_put(nlk->cb.module);
375 kfree_skb(nlk->cb.skb);
Herbert Xu3f660d62007-05-03 03:17:14 -0700376 }
377
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 skb_queue_purge(&sk->sk_receive_queue);
379
380 if (!sock_flag(sk, SOCK_DEAD)) {
Patrick McHardy6ac552f2007-12-04 00:19:38 -0800381 printk(KERN_ERR "Freeing alive netlink socket %p\n", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 return;
383 }
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700384
385 WARN_ON(atomic_read(&sk->sk_rmem_alloc));
386 WARN_ON(atomic_read(&sk->sk_wmem_alloc));
387 WARN_ON(nlk_sk(sk)->groups);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388}
389
Herbert Xu707693c2016-11-28 19:22:12 +0800390static void netlink_sock_destruct_work(struct work_struct *work)
391{
392 struct netlink_sock *nlk = container_of(work, struct netlink_sock,
393 work);
394
Herbert Xued5d7782016-12-05 15:28:21 +0800395 sk_free(&nlk->sk);
Herbert Xu707693c2016-11-28 19:22:12 +0800396}
397
Patrick McHardy6ac552f2007-12-04 00:19:38 -0800398/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on
399 * SMP. Look, when several writers sleep and reader wakes them up, all but one
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 * immediately hit write lock and grab all the cpus. Exclusive sleep solves
401 * this, _but_ remember, it adds useless work on UP machines.
402 */
403
Johannes Bergd136f1b2009-09-12 03:03:15 +0000404void netlink_table_grab(void)
Eric Dumazet9a429c42008-01-01 21:58:02 -0800405 __acquires(nl_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406{
Johannes Bergd136f1b2009-09-12 03:03:15 +0000407 might_sleep();
408
Arjan van de Ven6abd2192006-07-03 00:24:07 -0700409 write_lock_irq(&nl_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
411 if (atomic_read(&nl_table_users)) {
412 DECLARE_WAITQUEUE(wait, current);
413
414 add_wait_queue_exclusive(&nl_table_wait, &wait);
Patrick McHardy6ac552f2007-12-04 00:19:38 -0800415 for (;;) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 set_current_state(TASK_UNINTERRUPTIBLE);
417 if (atomic_read(&nl_table_users) == 0)
418 break;
Arjan van de Ven6abd2192006-07-03 00:24:07 -0700419 write_unlock_irq(&nl_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 schedule();
Arjan van de Ven6abd2192006-07-03 00:24:07 -0700421 write_lock_irq(&nl_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 }
423
424 __set_current_state(TASK_RUNNING);
425 remove_wait_queue(&nl_table_wait, &wait);
426 }
427}
428
Johannes Bergd136f1b2009-09-12 03:03:15 +0000429void netlink_table_ungrab(void)
Eric Dumazet9a429c42008-01-01 21:58:02 -0800430 __releases(nl_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431{
Arjan van de Ven6abd2192006-07-03 00:24:07 -0700432 write_unlock_irq(&nl_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 wake_up(&nl_table_wait);
434}
435
Patrick McHardy6ac552f2007-12-04 00:19:38 -0800436static inline void
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437netlink_lock_table(void)
438{
439 /* read_lock() synchronizes us to netlink_table_grab */
440
441 read_lock(&nl_table_lock);
442 atomic_inc(&nl_table_users);
443 read_unlock(&nl_table_lock);
444}
445
Patrick McHardy6ac552f2007-12-04 00:19:38 -0800446static inline void
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447netlink_unlock_table(void)
448{
449 if (atomic_dec_and_test(&nl_table_users))
450 wake_up(&nl_table_wait);
451}
452
Thomas Grafe3416942014-08-02 11:47:45 +0200453struct netlink_compare_arg
Gao fengda12c902013-06-06 14:49:11 +0800454{
Herbert Xuc428ecd2015-03-20 21:57:01 +1100455 possible_net_t pnet;
Thomas Grafe3416942014-08-02 11:47:45 +0200456 u32 portid;
457};
458
Herbert Xu8f2ddaa2015-03-21 14:14:03 +1100459/* Doing sizeof directly may yield 4 extra bytes on 64-bit. */
460#define netlink_compare_arg_len \
461 (offsetof(struct netlink_compare_arg, portid) + sizeof(u32))
Thomas Grafe3416942014-08-02 11:47:45 +0200462
Herbert Xuc428ecd2015-03-20 21:57:01 +1100463static inline int netlink_compare(struct rhashtable_compare_arg *arg,
464 const void *ptr)
465{
466 const struct netlink_compare_arg *x = arg->key;
467 const struct netlink_sock *nlk = ptr;
468
Herbert Xuda314c92015-09-22 11:38:56 +0800469 return nlk->portid != x->portid ||
Herbert Xuc428ecd2015-03-20 21:57:01 +1100470 !net_eq(sock_net(&nlk->sk), read_pnet(&x->pnet));
471}
472
473static void netlink_compare_arg_init(struct netlink_compare_arg *arg,
474 struct net *net, u32 portid)
475{
476 memset(arg, 0, sizeof(*arg));
477 write_pnet(&arg->pnet, net);
478 arg->portid = portid;
Thomas Grafe3416942014-08-02 11:47:45 +0200479}
480
481static struct sock *__netlink_lookup(struct netlink_table *table, u32 portid,
482 struct net *net)
483{
Herbert Xuc428ecd2015-03-20 21:57:01 +1100484 struct netlink_compare_arg arg;
Thomas Grafe3416942014-08-02 11:47:45 +0200485
Herbert Xuc428ecd2015-03-20 21:57:01 +1100486 netlink_compare_arg_init(&arg, net, portid);
487 return rhashtable_lookup_fast(&table->hash, &arg,
488 netlink_rhashtable_params);
Gao fengda12c902013-06-06 14:49:11 +0800489}
490
Herbert Xuc428ecd2015-03-20 21:57:01 +1100491static int __netlink_insert(struct netlink_table *table, struct sock *sk)
Ying Xuec5adde92015-01-12 14:52:23 +0800492{
Herbert Xuc428ecd2015-03-20 21:57:01 +1100493 struct netlink_compare_arg arg;
Ying Xuec5adde92015-01-12 14:52:23 +0800494
Herbert Xuda314c92015-09-22 11:38:56 +0800495 netlink_compare_arg_init(&arg, sock_net(sk), nlk_sk(sk)->portid);
Herbert Xuc428ecd2015-03-20 21:57:01 +1100496 return rhashtable_lookup_insert_key(&table->hash, &arg,
497 &nlk_sk(sk)->node,
498 netlink_rhashtable_params);
Ying Xuec5adde92015-01-12 14:52:23 +0800499}
500
Eric W. Biederman15e47302012-09-07 20:12:54 +0000501static struct sock *netlink_lookup(struct net *net, int protocol, u32 portid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502{
Gao fengda12c902013-06-06 14:49:11 +0800503 struct netlink_table *table = &nl_table[protocol];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505
Thomas Grafe3416942014-08-02 11:47:45 +0200506 rcu_read_lock();
507 sk = __netlink_lookup(table, portid, net);
508 if (sk)
509 sock_hold(sk);
510 rcu_read_unlock();
511
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 return sk;
513}
514
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800515static const struct proto_ops netlink_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
Patrick McHardy4277a082006-03-20 18:52:01 -0800517static void
518netlink_update_listeners(struct sock *sk)
519{
520 struct netlink_table *tbl = &nl_table[sk->sk_protocol];
Patrick McHardy4277a082006-03-20 18:52:01 -0800521 unsigned long mask;
522 unsigned int i;
Eric Dumazet6d772ac2012-10-18 03:21:55 +0000523 struct listeners *listeners;
524
525 listeners = nl_deref_protected(tbl->listeners);
526 if (!listeners)
527 return;
Patrick McHardy4277a082006-03-20 18:52:01 -0800528
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700529 for (i = 0; i < NLGRPLONGS(tbl->groups); i++) {
Patrick McHardy4277a082006-03-20 18:52:01 -0800530 mask = 0;
Sasha Levinb67bfe02013-02-27 17:06:00 -0800531 sk_for_each_bound(sk, &tbl->mc_list) {
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700532 if (i < NLGRPLONGS(nlk_sk(sk)->ngroups))
533 mask |= nlk_sk(sk)->groups[i];
534 }
Eric Dumazet6d772ac2012-10-18 03:21:55 +0000535 listeners->masks[i] = mask;
Patrick McHardy4277a082006-03-20 18:52:01 -0800536 }
537 /* this function is only called with the netlink table "grabbed", which
538 * makes sure updates are visible before bind or setsockopt return. */
539}
540
Herbert Xu8ea65f42015-01-26 14:02:56 +1100541static int netlink_insert(struct sock *sk, u32 portid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542{
Gao fengda12c902013-06-06 14:49:11 +0800543 struct netlink_table *table = &nl_table[sk->sk_protocol];
Herbert Xu919d9db2015-01-16 17:23:48 +1100544 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545
Ying Xuec5adde92015-01-12 14:52:23 +0800546 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
Herbert Xuda314c92015-09-22 11:38:56 +0800548 err = nlk_sk(sk)->portid == portid ? 0 : -EBUSY;
549 if (nlk_sk(sk)->bound)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 goto err;
551
552 err = -ENOMEM;
Thomas Graf97defe12015-01-02 23:00:20 +0100553 if (BITS_PER_LONG > 32 &&
554 unlikely(atomic_read(&table->hash.nelems) >= UINT_MAX))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 goto err;
556
Herbert Xuda314c92015-09-22 11:38:56 +0800557 nlk_sk(sk)->portid = portid;
Thomas Grafe3416942014-08-02 11:47:45 +0200558 sock_hold(sk);
Herbert Xu919d9db2015-01-16 17:23:48 +1100559
Herbert Xuc428ecd2015-03-20 21:57:01 +1100560 err = __netlink_insert(table, sk);
561 if (err) {
Daniel Borkmann4e7c1332015-08-07 00:26:41 +0200562 /* In case the hashtable backend returns with -EBUSY
563 * from here, it must not escape to the caller.
564 */
565 if (unlikely(err == -EBUSY))
566 err = -EOVERFLOW;
Herbert Xuc428ecd2015-03-20 21:57:01 +1100567 if (err == -EEXIST)
568 err = -EADDRINUSE;
Ying Xuec5adde92015-01-12 14:52:23 +0800569 sock_put(sk);
Herbert Xu1f770c02015-09-18 19:16:50 +0800570 goto err;
Herbert Xu919d9db2015-01-16 17:23:48 +1100571 }
572
Herbert Xuda314c92015-09-22 11:38:56 +0800573 /* We need to ensure that the socket is hashed and visible. */
574 smp_wmb();
575 nlk_sk(sk)->bound = portid;
Herbert Xu1f770c02015-09-18 19:16:50 +0800576
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577err:
Ying Xuec5adde92015-01-12 14:52:23 +0800578 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 return err;
580}
581
582static void netlink_remove(struct sock *sk)
583{
Thomas Grafe3416942014-08-02 11:47:45 +0200584 struct netlink_table *table;
585
Thomas Grafe3416942014-08-02 11:47:45 +0200586 table = &nl_table[sk->sk_protocol];
Herbert Xuc428ecd2015-03-20 21:57:01 +1100587 if (!rhashtable_remove_fast(&table->hash, &nlk_sk(sk)->node,
588 netlink_rhashtable_params)) {
Thomas Grafe3416942014-08-02 11:47:45 +0200589 WARN_ON(atomic_read(&sk->sk_refcnt) == 1);
590 __sock_put(sk);
591 }
Thomas Grafe3416942014-08-02 11:47:45 +0200592
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 netlink_table_grab();
Johannes Bergb10dcb32014-12-22 18:56:37 +0100594 if (nlk_sk(sk)->subscriptions) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 __sk_del_bind_node(sk);
Johannes Bergb10dcb32014-12-22 18:56:37 +0100596 netlink_update_listeners(sk);
597 }
Johannes Bergee1c24422015-01-16 11:37:14 +0100598 if (sk->sk_protocol == NETLINK_GENERIC)
599 atomic_inc(&genl_sk_destructing_cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 netlink_table_ungrab();
601}
602
603static struct proto netlink_proto = {
604 .name = "NETLINK",
605 .owner = THIS_MODULE,
606 .obj_size = sizeof(struct netlink_sock),
607};
608
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700609static int __netlink_create(struct net *net, struct socket *sock,
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500610 struct mutex *cb_mutex, int protocol,
611 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612{
613 struct sock *sk;
614 struct netlink_sock *nlk;
Patrick McHardyab33a172005-08-14 19:31:36 -0700615
616 sock->ops = &netlink_ops;
617
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500618 sk = sk_alloc(net, PF_NETLINK, GFP_KERNEL, &netlink_proto, kern);
Patrick McHardyab33a172005-08-14 19:31:36 -0700619 if (!sk)
620 return -ENOMEM;
621
622 sock_init_data(sock, sk);
623
624 nlk = nlk_sk(sk);
Eric Dumazet658cb352012-04-22 21:30:21 +0000625 if (cb_mutex) {
Patrick McHardyffa4d722007-04-25 14:01:17 -0700626 nlk->cb_mutex = cb_mutex;
Eric Dumazet658cb352012-04-22 21:30:21 +0000627 } else {
Patrick McHardyffa4d722007-04-25 14:01:17 -0700628 nlk->cb_mutex = &nlk->cb_def_mutex;
629 mutex_init(nlk->cb_mutex);
Herbert Xu7ff28d32017-03-14 18:25:57 +0800630 lockdep_set_class_and_name(nlk->cb_mutex,
631 nlk_cb_mutex_keys + protocol,
632 nlk_cb_mutex_key_strings[protocol]);
Patrick McHardyffa4d722007-04-25 14:01:17 -0700633 }
Patrick McHardyab33a172005-08-14 19:31:36 -0700634 init_waitqueue_head(&nlk->wait);
635
636 sk->sk_destruct = netlink_sock_destruct;
637 sk->sk_protocol = protocol;
638 return 0;
639}
640
Eric Paris3f378b62009-11-05 22:18:14 -0800641static int netlink_create(struct net *net, struct socket *sock, int protocol,
642 int kern)
Patrick McHardyab33a172005-08-14 19:31:36 -0700643{
644 struct module *module = NULL;
Patrick McHardyaf65bdf2007-04-20 14:14:21 -0700645 struct mutex *cb_mutex;
Patrick McHardyf7fa9b12005-08-15 12:29:13 -0700646 struct netlink_sock *nlk;
Johannes Berg023e2cf2014-12-23 21:00:06 +0100647 int (*bind)(struct net *net, int group);
648 void (*unbind)(struct net *net, int group);
Patrick McHardyab33a172005-08-14 19:31:36 -0700649 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650
651 sock->state = SS_UNCONNECTED;
652
653 if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
654 return -ESOCKTNOSUPPORT;
655
Patrick McHardy6ac552f2007-12-04 00:19:38 -0800656 if (protocol < 0 || protocol >= MAX_LINKS)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 return -EPROTONOSUPPORT;
Jeremy Cline67f0a282018-07-31 21:13:16 +0000658 protocol = array_index_nospec(protocol, MAX_LINKS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659
Patrick McHardy77247bb2005-08-14 19:27:13 -0700660 netlink_lock_table();
Johannes Berg95a5afc2008-10-16 15:24:51 -0700661#ifdef CONFIG_MODULES
Patrick McHardyab33a172005-08-14 19:31:36 -0700662 if (!nl_table[protocol].registered) {
Patrick McHardy77247bb2005-08-14 19:27:13 -0700663 netlink_unlock_table();
Harald Welte4fdb3bb2005-08-09 19:40:55 -0700664 request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol);
Patrick McHardy77247bb2005-08-14 19:27:13 -0700665 netlink_lock_table();
Harald Welte4fdb3bb2005-08-09 19:40:55 -0700666 }
Patrick McHardyab33a172005-08-14 19:31:36 -0700667#endif
668 if (nl_table[protocol].registered &&
669 try_module_get(nl_table[protocol].module))
670 module = nl_table[protocol].module;
Alexey Dobriyan974c37e2010-01-30 10:05:05 +0000671 else
672 err = -EPROTONOSUPPORT;
Patrick McHardyaf65bdf2007-04-20 14:14:21 -0700673 cb_mutex = nl_table[protocol].cb_mutex;
Pablo Neira Ayuso03292742012-06-29 06:15:22 +0000674 bind = nl_table[protocol].bind;
Richard Guy Briggs4f520902014-04-22 21:31:54 -0400675 unbind = nl_table[protocol].unbind;
Patrick McHardy77247bb2005-08-14 19:27:13 -0700676 netlink_unlock_table();
Harald Welte4fdb3bb2005-08-09 19:40:55 -0700677
Alexey Dobriyan974c37e2010-01-30 10:05:05 +0000678 if (err < 0)
679 goto out;
680
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500681 err = __netlink_create(net, sock, cb_mutex, protocol, kern);
Patrick McHardy6ac552f2007-12-04 00:19:38 -0800682 if (err < 0)
Patrick McHardyab33a172005-08-14 19:31:36 -0700683 goto out_module;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684
David S. Miller6f756a82008-11-23 17:34:03 -0800685 local_bh_disable();
Eric Dumazetc1fd3b92008-11-23 15:48:22 -0800686 sock_prot_inuse_add(net, &netlink_proto, 1);
David S. Miller6f756a82008-11-23 17:34:03 -0800687 local_bh_enable();
688
Patrick McHardyf7fa9b12005-08-15 12:29:13 -0700689 nlk = nlk_sk(sock->sk);
Patrick McHardyf7fa9b12005-08-15 12:29:13 -0700690 nlk->module = module;
Pablo Neira Ayuso03292742012-06-29 06:15:22 +0000691 nlk->netlink_bind = bind;
Richard Guy Briggs4f520902014-04-22 21:31:54 -0400692 nlk->netlink_unbind = unbind;
Patrick McHardyab33a172005-08-14 19:31:36 -0700693out:
694 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695
Patrick McHardyab33a172005-08-14 19:31:36 -0700696out_module:
697 module_put(module);
698 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699}
700
Thomas Graf21e49022015-01-02 23:00:22 +0100701static void deferred_put_nlk_sk(struct rcu_head *head)
702{
703 struct netlink_sock *nlk = container_of(head, struct netlink_sock, rcu);
Herbert Xued5d7782016-12-05 15:28:21 +0800704 struct sock *sk = &nlk->sk;
Thomas Graf21e49022015-01-02 23:00:22 +0100705
Herbert Xued5d7782016-12-05 15:28:21 +0800706 if (!atomic_dec_and_test(&sk->sk_refcnt))
707 return;
708
709 if (nlk->cb_running && nlk->cb.done) {
710 INIT_WORK(&nlk->work, netlink_sock_destruct_work);
711 schedule_work(&nlk->work);
712 return;
713 }
714
715 sk_free(sk);
Thomas Graf21e49022015-01-02 23:00:22 +0100716}
717
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718static int netlink_release(struct socket *sock)
719{
720 struct sock *sk = sock->sk;
721 struct netlink_sock *nlk;
722
723 if (!sk)
724 return 0;
725
726 netlink_remove(sk);
Denis Lunevac57b3a2007-04-18 17:05:58 -0700727 sock_orphan(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 nlk = nlk_sk(sk);
729
Herbert Xu3f660d62007-05-03 03:17:14 -0700730 /*
731 * OK. Socket is unlinked, any packets that arrive now
732 * will be purged.
733 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734
Johannes Bergee1c24422015-01-16 11:37:14 +0100735 /* must not acquire netlink_table_lock in any way again before unbind
736 * and notifying genetlink is done as otherwise it might deadlock
737 */
738 if (nlk->netlink_unbind) {
739 int i;
740
741 for (i = 0; i < nlk->ngroups; i++)
742 if (test_bit(i, nlk->groups))
743 nlk->netlink_unbind(sock_net(sk), i + 1);
744 }
745 if (sk->sk_protocol == NETLINK_GENERIC &&
746 atomic_dec_return(&genl_sk_destructing_cnt) == 0)
747 wake_up(&genl_sk_destructing_waitq);
748
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 sock->sk = NULL;
750 wake_up_interruptible_all(&nlk->wait);
751
752 skb_queue_purge(&sk->sk_write_queue);
753
Dmitry Ivanove2726022016-04-07 09:31:38 +0200754 if (nlk->portid && nlk->bound) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 struct netlink_notify n = {
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900756 .net = sock_net(sk),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 .protocol = sk->sk_protocol,
Eric W. Biederman15e47302012-09-07 20:12:54 +0000758 .portid = nlk->portid,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 };
Alan Sterne041c682006-03-27 01:16:30 -0800760 atomic_notifier_call_chain(&netlink_chain,
761 NETLINK_URELEASE, &n);
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +0900762 }
Harald Welte4fdb3bb2005-08-09 19:40:55 -0700763
Mariusz Kozlowski5e7c0012007-01-02 15:24:30 -0800764 module_put(nlk->module);
Harald Welte4fdb3bb2005-08-09 19:40:55 -0700765
Denis V. Lunevaed81562007-10-10 21:14:32 -0700766 if (netlink_is_kernel(sk)) {
Johannes Bergb10dcb32014-12-22 18:56:37 +0100767 netlink_table_grab();
Denis V. Lunev869e58f2008-01-18 23:53:31 -0800768 BUG_ON(nl_table[sk->sk_protocol].registered == 0);
769 if (--nl_table[sk->sk_protocol].registered == 0) {
Eric Dumazet6d772ac2012-10-18 03:21:55 +0000770 struct listeners *old;
771
772 old = nl_deref_protected(nl_table[sk->sk_protocol].listeners);
773 RCU_INIT_POINTER(nl_table[sk->sk_protocol].listeners, NULL);
774 kfree_rcu(old, rcu);
Denis V. Lunev869e58f2008-01-18 23:53:31 -0800775 nl_table[sk->sk_protocol].module = NULL;
Pablo Neira Ayuso9785e102012-09-08 02:53:53 +0000776 nl_table[sk->sk_protocol].bind = NULL;
Richard Guy Briggs4f520902014-04-22 21:31:54 -0400777 nl_table[sk->sk_protocol].unbind = NULL;
Pablo Neira Ayuso9785e102012-09-08 02:53:53 +0000778 nl_table[sk->sk_protocol].flags = 0;
Denis V. Lunev869e58f2008-01-18 23:53:31 -0800779 nl_table[sk->sk_protocol].registered = 0;
780 }
Johannes Bergb10dcb32014-12-22 18:56:37 +0100781 netlink_table_ungrab();
Eric Dumazet658cb352012-04-22 21:30:21 +0000782 }
Patrick McHardy77247bb2005-08-14 19:27:13 -0700783
Patrick McHardyf7fa9b12005-08-15 12:29:13 -0700784 kfree(nlk->groups);
785 nlk->groups = NULL;
786
Eric Dumazet37558102008-11-24 14:05:22 -0800787 local_bh_disable();
Eric Dumazetc1fd3b92008-11-23 15:48:22 -0800788 sock_prot_inuse_add(sock_net(sk), &netlink_proto, -1);
Eric Dumazet37558102008-11-24 14:05:22 -0800789 local_bh_enable();
Thomas Graf21e49022015-01-02 23:00:22 +0100790 call_rcu(&nlk->rcu, deferred_put_nlk_sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 return 0;
792}
793
794static int netlink_autobind(struct socket *sock)
795{
796 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900797 struct net *net = sock_net(sk);
Gao fengda12c902013-06-06 14:49:11 +0800798 struct netlink_table *table = &nl_table[sk->sk_protocol];
Eric W. Biederman15e47302012-09-07 20:12:54 +0000799 s32 portid = task_tgid_vnr(current);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 int err;
Herbert Xub9fbe702015-05-17 10:45:34 +0800801 s32 rover = -4096;
802 bool ok;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803
804retry:
805 cond_resched();
Thomas Grafe3416942014-08-02 11:47:45 +0200806 rcu_read_lock();
Herbert Xub9fbe702015-05-17 10:45:34 +0800807 ok = !__netlink_lookup(table, portid, net);
808 rcu_read_unlock();
809 if (!ok) {
Thomas Grafe3416942014-08-02 11:47:45 +0200810 /* Bind collision, search negative portid values. */
Herbert Xub9fbe702015-05-17 10:45:34 +0800811 if (rover == -4096)
812 /* rover will be in range [S32_MIN, -4097] */
813 rover = S32_MIN + prandom_u32_max(-4096 - S32_MIN);
814 else if (rover >= -4096)
Thomas Grafe3416942014-08-02 11:47:45 +0200815 rover = -4097;
Herbert Xub9fbe702015-05-17 10:45:34 +0800816 portid = rover--;
Thomas Grafe3416942014-08-02 11:47:45 +0200817 goto retry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819
Herbert Xu8ea65f42015-01-26 14:02:56 +1100820 err = netlink_insert(sk, portid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821 if (err == -EADDRINUSE)
822 goto retry;
David S. Millerd470e3b2005-06-26 15:31:51 -0700823
824 /* If 2 threads race to autobind, that is fine. */
825 if (err == -EBUSY)
826 err = 0;
827
828 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829}
830
Eric W. Biedermanaa4cf942014-04-23 14:28:03 -0700831/**
832 * __netlink_ns_capable - General netlink message capability test
833 * @nsp: NETLINK_CB of the socket buffer holding a netlink command from userspace.
834 * @user_ns: The user namespace of the capability to use
835 * @cap: The capability to use
836 *
837 * Test to see if the opener of the socket we received the message
838 * from had when the netlink socket was created and the sender of the
839 * message has has the capability @cap in the user namespace @user_ns.
840 */
841bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
842 struct user_namespace *user_ns, int cap)
843{
Eric W. Biederman2d7a85f2014-05-30 11:04:00 -0700844 return ((nsp->flags & NETLINK_SKB_DST) ||
845 file_ns_capable(nsp->sk->sk_socket->file, user_ns, cap)) &&
846 ns_capable(user_ns, cap);
Eric W. Biedermanaa4cf942014-04-23 14:28:03 -0700847}
848EXPORT_SYMBOL(__netlink_ns_capable);
849
850/**
851 * netlink_ns_capable - General netlink message capability test
852 * @skb: socket buffer holding a netlink command from userspace
853 * @user_ns: The user namespace of the capability to use
854 * @cap: The capability to use
855 *
856 * Test to see if the opener of the socket we received the message
857 * from had when the netlink socket was created and the sender of the
858 * message has has the capability @cap in the user namespace @user_ns.
859 */
860bool netlink_ns_capable(const struct sk_buff *skb,
861 struct user_namespace *user_ns, int cap)
862{
863 return __netlink_ns_capable(&NETLINK_CB(skb), user_ns, cap);
864}
865EXPORT_SYMBOL(netlink_ns_capable);
866
867/**
868 * netlink_capable - Netlink global message capability test
869 * @skb: socket buffer holding a netlink command from userspace
870 * @cap: The capability to use
871 *
872 * Test to see if the opener of the socket we received the message
873 * from had when the netlink socket was created and the sender of the
874 * message has has the capability @cap in all user namespaces.
875 */
876bool netlink_capable(const struct sk_buff *skb, int cap)
877{
878 return netlink_ns_capable(skb, &init_user_ns, cap);
879}
880EXPORT_SYMBOL(netlink_capable);
881
882/**
883 * netlink_net_capable - Netlink network namespace message capability test
884 * @skb: socket buffer holding a netlink command from userspace
885 * @cap: The capability to use
886 *
887 * Test to see if the opener of the socket we received the message
888 * from had when the netlink socket was created and the sender of the
889 * message has has the capability @cap over the network namespace of
890 * the socket we received the message from.
891 */
892bool netlink_net_capable(const struct sk_buff *skb, int cap)
893{
894 return netlink_ns_capable(skb, sock_net(skb->sk)->user_ns, cap);
895}
896EXPORT_SYMBOL(netlink_net_capable);
897
Eric W. Biederman5187cd02014-04-23 14:25:48 -0700898static inline int netlink_allowed(const struct socket *sock, unsigned int flag)
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +0900899{
Pablo Neira Ayuso9785e102012-09-08 02:53:53 +0000900 return (nl_table[sock->sk->sk_protocol].flags & flag) ||
Eric W. Biedermandf008c92012-11-16 03:03:07 +0000901 ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN);
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +0900902}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903
Patrick McHardyf7fa9b12005-08-15 12:29:13 -0700904static void
905netlink_update_subscriptions(struct sock *sk, unsigned int subscriptions)
906{
907 struct netlink_sock *nlk = nlk_sk(sk);
908
909 if (nlk->subscriptions && !subscriptions)
910 __sk_del_bind_node(sk);
911 else if (!nlk->subscriptions && subscriptions)
912 sk_add_bind_node(sk, &nl_table[sk->sk_protocol].mc_list);
913 nlk->subscriptions = subscriptions;
914}
915
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700916static int netlink_realloc_groups(struct sock *sk)
Patrick McHardy513c2502005-09-06 15:43:59 -0700917{
918 struct netlink_sock *nlk = nlk_sk(sk);
919 unsigned int groups;
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700920 unsigned long *new_groups;
Patrick McHardy513c2502005-09-06 15:43:59 -0700921 int err = 0;
922
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700923 netlink_table_grab();
924
Patrick McHardy513c2502005-09-06 15:43:59 -0700925 groups = nl_table[sk->sk_protocol].groups;
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700926 if (!nl_table[sk->sk_protocol].registered) {
Patrick McHardy513c2502005-09-06 15:43:59 -0700927 err = -ENOENT;
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700928 goto out_unlock;
929 }
Patrick McHardy513c2502005-09-06 15:43:59 -0700930
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700931 if (nlk->ngroups >= groups)
932 goto out_unlock;
Patrick McHardy513c2502005-09-06 15:43:59 -0700933
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700934 new_groups = krealloc(nlk->groups, NLGRPSZ(groups), GFP_ATOMIC);
935 if (new_groups == NULL) {
936 err = -ENOMEM;
937 goto out_unlock;
938 }
Patrick McHardy6ac552f2007-12-04 00:19:38 -0800939 memset((char *)new_groups + NLGRPSZ(nlk->ngroups), 0,
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700940 NLGRPSZ(groups) - NLGRPSZ(nlk->ngroups));
941
942 nlk->groups = new_groups;
Patrick McHardy513c2502005-09-06 15:43:59 -0700943 nlk->ngroups = groups;
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700944 out_unlock:
945 netlink_table_ungrab();
946 return err;
Patrick McHardy513c2502005-09-06 15:43:59 -0700947}
948
Johannes Berg02c81ab2014-12-22 18:56:35 +0100949static void netlink_undo_bind(int group, long unsigned int groups,
Johannes Berg023e2cf2014-12-23 21:00:06 +0100950 struct sock *sk)
Richard Guy Briggs4f520902014-04-22 21:31:54 -0400951{
Johannes Berg023e2cf2014-12-23 21:00:06 +0100952 struct netlink_sock *nlk = nlk_sk(sk);
Richard Guy Briggs4f520902014-04-22 21:31:54 -0400953 int undo;
954
955 if (!nlk->netlink_unbind)
956 return;
957
958 for (undo = 0; undo < group; undo++)
Hiroaki SHIMODA6251edd2014-11-13 04:24:10 +0900959 if (test_bit(undo, &groups))
Pablo Neira8b7c36d2015-01-29 10:51:53 +0100960 nlk->netlink_unbind(sock_net(sk), undo + 1);
Richard Guy Briggs4f520902014-04-22 21:31:54 -0400961}
962
Patrick McHardy6ac552f2007-12-04 00:19:38 -0800963static int netlink_bind(struct socket *sock, struct sockaddr *addr,
964 int addr_len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965{
966 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900967 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968 struct netlink_sock *nlk = nlk_sk(sk);
969 struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
970 int err;
Richard Guy Briggs4f520902014-04-22 21:31:54 -0400971 long unsigned int groups = nladdr->nl_groups;
Herbert Xuda314c92015-09-22 11:38:56 +0800972 bool bound;
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +0900973
Hannes Frederic Sowa4e4b5372012-12-15 15:42:19 +0000974 if (addr_len < sizeof(struct sockaddr_nl))
975 return -EINVAL;
976
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 if (nladdr->nl_family != AF_NETLINK)
978 return -EINVAL;
979
980 /* Only superuser is allowed to listen multicasts */
Richard Guy Briggs4f520902014-04-22 21:31:54 -0400981 if (groups) {
Eric W. Biederman5187cd02014-04-23 14:25:48 -0700982 if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV))
Patrick McHardy513c2502005-09-06 15:43:59 -0700983 return -EPERM;
Johannes Bergb4ff4f02007-07-18 15:46:06 -0700984 err = netlink_realloc_groups(sk);
985 if (err)
986 return err;
Patrick McHardy513c2502005-09-06 15:43:59 -0700987 }
Dmitry Safonov4d502572018-07-30 18:32:36 +0100988
989 if (nlk->ngroups == 0)
990 groups = 0;
Dmitry Safonovc68c7722018-08-05 01:35:53 +0100991 else if (nlk->ngroups < 8*sizeof(groups))
992 groups &= (1UL << nlk->ngroups) - 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
Herbert Xuda314c92015-09-22 11:38:56 +0800994 bound = nlk->bound;
995 if (bound) {
996 /* Ensure nlk->portid is up-to-date. */
997 smp_rmb();
998
Eric W. Biederman15e47302012-09-07 20:12:54 +0000999 if (nladdr->nl_pid != nlk->portid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 return -EINVAL;
Herbert Xuda314c92015-09-22 11:38:56 +08001001 }
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001002
1003 if (nlk->netlink_bind && groups) {
1004 int group;
1005
Nikolay Aleksandrov4cf7fd82020-02-20 16:42:13 +02001006 /* nl_groups is a u32, so cap the maximum groups we can bind */
1007 for (group = 0; group < BITS_PER_TYPE(u32); group++) {
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001008 if (!test_bit(group, &groups))
1009 continue;
Pablo Neira8b7c36d2015-01-29 10:51:53 +01001010 err = nlk->netlink_bind(net, group + 1);
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001011 if (!err)
1012 continue;
Johannes Berg023e2cf2014-12-23 21:00:06 +01001013 netlink_undo_bind(group, groups, sk);
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001014 return err;
1015 }
1016 }
1017
Herbert Xuda314c92015-09-22 11:38:56 +08001018 /* No need for barriers here as we return to user-space without
1019 * using any of the bound attributes.
1020 */
1021 if (!bound) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 err = nladdr->nl_pid ?
Herbert Xu8ea65f42015-01-26 14:02:56 +11001023 netlink_insert(sk, nladdr->nl_pid) :
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 netlink_autobind(sock);
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001025 if (err) {
Nikolay Aleksandrov4cf7fd82020-02-20 16:42:13 +02001026 netlink_undo_bind(BITS_PER_TYPE(u32), groups, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 return err;
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001028 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 }
1030
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001031 if (!groups && (nlk->groups == NULL || !(u32)nlk->groups[0]))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 return 0;
1033
1034 netlink_table_grab();
Patrick McHardyf7fa9b12005-08-15 12:29:13 -07001035 netlink_update_subscriptions(sk, nlk->subscriptions +
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001036 hweight32(groups) -
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09001037 hweight32(nlk->groups[0]));
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001038 nlk->groups[0] = (nlk->groups[0] & ~0xffffffffUL) | groups;
Patrick McHardy4277a082006-03-20 18:52:01 -08001039 netlink_update_listeners(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040 netlink_table_ungrab();
1041
1042 return 0;
1043}
1044
1045static int netlink_connect(struct socket *sock, struct sockaddr *addr,
1046 int alen, int flags)
1047{
1048 int err = 0;
1049 struct sock *sk = sock->sk;
1050 struct netlink_sock *nlk = nlk_sk(sk);
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001051 struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052
Changli Gao6503d962010-03-31 22:58:26 +00001053 if (alen < sizeof(addr->sa_family))
1054 return -EINVAL;
1055
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 if (addr->sa_family == AF_UNSPEC) {
1057 sk->sk_state = NETLINK_UNCONNECTED;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001058 nlk->dst_portid = 0;
Patrick McHardyd629b832005-08-14 19:27:50 -07001059 nlk->dst_group = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 return 0;
1061 }
1062 if (addr->sa_family != AF_NETLINK)
1063 return -EINVAL;
1064
Alexander Potapenkocf105332018-03-23 13:49:02 +01001065 if (alen < sizeof(struct sockaddr_nl))
1066 return -EINVAL;
1067
Mike Pecovnik46833a82014-02-24 21:11:16 +01001068 if ((nladdr->nl_groups || nladdr->nl_pid) &&
Eric W. Biederman5187cd02014-04-23 14:25:48 -07001069 !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 return -EPERM;
1071
Herbert Xuda314c92015-09-22 11:38:56 +08001072 /* No need for barriers here as we return to user-space without
1073 * using any of the bound attributes.
1074 */
1075 if (!nlk->bound)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 err = netlink_autobind(sock);
1077
1078 if (err == 0) {
1079 sk->sk_state = NETLINK_CONNECTED;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001080 nlk->dst_portid = nladdr->nl_pid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001081 nlk->dst_group = ffs(nladdr->nl_groups);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 }
1083
1084 return err;
1085}
1086
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001087static int netlink_getname(struct socket *sock, struct sockaddr *addr,
1088 int *addr_len, int peer)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089{
1090 struct sock *sk = sock->sk;
1091 struct netlink_sock *nlk = nlk_sk(sk);
Cyrill Gorcunov13cfa972009-11-08 05:51:19 +00001092 DECLARE_SOCKADDR(struct sockaddr_nl *, nladdr, addr);
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09001093
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 nladdr->nl_family = AF_NETLINK;
1095 nladdr->nl_pad = 0;
1096 *addr_len = sizeof(*nladdr);
1097
1098 if (peer) {
Eric W. Biederman15e47302012-09-07 20:12:54 +00001099 nladdr->nl_pid = nlk->dst_portid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001100 nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101 } else {
Eric W. Biederman15e47302012-09-07 20:12:54 +00001102 nladdr->nl_pid = nlk->portid;
Patrick McHardy513c2502005-09-06 15:43:59 -07001103 nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104 }
1105 return 0;
1106}
1107
David Decotigny025c6812016-03-21 10:15:35 -07001108static int netlink_ioctl(struct socket *sock, unsigned int cmd,
1109 unsigned long arg)
1110{
1111 /* try to hand this ioctl down to the NIC drivers.
1112 */
1113 return -ENOIOCTLCMD;
1114}
1115
Eric W. Biederman15e47302012-09-07 20:12:54 +00001116static struct sock *netlink_getsockbyportid(struct sock *ssk, u32 portid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 struct sock *sock;
1119 struct netlink_sock *nlk;
1120
Eric W. Biederman15e47302012-09-07 20:12:54 +00001121 sock = netlink_lookup(sock_net(ssk), ssk->sk_protocol, portid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 if (!sock)
1123 return ERR_PTR(-ECONNREFUSED);
1124
1125 /* Don't bother queuing skb if kernel socket has no input function */
1126 nlk = nlk_sk(sock);
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001127 if (sock->sk_state == NETLINK_CONNECTED &&
Eric W. Biederman15e47302012-09-07 20:12:54 +00001128 nlk->dst_portid != nlk_sk(ssk)->portid) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 sock_put(sock);
1130 return ERR_PTR(-ECONNREFUSED);
1131 }
1132 return sock;
1133}
1134
1135struct sock *netlink_getsockbyfilp(struct file *filp)
1136{
Al Viro496ad9a2013-01-23 17:07:38 -05001137 struct inode *inode = file_inode(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 struct sock *sock;
1139
1140 if (!S_ISSOCK(inode->i_mode))
1141 return ERR_PTR(-ENOTSOCK);
1142
1143 sock = SOCKET_I(inode)->sk;
1144 if (sock->sk_family != AF_NETLINK)
1145 return ERR_PTR(-EINVAL);
1146
1147 sock_hold(sock);
1148 return sock;
1149}
1150
Pablo Neira3a365152013-06-28 03:04:23 +02001151static struct sk_buff *netlink_alloc_large_skb(unsigned int size,
1152 int broadcast)
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001153{
1154 struct sk_buff *skb;
1155 void *data;
1156
Pablo Neira3a365152013-06-28 03:04:23 +02001157 if (size <= NLMSG_GOODSIZE || broadcast)
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001158 return alloc_skb(size, GFP_KERNEL);
1159
Pablo Neira3a365152013-06-28 03:04:23 +02001160 size = SKB_DATA_ALIGN(size) +
1161 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001162
1163 data = vmalloc(size);
1164 if (data == NULL)
Pablo Neira3a365152013-06-28 03:04:23 +02001165 return NULL;
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001166
Eric Dumazet2ea2f622015-04-24 16:05:01 -07001167 skb = __build_skb(data, size);
Pablo Neira3a365152013-06-28 03:04:23 +02001168 if (skb == NULL)
1169 vfree(data);
Eric Dumazet2ea2f622015-04-24 16:05:01 -07001170 else
Pablo Neira3a365152013-06-28 03:04:23 +02001171 skb->destructor = netlink_skb_destructor;
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001172
1173 return skb;
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001174}
1175
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176/*
1177 * Attach a skb to a netlink socket.
1178 * The caller must hold a reference to the destination socket. On error, the
1179 * reference is dropped. The skb is not send to the destination, just all
1180 * all error checks are performed and memory in the queue is reserved.
1181 * Return values:
1182 * < 0: error. skb freed, reference to sock dropped.
1183 * 0: continue
1184 * 1: repeat lookup - reference dropped while waiting for socket memory.
1185 */
Denis V. Lunev9457afe2008-06-05 11:23:39 -07001186int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
Patrick McHardyc3d8d1e2007-11-07 02:42:09 -08001187 long *timeo, struct sock *ssk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188{
1189 struct netlink_sock *nlk;
1190
1191 nlk = nlk_sk(sk);
1192
Patrick McHardy5fd96122013-04-17 06:47:03 +00001193 if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
Florian Westphald1b4c682016-02-18 15:03:24 +01001194 test_bit(NETLINK_S_CONGESTED, &nlk->state))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 DECLARE_WAITQUEUE(wait, current);
Patrick McHardyc3d8d1e2007-11-07 02:42:09 -08001196 if (!*timeo) {
Denis V. Lunevaed81562007-10-10 21:14:32 -07001197 if (!ssk || netlink_is_kernel(ssk))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 netlink_overrun(sk);
1199 sock_put(sk);
1200 kfree_skb(skb);
1201 return -EAGAIN;
1202 }
1203
1204 __set_current_state(TASK_INTERRUPTIBLE);
1205 add_wait_queue(&nlk->wait, &wait);
1206
1207 if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001208 test_bit(NETLINK_S_CONGESTED, &nlk->state)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 !sock_flag(sk, SOCK_DEAD))
Patrick McHardyc3d8d1e2007-11-07 02:42:09 -08001210 *timeo = schedule_timeout(*timeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
1212 __set_current_state(TASK_RUNNING);
1213 remove_wait_queue(&nlk->wait, &wait);
1214 sock_put(sk);
1215
1216 if (signal_pending(current)) {
1217 kfree_skb(skb);
Patrick McHardyc3d8d1e2007-11-07 02:42:09 -08001218 return sock_intr_errno(*timeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 }
1220 return 1;
1221 }
Patrick McHardycf0a0182013-04-17 06:47:00 +00001222 netlink_skb_set_owner_r(skb, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 return 0;
1224}
1225
Eric Dumazet4a7e7c22012-04-05 22:17:46 +00001226static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 int len = skb->len;
1229
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +02001230 netlink_deliver_tap(skb);
1231
Florian Westphald1b4c682016-02-18 15:03:24 +01001232 skb_queue_tail(&sk->sk_receive_queue, skb);
David S. Miller676d2362014-04-11 16:15:36 -04001233 sk->sk_data_ready(sk);
Eric Dumazet4a7e7c22012-04-05 22:17:46 +00001234 return len;
1235}
1236
1237int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
1238{
1239 int len = __netlink_sendskb(sk, skb);
1240
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 sock_put(sk);
1242 return len;
1243}
1244
1245void netlink_detachskb(struct sock *sk, struct sk_buff *skb)
1246{
1247 kfree_skb(skb);
1248 sock_put(sk);
1249}
1250
stephen hemmingerb57ef81f2011-12-22 08:52:02 +00001251static struct sk_buff *netlink_trim(struct sk_buff *skb, gfp_t allocation)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252{
1253 int delta;
1254
Patrick McHardy1298ca42013-04-17 06:46:59 +00001255 WARN_ON(skb->sk != NULL);
Arnaldo Carvalho de Melo4305b542007-04-19 20:43:29 -07001256 delta = skb->end - skb->tail;
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001257 if (is_vmalloc_addr(skb->head) || delta * 2 < skb->truesize)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258 return skb;
1259
1260 if (skb_shared(skb)) {
1261 struct sk_buff *nskb = skb_clone(skb, allocation);
1262 if (!nskb)
1263 return skb;
Eric Dumazet8460c002012-04-19 02:24:28 +00001264 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265 skb = nskb;
1266 }
1267
1268 if (!pskb_expand_head(skb, 0, -delta, allocation))
1269 skb->truesize -= delta;
1270
1271 return skb;
1272}
1273
Eric W. Biederman3fbc2902012-05-24 17:21:27 -06001274static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb,
1275 struct sock *ssk)
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001276{
1277 int ret;
1278 struct netlink_sock *nlk = nlk_sk(sk);
1279
1280 ret = -ECONNREFUSED;
1281 if (nlk->netlink_rcv != NULL) {
1282 ret = skb->len;
Patrick McHardycf0a0182013-04-17 06:47:00 +00001283 netlink_skb_set_owner_r(skb, sk);
Patrick McHardye32123e2013-04-17 06:46:57 +00001284 NETLINK_CB(skb).sk = ssk;
Daniel Borkmann73bfd372013-12-23 14:35:55 +01001285 netlink_deliver_tap_kernel(sk, ssk, skb);
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001286 nlk->netlink_rcv(skb);
Eric Dumazetbfb253c2012-04-22 21:30:29 +00001287 consume_skb(skb);
1288 } else {
1289 kfree_skb(skb);
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001290 }
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001291 sock_put(sk);
1292 return ret;
1293}
1294
1295int netlink_unicast(struct sock *ssk, struct sk_buff *skb,
Eric W. Biederman15e47302012-09-07 20:12:54 +00001296 u32 portid, int nonblock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297{
1298 struct sock *sk;
1299 int err;
1300 long timeo;
1301
1302 skb = netlink_trim(skb, gfp_any());
1303
1304 timeo = sock_sndtimeo(ssk, nonblock);
1305retry:
Eric W. Biederman15e47302012-09-07 20:12:54 +00001306 sk = netlink_getsockbyportid(ssk, portid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 if (IS_ERR(sk)) {
1308 kfree_skb(skb);
1309 return PTR_ERR(sk);
1310 }
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001311 if (netlink_is_kernel(sk))
Eric W. Biederman3fbc2902012-05-24 17:21:27 -06001312 return netlink_unicast_kernel(sk, skb, ssk);
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001313
Stephen Hemmingerb1153f22008-03-21 15:46:12 -07001314 if (sk_filter(sk, skb)) {
Wang Chen84874602008-07-01 19:55:09 -07001315 err = skb->len;
Stephen Hemmingerb1153f22008-03-21 15:46:12 -07001316 kfree_skb(skb);
1317 sock_put(sk);
1318 return err;
1319 }
1320
Denis V. Lunev9457afe2008-06-05 11:23:39 -07001321 err = netlink_attachskb(sk, skb, &timeo, ssk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 if (err == 1)
1323 goto retry;
1324 if (err)
1325 return err;
1326
Denis V. Lunev7ee015e2007-10-10 21:14:03 -07001327 return netlink_sendskb(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001329EXPORT_SYMBOL(netlink_unicast);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330
Patrick McHardy4277a082006-03-20 18:52:01 -08001331int netlink_has_listeners(struct sock *sk, unsigned int group)
1332{
1333 int res = 0;
Eric Dumazet5c398dc2010-10-24 04:27:10 +00001334 struct listeners *listeners;
Patrick McHardy4277a082006-03-20 18:52:01 -08001335
Denis V. Lunevaed81562007-10-10 21:14:32 -07001336 BUG_ON(!netlink_is_kernel(sk));
Johannes Bergb4ff4f02007-07-18 15:46:06 -07001337
1338 rcu_read_lock();
1339 listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners);
1340
Eric Dumazet6d772ac2012-10-18 03:21:55 +00001341 if (listeners && group - 1 < nl_table[sk->sk_protocol].groups)
Eric Dumazet5c398dc2010-10-24 04:27:10 +00001342 res = test_bit(group - 1, listeners->masks);
Johannes Bergb4ff4f02007-07-18 15:46:06 -07001343
1344 rcu_read_unlock();
1345
Patrick McHardy4277a082006-03-20 18:52:01 -08001346 return res;
1347}
1348EXPORT_SYMBOL_GPL(netlink_has_listeners);
1349
stephen hemmingerb57ef81f2011-12-22 08:52:02 +00001350static int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351{
1352 struct netlink_sock *nlk = nlk_sk(sk);
1353
1354 if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001355 !test_bit(NETLINK_S_CONGESTED, &nlk->state)) {
Patrick McHardycf0a0182013-04-17 06:47:00 +00001356 netlink_skb_set_owner_r(skb, sk);
Eric Dumazet4a7e7c22012-04-05 22:17:46 +00001357 __netlink_sendskb(sk, skb);
stephen hemminger2c6458002011-12-22 08:52:03 +00001358 return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 }
1360 return -1;
1361}
1362
1363struct netlink_broadcast_data {
1364 struct sock *exclude_sk;
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02001365 struct net *net;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001366 u32 portid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367 u32 group;
1368 int failure;
Pablo Neira Ayusoff491a72009-02-05 23:56:36 -08001369 int delivery_failure;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370 int congested;
1371 int delivered;
Al Viro7d877f32005-10-21 03:20:43 -04001372 gfp_t allocation;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 struct sk_buff *skb, *skb2;
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001374 int (*tx_filter)(struct sock *dsk, struct sk_buff *skb, void *data);
1375 void *tx_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376};
1377
Rami Rosen46c95212014-07-01 21:17:35 +03001378static void do_one_broadcast(struct sock *sk,
1379 struct netlink_broadcast_data *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380{
1381 struct netlink_sock *nlk = nlk_sk(sk);
1382 int val;
1383
1384 if (p->exclude_sk == sk)
Rami Rosen46c95212014-07-01 21:17:35 +03001385 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386
Eric W. Biederman15e47302012-09-07 20:12:54 +00001387 if (nlk->portid == p->portid || p->group - 1 >= nlk->ngroups ||
Patrick McHardyf7fa9b12005-08-15 12:29:13 -07001388 !test_bit(p->group - 1, nlk->groups))
Rami Rosen46c95212014-07-01 21:17:35 +03001389 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001391 if (!net_eq(sock_net(sk), p->net)) {
1392 if (!(nlk->flags & NETLINK_F_LISTEN_ALL_NSID))
1393 return;
1394
1395 if (!peernet_has_id(sock_net(sk), p->net))
1396 return;
1397
1398 if (!file_ns_capable(sk->sk_socket->file, p->net->user_ns,
1399 CAP_NET_BROADCAST))
1400 return;
1401 }
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02001402
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403 if (p->failure) {
1404 netlink_overrun(sk);
Rami Rosen46c95212014-07-01 21:17:35 +03001405 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 }
1407
1408 sock_hold(sk);
1409 if (p->skb2 == NULL) {
Tommy S. Christensen68acc022005-05-19 13:06:35 -07001410 if (skb_shared(p->skb)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 p->skb2 = skb_clone(p->skb, p->allocation);
1412 } else {
Tommy S. Christensen68acc022005-05-19 13:06:35 -07001413 p->skb2 = skb_get(p->skb);
1414 /*
1415 * skb ownership may have been set when
1416 * delivered to a previous socket.
1417 */
1418 skb_orphan(p->skb2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 }
1420 }
1421 if (p->skb2 == NULL) {
1422 netlink_overrun(sk);
1423 /* Clone failed. Notify ALL listeners. */
1424 p->failure = 1;
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001425 if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR)
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001426 p->delivery_failure = 1;
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001427 goto out;
1428 }
1429 if (p->tx_filter && p->tx_filter(sk, p->skb2, p->tx_data)) {
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001430 kfree_skb(p->skb2);
1431 p->skb2 = NULL;
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001432 goto out;
1433 }
1434 if (sk_filter(sk, p->skb2)) {
Stephen Hemmingerb1153f22008-03-21 15:46:12 -07001435 kfree_skb(p->skb2);
1436 p->skb2 = NULL;
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001437 goto out;
1438 }
1439 NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
1440 NETLINK_CB(p->skb2).nsid_is_set = true;
1441 val = netlink_broadcast_deliver(sk, p->skb2);
1442 if (val < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 netlink_overrun(sk);
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001444 if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR)
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001445 p->delivery_failure = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 } else {
1447 p->congested |= val;
1448 p->delivered = 1;
1449 p->skb2 = NULL;
1450 }
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001451out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 sock_put(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453}
1454
Eric W. Biederman15e47302012-09-07 20:12:54 +00001455int netlink_broadcast_filtered(struct sock *ssk, struct sk_buff *skb, u32 portid,
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001456 u32 group, gfp_t allocation,
1457 int (*filter)(struct sock *dsk, struct sk_buff *skb, void *data),
1458 void *filter_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459{
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001460 struct net *net = sock_net(ssk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461 struct netlink_broadcast_data info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 struct sock *sk;
1463
1464 skb = netlink_trim(skb, allocation);
1465
1466 info.exclude_sk = ssk;
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02001467 info.net = net;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001468 info.portid = portid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 info.group = group;
1470 info.failure = 0;
Pablo Neira Ayusoff491a72009-02-05 23:56:36 -08001471 info.delivery_failure = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 info.congested = 0;
1473 info.delivered = 0;
1474 info.allocation = allocation;
1475 info.skb = skb;
1476 info.skb2 = NULL;
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001477 info.tx_filter = filter;
1478 info.tx_data = filter_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479
1480 /* While we sleep in clone, do not allow to change socket list */
1481
1482 netlink_lock_table();
1483
Sasha Levinb67bfe02013-02-27 17:06:00 -08001484 sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 do_one_broadcast(sk, &info);
1486
Neil Horman70d4bf62010-07-20 06:45:56 +00001487 consume_skb(skb);
Tommy S. Christensenaa1c6a62005-05-19 13:07:32 -07001488
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 netlink_unlock_table();
1490
Neil Horman70d4bf62010-07-20 06:45:56 +00001491 if (info.delivery_failure) {
1492 kfree_skb(info.skb2);
Pablo Neira Ayusoff491a72009-02-05 23:56:36 -08001493 return -ENOBUFS;
Eric Dumazet658cb352012-04-22 21:30:21 +00001494 }
1495 consume_skb(info.skb2);
Pablo Neira Ayusoff491a72009-02-05 23:56:36 -08001496
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 if (info.delivered) {
Mel Gormand0164ad2015-11-06 16:28:21 -08001498 if (info.congested && gfpflags_allow_blocking(allocation))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 yield();
1500 return 0;
1501 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 return -ESRCH;
1503}
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001504EXPORT_SYMBOL(netlink_broadcast_filtered);
1505
Eric W. Biederman15e47302012-09-07 20:12:54 +00001506int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 portid,
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001507 u32 group, gfp_t allocation)
1508{
Eric W. Biederman15e47302012-09-07 20:12:54 +00001509 return netlink_broadcast_filtered(ssk, skb, portid, group, allocation,
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001510 NULL, NULL);
1511}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001512EXPORT_SYMBOL(netlink_broadcast);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513
1514struct netlink_set_err_data {
1515 struct sock *exclude_sk;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001516 u32 portid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 u32 group;
1518 int code;
1519};
1520
stephen hemmingerb57ef81f2011-12-22 08:52:02 +00001521static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522{
1523 struct netlink_sock *nlk = nlk_sk(sk);
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001524 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525
1526 if (sk == p->exclude_sk)
1527 goto out;
1528
Octavian Purdila09ad9bc2009-11-25 15:14:13 -08001529 if (!net_eq(sock_net(sk), sock_net(p->exclude_sk)))
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02001530 goto out;
1531
Eric W. Biederman15e47302012-09-07 20:12:54 +00001532 if (nlk->portid == p->portid || p->group - 1 >= nlk->ngroups ||
Patrick McHardyf7fa9b12005-08-15 12:29:13 -07001533 !test_bit(p->group - 1, nlk->groups))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 goto out;
1535
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001536 if (p->code == ENOBUFS && nlk->flags & NETLINK_F_RECV_NO_ENOBUFS) {
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001537 ret = 1;
1538 goto out;
1539 }
1540
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 sk->sk_err = p->code;
1542 sk->sk_error_report(sk);
1543out:
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001544 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545}
1546
Pablo Neira Ayuso4843b932009-03-03 23:37:30 -08001547/**
1548 * netlink_set_err - report error to broadcast listeners
1549 * @ssk: the kernel netlink socket, as returned by netlink_kernel_create()
Eric W. Biederman15e47302012-09-07 20:12:54 +00001550 * @portid: the PORTID of a process that we want to skip (if any)
Johannes Berg840e93f22013-11-19 10:35:40 +01001551 * @group: the broadcast group that will notice the error
Pablo Neira Ayuso4843b932009-03-03 23:37:30 -08001552 * @code: error code, must be negative (as usual in kernelspace)
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001553 *
1554 * This function returns the number of broadcast listeners that have set the
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001555 * NETLINK_NO_ENOBUFS socket option.
Pablo Neira Ayuso4843b932009-03-03 23:37:30 -08001556 */
Eric W. Biederman15e47302012-09-07 20:12:54 +00001557int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558{
1559 struct netlink_set_err_data info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 struct sock *sk;
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001561 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562
1563 info.exclude_sk = ssk;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001564 info.portid = portid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 info.group = group;
Pablo Neira Ayuso4843b932009-03-03 23:37:30 -08001566 /* sk->sk_err wants a positive error value */
1567 info.code = -code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568
1569 read_lock(&nl_table_lock);
1570
Sasha Levinb67bfe02013-02-27 17:06:00 -08001571 sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list)
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001572 ret += do_one_set_err(sk, &info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573
1574 read_unlock(&nl_table_lock);
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001575 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576}
Pablo Neira Ayusodd5b6ce2009-03-23 13:21:06 +01001577EXPORT_SYMBOL(netlink_set_err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578
Johannes Berg84659eb2007-07-18 15:47:05 -07001579/* must be called with netlink table grabbed */
1580static void netlink_update_socket_mc(struct netlink_sock *nlk,
1581 unsigned int group,
1582 int is_new)
1583{
1584 int old, new = !!is_new, subscriptions;
1585
1586 old = test_bit(group - 1, nlk->groups);
1587 subscriptions = nlk->subscriptions - old + new;
1588 if (new)
1589 __set_bit(group - 1, nlk->groups);
1590 else
1591 __clear_bit(group - 1, nlk->groups);
1592 netlink_update_subscriptions(&nlk->sk, subscriptions);
1593 netlink_update_listeners(&nlk->sk);
1594}
1595
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001596static int netlink_setsockopt(struct socket *sock, int level, int optname,
David S. Millerb7058842009-09-30 16:12:20 -07001597 char __user *optval, unsigned int optlen)
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001598{
1599 struct sock *sk = sock->sk;
1600 struct netlink_sock *nlk = nlk_sk(sk);
Johannes Bergeb496532007-07-18 02:07:51 -07001601 unsigned int val = 0;
1602 int err;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001603
1604 if (level != SOL_NETLINK)
1605 return -ENOPROTOOPT;
1606
Florian Westphald1b4c682016-02-18 15:03:24 +01001607 if (optlen >= sizeof(int) &&
Johannes Bergeb496532007-07-18 02:07:51 -07001608 get_user(val, (unsigned int __user *)optval))
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001609 return -EFAULT;
1610
1611 switch (optname) {
1612 case NETLINK_PKTINFO:
1613 if (val)
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001614 nlk->flags |= NETLINK_F_RECV_PKTINFO;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001615 else
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001616 nlk->flags &= ~NETLINK_F_RECV_PKTINFO;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001617 err = 0;
1618 break;
1619 case NETLINK_ADD_MEMBERSHIP:
1620 case NETLINK_DROP_MEMBERSHIP: {
Eric W. Biederman5187cd02014-04-23 14:25:48 -07001621 if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV))
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001622 return -EPERM;
Johannes Bergb4ff4f02007-07-18 15:46:06 -07001623 err = netlink_realloc_groups(sk);
1624 if (err)
1625 return err;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001626 if (!val || val - 1 >= nlk->ngroups)
1627 return -EINVAL;
Richard Guy Briggs7774d5e2014-04-22 21:31:55 -04001628 if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) {
Johannes Berg023e2cf2014-12-23 21:00:06 +01001629 err = nlk->netlink_bind(sock_net(sk), val);
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001630 if (err)
1631 return err;
1632 }
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001633 netlink_table_grab();
Johannes Berg84659eb2007-07-18 15:47:05 -07001634 netlink_update_socket_mc(nlk, val,
1635 optname == NETLINK_ADD_MEMBERSHIP);
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001636 netlink_table_ungrab();
Richard Guy Briggs7774d5e2014-04-22 21:31:55 -04001637 if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind)
Johannes Berg023e2cf2014-12-23 21:00:06 +01001638 nlk->netlink_unbind(sock_net(sk), val);
Pablo Neira Ayuso03292742012-06-29 06:15:22 +00001639
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001640 err = 0;
1641 break;
1642 }
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001643 case NETLINK_BROADCAST_ERROR:
1644 if (val)
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001645 nlk->flags |= NETLINK_F_BROADCAST_SEND_ERROR;
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001646 else
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001647 nlk->flags &= ~NETLINK_F_BROADCAST_SEND_ERROR;
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001648 err = 0;
1649 break;
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07001650 case NETLINK_NO_ENOBUFS:
1651 if (val) {
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001652 nlk->flags |= NETLINK_F_RECV_NO_ENOBUFS;
1653 clear_bit(NETLINK_S_CONGESTED, &nlk->state);
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07001654 wake_up_interruptible(&nlk->wait);
Eric Dumazet658cb352012-04-22 21:30:21 +00001655 } else {
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001656 nlk->flags &= ~NETLINK_F_RECV_NO_ENOBUFS;
Eric Dumazet658cb352012-04-22 21:30:21 +00001657 }
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07001658 err = 0;
1659 break;
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001660 case NETLINK_LISTEN_ALL_NSID:
1661 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_BROADCAST))
1662 return -EPERM;
1663
1664 if (val)
1665 nlk->flags |= NETLINK_F_LISTEN_ALL_NSID;
1666 else
1667 nlk->flags &= ~NETLINK_F_LISTEN_ALL_NSID;
1668 err = 0;
1669 break;
Christophe Ricard0a6a3a22015-08-28 07:07:48 +02001670 case NETLINK_CAP_ACK:
1671 if (val)
1672 nlk->flags |= NETLINK_F_CAP_ACK;
1673 else
1674 nlk->flags &= ~NETLINK_F_CAP_ACK;
1675 err = 0;
1676 break;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001677 default:
1678 err = -ENOPROTOOPT;
1679 }
1680 return err;
1681}
1682
1683static int netlink_getsockopt(struct socket *sock, int level, int optname,
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09001684 char __user *optval, int __user *optlen)
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001685{
1686 struct sock *sk = sock->sk;
1687 struct netlink_sock *nlk = nlk_sk(sk);
1688 int len, val, err;
1689
1690 if (level != SOL_NETLINK)
1691 return -ENOPROTOOPT;
1692
1693 if (get_user(len, optlen))
1694 return -EFAULT;
1695 if (len < 0)
1696 return -EINVAL;
1697
1698 switch (optname) {
1699 case NETLINK_PKTINFO:
1700 if (len < sizeof(int))
1701 return -EINVAL;
1702 len = sizeof(int);
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001703 val = nlk->flags & NETLINK_F_RECV_PKTINFO ? 1 : 0;
Heiko Carstensa27b58f2006-10-30 15:06:12 -08001704 if (put_user(len, optlen) ||
1705 put_user(val, optval))
1706 return -EFAULT;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001707 err = 0;
1708 break;
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001709 case NETLINK_BROADCAST_ERROR:
1710 if (len < sizeof(int))
1711 return -EINVAL;
1712 len = sizeof(int);
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001713 val = nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR ? 1 : 0;
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001714 if (put_user(len, optlen) ||
1715 put_user(val, optval))
1716 return -EFAULT;
1717 err = 0;
1718 break;
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07001719 case NETLINK_NO_ENOBUFS:
1720 if (len < sizeof(int))
1721 return -EINVAL;
1722 len = sizeof(int);
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001723 val = nlk->flags & NETLINK_F_RECV_NO_ENOBUFS ? 1 : 0;
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07001724 if (put_user(len, optlen) ||
1725 put_user(val, optval))
1726 return -EFAULT;
1727 err = 0;
1728 break;
David Herrmannb42be382015-06-17 17:14:33 +02001729 case NETLINK_LIST_MEMBERSHIPS: {
1730 int pos, idx, shift;
1731
1732 err = 0;
David Herrmann47191d62015-10-21 11:47:43 +02001733 netlink_lock_table();
David Herrmannb42be382015-06-17 17:14:33 +02001734 for (pos = 0; pos * 8 < nlk->ngroups; pos += sizeof(u32)) {
1735 if (len - pos < sizeof(u32))
1736 break;
1737
1738 idx = pos / sizeof(unsigned long);
1739 shift = (pos % sizeof(unsigned long)) * 8;
1740 if (put_user((u32)(nlk->groups[idx] >> shift),
1741 (u32 __user *)(optval + pos))) {
1742 err = -EFAULT;
1743 break;
1744 }
1745 }
1746 if (put_user(ALIGN(nlk->ngroups / 8, sizeof(u32)), optlen))
1747 err = -EFAULT;
David Herrmann47191d62015-10-21 11:47:43 +02001748 netlink_unlock_table();
David Herrmannb42be382015-06-17 17:14:33 +02001749 break;
1750 }
Christophe Ricard0a6a3a22015-08-28 07:07:48 +02001751 case NETLINK_CAP_ACK:
1752 if (len < sizeof(int))
1753 return -EINVAL;
1754 len = sizeof(int);
1755 val = nlk->flags & NETLINK_F_CAP_ACK ? 1 : 0;
1756 if (put_user(len, optlen) ||
1757 put_user(val, optval))
1758 return -EFAULT;
1759 err = 0;
1760 break;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001761 default:
1762 err = -ENOPROTOOPT;
1763 }
1764 return err;
1765}
1766
1767static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
1768{
1769 struct nl_pktinfo info;
1770
1771 info.group = NETLINK_CB(skb).dst_group;
1772 put_cmsg(msg, SOL_NETLINK, NETLINK_PKTINFO, sizeof(info), &info);
1773}
1774
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001775static void netlink_cmsg_listen_all_nsid(struct sock *sk, struct msghdr *msg,
1776 struct sk_buff *skb)
1777{
1778 if (!NETLINK_CB(skb).nsid_is_set)
1779 return;
1780
1781 put_cmsg(msg, SOL_NETLINK, NETLINK_LISTEN_ALL_NSID, sizeof(int),
1782 &NETLINK_CB(skb).nsid);
1783}
1784
Ying Xue1b784142015-03-02 15:37:48 +08001785static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 struct sock *sk = sock->sk;
1788 struct netlink_sock *nlk = nlk_sk(sk);
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001789 DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name);
Eric W. Biederman15e47302012-09-07 20:12:54 +00001790 u32 dst_portid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001791 u32 dst_group;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 struct sk_buff *skb;
1793 int err;
1794 struct scm_cookie scm;
Eric W. Biederman2d7a85f2014-05-30 11:04:00 -07001795 u32 netlink_skb_flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796
1797 if (msg->msg_flags&MSG_OOB)
1798 return -EOPNOTSUPP;
1799
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001800 err = scm_send(sock, msg, &scm, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 if (err < 0)
1802 return err;
1803
1804 if (msg->msg_namelen) {
Eric W. Biedermanb47030c2010-06-13 03:31:06 +00001805 err = -EINVAL;
Eric Dumazet473ac552018-04-07 13:42:37 -07001806 if (msg->msg_namelen < sizeof(struct sockaddr_nl))
1807 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 if (addr->nl_family != AF_NETLINK)
Eric W. Biedermanb47030c2010-06-13 03:31:06 +00001809 goto out;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001810 dst_portid = addr->nl_pid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001811 dst_group = ffs(addr->nl_groups);
Eric W. Biedermanb47030c2010-06-13 03:31:06 +00001812 err = -EPERM;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001813 if ((dst_group || dst_portid) &&
Eric W. Biederman5187cd02014-04-23 14:25:48 -07001814 !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
Eric W. Biedermanb47030c2010-06-13 03:31:06 +00001815 goto out;
Eric W. Biederman2d7a85f2014-05-30 11:04:00 -07001816 netlink_skb_flags |= NETLINK_SKB_DST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 } else {
Eric W. Biederman15e47302012-09-07 20:12:54 +00001818 dst_portid = nlk->dst_portid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001819 dst_group = nlk->dst_group;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 }
1821
Herbert Xuda314c92015-09-22 11:38:56 +08001822 if (!nlk->bound) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 err = netlink_autobind(sock);
1824 if (err)
1825 goto out;
Herbert Xuda314c92015-09-22 11:38:56 +08001826 } else {
1827 /* Ensure nlk is hashed and visible. */
1828 smp_rmb();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 }
1830
1831 err = -EMSGSIZE;
1832 if (len > sk->sk_sndbuf - 32)
1833 goto out;
1834 err = -ENOBUFS;
Pablo Neira3a365152013-06-28 03:04:23 +02001835 skb = netlink_alloc_large_skb(len, dst_group);
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001836 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 goto out;
1838
Eric W. Biederman15e47302012-09-07 20:12:54 +00001839 NETLINK_CB(skb).portid = nlk->portid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001840 NETLINK_CB(skb).dst_group = dst_group;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001841 NETLINK_CB(skb).creds = scm.creds;
Eric W. Biederman2d7a85f2014-05-30 11:04:00 -07001842 NETLINK_CB(skb).flags = netlink_skb_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 err = -EFAULT;
Al Viro6ce8e9c2014-04-06 21:25:44 -04001845 if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 kfree_skb(skb);
1847 goto out;
1848 }
1849
1850 err = security_netlink_send(sk, skb);
1851 if (err) {
1852 kfree_skb(skb);
1853 goto out;
1854 }
1855
Patrick McHardyd629b832005-08-14 19:27:50 -07001856 if (dst_group) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 atomic_inc(&skb->users);
Eric W. Biederman15e47302012-09-07 20:12:54 +00001858 netlink_broadcast(sk, skb, dst_portid, dst_group, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 }
Eric W. Biederman15e47302012-09-07 20:12:54 +00001860 err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags&MSG_DONTWAIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861
1862out:
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001863 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 return err;
1865}
1866
Ying Xue1b784142015-03-02 15:37:48 +08001867static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 int flags)
1869{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 struct scm_cookie scm;
1871 struct sock *sk = sock->sk;
1872 struct netlink_sock *nlk = nlk_sk(sk);
1873 int noblock = flags&MSG_DONTWAIT;
1874 size_t copied;
Johannes Berg68d6ac62010-08-15 21:20:44 +00001875 struct sk_buff *skb, *data_skb;
Andrey Vaginb44d2112011-02-21 02:40:47 +00001876 int err, ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877
1878 if (flags&MSG_OOB)
1879 return -EOPNOTSUPP;
1880
1881 copied = 0;
1882
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001883 skb = skb_recv_datagram(sk, flags, noblock, &err);
1884 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 goto out;
1886
Johannes Berg68d6ac62010-08-15 21:20:44 +00001887 data_skb = skb;
1888
Johannes Berg1dacc762009-07-01 11:26:02 +00001889#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
1890 if (unlikely(skb_shinfo(skb)->frag_list)) {
Johannes Berg1dacc762009-07-01 11:26:02 +00001891 /*
Johannes Berg68d6ac62010-08-15 21:20:44 +00001892 * If this skb has a frag_list, then here that means that we
1893 * will have to use the frag_list skb's data for compat tasks
1894 * and the regular skb's data for normal (non-compat) tasks.
Johannes Berg1dacc762009-07-01 11:26:02 +00001895 *
Johannes Berg68d6ac62010-08-15 21:20:44 +00001896 * If we need to send the compat skb, assign it to the
1897 * 'data_skb' variable so that it will be used below for data
1898 * copying. We keep 'skb' for everything else, including
1899 * freeing both later.
Johannes Berg1dacc762009-07-01 11:26:02 +00001900 */
Johannes Berg68d6ac62010-08-15 21:20:44 +00001901 if (flags & MSG_CMSG_COMPAT)
1902 data_skb = skb_shinfo(skb)->frag_list;
Johannes Berg1dacc762009-07-01 11:26:02 +00001903 }
1904#endif
1905
Eric Dumazet9063e212014-03-07 12:02:33 -08001906 /* Record the max length of recvmsg() calls for future allocations */
1907 nlk->max_recvmsg_len = max(nlk->max_recvmsg_len, len);
1908 nlk->max_recvmsg_len = min_t(size_t, nlk->max_recvmsg_len,
Eric Dumazetd35c99f2016-10-06 04:13:18 +09001909 SKB_WITH_OVERHEAD(32768));
Eric Dumazet9063e212014-03-07 12:02:33 -08001910
Johannes Berg68d6ac62010-08-15 21:20:44 +00001911 copied = data_skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 if (len < copied) {
1913 msg->msg_flags |= MSG_TRUNC;
1914 copied = len;
1915 }
1916
Johannes Berg68d6ac62010-08-15 21:20:44 +00001917 skb_reset_transport_header(data_skb);
David S. Miller51f3d022014-11-05 16:46:40 -05001918 err = skb_copy_datagram_msg(data_skb, 0, msg, copied);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919
1920 if (msg->msg_name) {
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001921 DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 addr->nl_family = AF_NETLINK;
1923 addr->nl_pad = 0;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001924 addr->nl_pid = NETLINK_CB(skb).portid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001925 addr->nl_groups = netlink_group_mask(NETLINK_CB(skb).dst_group);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 msg->msg_namelen = sizeof(*addr);
1927 }
1928
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001929 if (nlk->flags & NETLINK_F_RECV_PKTINFO)
Patrick McHardycc9a06c2006-03-12 20:34:27 -08001930 netlink_cmsg_recv_pktinfo(msg, skb);
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001931 if (nlk->flags & NETLINK_F_LISTEN_ALL_NSID)
1932 netlink_cmsg_listen_all_nsid(sk, msg, skb);
Patrick McHardycc9a06c2006-03-12 20:34:27 -08001933
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001934 memset(&scm, 0, sizeof(scm));
1935 scm.creds = *NETLINK_CREDS(skb);
Patrick McHardy188ccb52007-05-03 03:27:01 -07001936 if (flags & MSG_TRUNC)
Johannes Berg68d6ac62010-08-15 21:20:44 +00001937 copied = data_skb->len;
David S. Millerdaa37662010-08-15 23:21:50 -07001938
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 skb_free_datagram(sk, skb);
1940
Pravin B Shelar16b304f2013-08-15 15:31:06 -07001941 if (nlk->cb_running &&
1942 atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
Andrey Vaginb44d2112011-02-21 02:40:47 +00001943 ret = netlink_dump(sk);
1944 if (ret) {
Ben Pfaffac30ef82014-07-09 10:31:22 -07001945 sk->sk_err = -ret;
Andrey Vaginb44d2112011-02-21 02:40:47 +00001946 sk->sk_error_report(sk);
1947 }
1948 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001950 scm_recv(sock, msg, &scm, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951out:
1952 netlink_rcv_wake(sk);
1953 return err ? : copied;
1954}
1955
David S. Miller676d2362014-04-11 16:15:36 -04001956static void netlink_data_ready(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957{
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001958 BUG();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959}
1960
1961/*
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09001962 * We export these functions to other modules. They provide a
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963 * complete set of kernel non-blocking support for message
1964 * queueing.
1965 */
1966
1967struct sock *
Pablo Neira Ayuso9f00d972012-09-08 02:53:54 +00001968__netlink_kernel_create(struct net *net, int unit, struct module *module,
1969 struct netlink_kernel_cfg *cfg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970{
1971 struct socket *sock;
1972 struct sock *sk;
Patrick McHardy77247bb2005-08-14 19:27:13 -07001973 struct netlink_sock *nlk;
Eric Dumazet5c398dc2010-10-24 04:27:10 +00001974 struct listeners *listeners = NULL;
Pablo Neira Ayusoa31f2d12012-06-29 06:15:21 +00001975 struct mutex *cb_mutex = cfg ? cfg->cb_mutex : NULL;
1976 unsigned int groups;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977
Akinobu Mitafab2caf2006-08-29 02:15:24 -07001978 BUG_ON(!nl_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001980 if (unit < 0 || unit >= MAX_LINKS)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981 return NULL;
1982
1983 if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
1984 return NULL;
Eric W. Biederman13d30782015-05-08 21:11:33 -05001985
1986 if (__netlink_create(net, sock, cb_mutex, unit, 1) < 0)
Pavel Emelyanov23fe1862008-01-30 19:31:06 -08001987 goto out_sock_release_nosk;
1988
1989 sk = sock->sk;
Harald Welte4fdb3bb2005-08-09 19:40:55 -07001990
Pablo Neira Ayusoa31f2d12012-06-29 06:15:21 +00001991 if (!cfg || cfg->groups < 32)
Patrick McHardy4277a082006-03-20 18:52:01 -08001992 groups = 32;
Pablo Neira Ayusoa31f2d12012-06-29 06:15:21 +00001993 else
1994 groups = cfg->groups;
Patrick McHardy4277a082006-03-20 18:52:01 -08001995
Eric Dumazet5c398dc2010-10-24 04:27:10 +00001996 listeners = kzalloc(sizeof(*listeners) + NLGRPSZ(groups), GFP_KERNEL);
Patrick McHardy4277a082006-03-20 18:52:01 -08001997 if (!listeners)
1998 goto out_sock_release;
1999
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000 sk->sk_data_ready = netlink_data_ready;
Pablo Neira Ayusoa31f2d12012-06-29 06:15:21 +00002001 if (cfg && cfg->input)
2002 nlk_sk(sk)->netlink_rcv = cfg->input;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003
Herbert Xu8ea65f42015-01-26 14:02:56 +11002004 if (netlink_insert(sk, 0))
Patrick McHardy77247bb2005-08-14 19:27:13 -07002005 goto out_sock_release;
2006
2007 nlk = nlk_sk(sk);
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02002008 nlk->flags |= NETLINK_F_KERNEL_SOCKET;
Patrick McHardy77247bb2005-08-14 19:27:13 -07002009
2010 netlink_table_grab();
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002011 if (!nl_table[unit].registered) {
2012 nl_table[unit].groups = groups;
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002013 rcu_assign_pointer(nl_table[unit].listeners, listeners);
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002014 nl_table[unit].cb_mutex = cb_mutex;
2015 nl_table[unit].module = module;
Pablo Neira Ayuso9785e102012-09-08 02:53:53 +00002016 if (cfg) {
2017 nl_table[unit].bind = cfg->bind;
Hiroaki SHIMODA6251edd2014-11-13 04:24:10 +09002018 nl_table[unit].unbind = cfg->unbind;
Pablo Neira Ayuso9785e102012-09-08 02:53:53 +00002019 nl_table[unit].flags = cfg->flags;
Gao fengda12c902013-06-06 14:49:11 +08002020 if (cfg->compare)
2021 nl_table[unit].compare = cfg->compare;
Pablo Neira Ayuso9785e102012-09-08 02:53:53 +00002022 }
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002023 nl_table[unit].registered = 1;
Jesper Juhlf937f1f462007-10-15 01:39:12 -07002024 } else {
2025 kfree(listeners);
Denis V. Lunev869e58f2008-01-18 23:53:31 -08002026 nl_table[unit].registered++;
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002027 }
Patrick McHardy77247bb2005-08-14 19:27:13 -07002028 netlink_table_ungrab();
Harald Welte4fdb3bb2005-08-09 19:40:55 -07002029 return sk;
2030
Harald Welte4fdb3bb2005-08-09 19:40:55 -07002031out_sock_release:
Patrick McHardy4277a082006-03-20 18:52:01 -08002032 kfree(listeners);
Denis V. Lunev9dfbec12008-02-29 11:17:56 -08002033 netlink_kernel_release(sk);
Pavel Emelyanov23fe1862008-01-30 19:31:06 -08002034 return NULL;
2035
2036out_sock_release_nosk:
Harald Welte4fdb3bb2005-08-09 19:40:55 -07002037 sock_release(sock);
Patrick McHardy77247bb2005-08-14 19:27:13 -07002038 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039}
Pablo Neira Ayuso9f00d972012-09-08 02:53:54 +00002040EXPORT_SYMBOL(__netlink_kernel_create);
Denis V. Lunevb7c6ba62008-01-28 14:41:19 -08002041
2042void
2043netlink_kernel_release(struct sock *sk)
2044{
Eric W. Biederman13d30782015-05-08 21:11:33 -05002045 if (sk == NULL || sk->sk_socket == NULL)
2046 return;
2047
2048 sock_release(sk->sk_socket);
Denis V. Lunevb7c6ba62008-01-28 14:41:19 -08002049}
2050EXPORT_SYMBOL(netlink_kernel_release);
2051
Johannes Bergd136f1b2009-09-12 03:03:15 +00002052int __netlink_change_ngroups(struct sock *sk, unsigned int groups)
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002053{
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002054 struct listeners *new, *old;
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002055 struct netlink_table *tbl = &nl_table[sk->sk_protocol];
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002056
2057 if (groups < 32)
2058 groups = 32;
2059
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002060 if (NLGRPSZ(tbl->groups) < NLGRPSZ(groups)) {
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002061 new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC);
2062 if (!new)
Johannes Bergd136f1b2009-09-12 03:03:15 +00002063 return -ENOMEM;
Eric Dumazet6d772ac2012-10-18 03:21:55 +00002064 old = nl_deref_protected(tbl->listeners);
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002065 memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups));
2066 rcu_assign_pointer(tbl->listeners, new);
2067
Lai Jiangshan37b6b932011-03-15 18:01:42 +08002068 kfree_rcu(old, rcu);
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002069 }
2070 tbl->groups = groups;
2071
Johannes Bergd136f1b2009-09-12 03:03:15 +00002072 return 0;
2073}
2074
2075/**
2076 * netlink_change_ngroups - change number of multicast groups
2077 *
2078 * This changes the number of multicast groups that are available
2079 * on a certain netlink family. Note that it is not possible to
2080 * change the number of groups to below 32. Also note that it does
2081 * not implicitly call netlink_clear_multicast_users() when the
2082 * number of groups is reduced.
2083 *
2084 * @sk: The kernel netlink socket, as returned by netlink_kernel_create().
2085 * @groups: The new number of groups.
2086 */
2087int netlink_change_ngroups(struct sock *sk, unsigned int groups)
2088{
2089 int err;
2090
2091 netlink_table_grab();
2092 err = __netlink_change_ngroups(sk, groups);
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002093 netlink_table_ungrab();
Johannes Bergd136f1b2009-09-12 03:03:15 +00002094
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002095 return err;
2096}
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002097
Johannes Bergb8273572009-09-24 15:44:05 -07002098void __netlink_clear_multicast_users(struct sock *ksk, unsigned int group)
2099{
2100 struct sock *sk;
Johannes Bergb8273572009-09-24 15:44:05 -07002101 struct netlink_table *tbl = &nl_table[ksk->sk_protocol];
2102
Sasha Levinb67bfe02013-02-27 17:06:00 -08002103 sk_for_each_bound(sk, &tbl->mc_list)
Johannes Bergb8273572009-09-24 15:44:05 -07002104 netlink_update_socket_mc(nlk_sk(sk), group, 0);
2105}
2106
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002107struct nlmsghdr *
Eric W. Biederman15e47302012-09-07 20:12:54 +00002108__nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, int type, int len, int flags)
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002109{
2110 struct nlmsghdr *nlh;
Hong zhi guo573ce262013-03-27 06:47:04 +00002111 int size = nlmsg_msg_size(len);
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002112
Wang Yufen23b45672014-02-17 16:53:32 +08002113 nlh = (struct nlmsghdr *)skb_put(skb, NLMSG_ALIGN(size));
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002114 nlh->nlmsg_type = type;
2115 nlh->nlmsg_len = size;
2116 nlh->nlmsg_flags = flags;
Eric W. Biederman15e47302012-09-07 20:12:54 +00002117 nlh->nlmsg_pid = portid;
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002118 nlh->nlmsg_seq = seq;
2119 if (!__builtin_constant_p(size) || NLMSG_ALIGN(size) - size != 0)
Hong zhi guo573ce262013-03-27 06:47:04 +00002120 memset(nlmsg_data(nlh) + len, 0, NLMSG_ALIGN(size) - size);
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002121 return nlh;
2122}
2123EXPORT_SYMBOL(__nlmsg_put);
2124
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125/*
2126 * It looks a bit ugly.
2127 * It would be better to create kernel thread.
2128 */
2129
2130static int netlink_dump(struct sock *sk)
2131{
2132 struct netlink_sock *nlk = nlk_sk(sk);
2133 struct netlink_callback *cb;
Greg Rosec7ac8672011-06-10 01:27:09 +00002134 struct sk_buff *skb = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002135 struct nlmsghdr *nlh;
Herbert Xu92964c72016-05-16 17:28:16 +08002136 struct module *module;
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002137 int err = -ENOBUFS;
Arad, Ronendb65a3a2015-10-15 01:55:17 -07002138 int alloc_min_size;
Greg Rosec7ac8672011-06-10 01:27:09 +00002139 int alloc_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140
Patrick McHardyaf65bdf2007-04-20 14:14:21 -07002141 mutex_lock(nlk->cb_mutex);
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002142 if (!nlk->cb_running) {
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002143 err = -EINVAL;
2144 goto errout_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 }
2146
Florian Westphald1b4c682016-02-18 15:03:24 +01002147 if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
Patrick McHardyf9c22882013-04-17 06:47:04 +00002148 goto errout_skb;
Eric Dumazet9063e212014-03-07 12:02:33 -08002149
2150 /* NLMSG_GOODSIZE is small to avoid high order allocations being
2151 * required, but it makes sense to _attempt_ a 16K bytes allocation
2152 * to reduce number of system calls on dump operations, if user
2153 * ever provided a big enough buffer.
2154 */
Arad, Ronendb65a3a2015-10-15 01:55:17 -07002155 cb = &nlk->cb;
2156 alloc_min_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
2157
2158 if (alloc_min_size < nlk->max_recvmsg_len) {
2159 alloc_size = nlk->max_recvmsg_len;
Eric Dumazetd35c99f2016-10-06 04:13:18 +09002160 skb = alloc_skb(alloc_size,
2161 (GFP_KERNEL & ~__GFP_DIRECT_RECLAIM) |
2162 __GFP_NOWARN | __GFP_NORETRY);
Eric Dumazet9063e212014-03-07 12:02:33 -08002163 }
Arad, Ronendb65a3a2015-10-15 01:55:17 -07002164 if (!skb) {
2165 alloc_size = alloc_min_size;
Florian Westphalc5b0db32016-02-18 15:03:28 +01002166 skb = alloc_skb(alloc_size, GFP_KERNEL);
Arad, Ronendb65a3a2015-10-15 01:55:17 -07002167 }
Greg Rosec7ac8672011-06-10 01:27:09 +00002168 if (!skb)
Dan Carpenterc63d6ea2011-06-15 03:11:42 +00002169 goto errout_skb;
Arad, Ronendb65a3a2015-10-15 01:55:17 -07002170
2171 /* Trim skb to allocated size. User is expected to provide buffer as
2172 * large as max(min_dump_alloc, 16KiB (mac_recvmsg_len capped at
2173 * netlink_recvmsg())). dump will pack as many smaller messages as
2174 * could fit within the allocated skb. skb is typically allocated
2175 * with larger space than required (could be as much as near 2x the
2176 * requested size with align to next power of 2 approach). Allowing
2177 * dump to use the excess space makes it difficult for a user to have a
2178 * reasonable static buffer based on the expected largest dump of a
2179 * single netdev. The outcome is MSG_TRUNC error.
2180 */
Florian Westphald1b4c682016-02-18 15:03:24 +01002181 skb_reserve(skb, skb_tailroom(skb) - alloc_size);
Patrick McHardyf9c22882013-04-17 06:47:04 +00002182 netlink_skb_set_owner_r(skb, sk);
Greg Rosec7ac8672011-06-10 01:27:09 +00002183
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002184 if (nlk->dump_done_errno > 0)
2185 nlk->dump_done_errno = cb->dump(skb, cb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002187 if (nlk->dump_done_errno > 0 ||
2188 skb_tailroom(skb) < nlmsg_total_size(sizeof(nlk->dump_done_errno))) {
Patrick McHardyaf65bdf2007-04-20 14:14:21 -07002189 mutex_unlock(nlk->cb_mutex);
Stephen Hemmingerb1153f22008-03-21 15:46:12 -07002190
2191 if (sk_filter(sk, skb))
2192 kfree_skb(skb);
Eric Dumazet4a7e7c22012-04-05 22:17:46 +00002193 else
2194 __netlink_sendskb(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195 return 0;
2196 }
2197
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002198 nlh = nlmsg_put_answer(skb, cb, NLMSG_DONE,
2199 sizeof(nlk->dump_done_errno), NLM_F_MULTI);
2200 if (WARN_ON(!nlh))
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002201 goto errout_skb;
2202
Johannes Berg670dc282011-06-20 13:40:46 +02002203 nl_dump_check_consistent(cb, nlh);
2204
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002205 memcpy(nlmsg_data(nlh), &nlk->dump_done_errno,
2206 sizeof(nlk->dump_done_errno));
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002207
Stephen Hemmingerb1153f22008-03-21 15:46:12 -07002208 if (sk_filter(sk, skb))
2209 kfree_skb(skb);
Eric Dumazet4a7e7c22012-04-05 22:17:46 +00002210 else
2211 __netlink_sendskb(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212
Thomas Grafa8f74b22005-11-10 02:25:52 +01002213 if (cb->done)
2214 cb->done(cb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002216 nlk->cb_running = false;
Herbert Xu92964c72016-05-16 17:28:16 +08002217 module = cb->module;
2218 skb = cb->skb;
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002219 mutex_unlock(nlk->cb_mutex);
Herbert Xu92964c72016-05-16 17:28:16 +08002220 module_put(module);
2221 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222 return 0;
Thomas Graf17977542005-06-18 22:53:48 -07002223
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002224errout_skb:
Patrick McHardyaf65bdf2007-04-20 14:14:21 -07002225 mutex_unlock(nlk->cb_mutex);
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002226 kfree_skb(skb);
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002227 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228}
2229
Gao feng6dc878a2012-10-04 20:15:48 +00002230int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
2231 const struct nlmsghdr *nlh,
2232 struct netlink_dump_control *control)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233{
2234 struct netlink_callback *cb;
2235 struct sock *sk;
2236 struct netlink_sock *nlk;
Andrey Vaginb44d2112011-02-21 02:40:47 +00002237 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238
Florian Westphald1b4c682016-02-18 15:03:24 +01002239 atomic_inc(&skb->users);
Patrick McHardyf9c22882013-04-17 06:47:04 +00002240
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002241 sk = netlink_lookup(sock_net(ssk), ssk->sk_protocol, NETLINK_CB(skb).portid);
2242 if (sk == NULL) {
2243 ret = -ECONNREFUSED;
2244 goto error_free;
2245 }
2246
2247 nlk = nlk_sk(sk);
2248 mutex_lock(nlk->cb_mutex);
2249 /* A dump is in progress... */
2250 if (nlk->cb_running) {
2251 ret = -EBUSY;
2252 goto error_unlock;
2253 }
2254 /* add reference of module which cb->dump belongs to */
2255 if (!try_module_get(control->module)) {
2256 ret = -EPROTONOSUPPORT;
2257 goto error_unlock;
2258 }
2259
2260 cb = &nlk->cb;
2261 memset(cb, 0, sizeof(*cb));
Tom Herbertfc9e50f2015-12-15 15:41:37 -08002262 cb->start = control->start;
Pablo Neira Ayuso80d326f2012-02-24 14:30:15 +00002263 cb->dump = control->dump;
2264 cb->done = control->done;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002265 cb->nlh = nlh;
Pablo Neira Ayuso7175c882012-02-24 14:30:16 +00002266 cb->data = control->data;
Gao feng6dc878a2012-10-04 20:15:48 +00002267 cb->module = control->module;
Pablo Neira Ayuso80d326f2012-02-24 14:30:15 +00002268 cb->min_dump_alloc = control->min_dump_alloc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269 cb->skb = skb;
2270
Jason A. Donenfeld4cd69ad2017-10-09 14:14:51 +02002271 if (cb->start) {
2272 ret = cb->start(cb);
2273 if (ret)
Jason A. Donenfelde7b12ef2018-02-21 04:41:59 +01002274 goto error_put;
Jason A. Donenfeld4cd69ad2017-10-09 14:14:51 +02002275 }
2276
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002277 nlk->cb_running = true;
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002278 nlk->dump_done_errno = INT_MAX;
Gao feng6dc878a2012-10-04 20:15:48 +00002279
Patrick McHardyaf65bdf2007-04-20 14:14:21 -07002280 mutex_unlock(nlk->cb_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281
Jason A. Donenfeld4cd69ad2017-10-09 14:14:51 +02002282 ret = netlink_dump(sk);
Jason A. Donenfeldb4a11922017-09-28 00:41:44 +02002283
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 sock_put(sk);
Denis V. Lunev5c582982007-10-23 20:29:25 -07002285
Andrey Vaginb44d2112011-02-21 02:40:47 +00002286 if (ret)
2287 return ret;
2288
Denis V. Lunev5c582982007-10-23 20:29:25 -07002289 /* We successfully started a dump, by returning -EINTR we
2290 * signal not to send ACK even if it was requested.
2291 */
2292 return -EINTR;
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002293
Jason A. Donenfelde7b12ef2018-02-21 04:41:59 +01002294error_put:
2295 module_put(control->module);
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002296error_unlock:
2297 sock_put(sk);
2298 mutex_unlock(nlk->cb_mutex);
2299error_free:
2300 kfree_skb(skb);
2301 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302}
Gao feng6dc878a2012-10-04 20:15:48 +00002303EXPORT_SYMBOL(__netlink_dump_start);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304
2305void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
2306{
2307 struct sk_buff *skb;
2308 struct nlmsghdr *rep;
2309 struct nlmsgerr *errmsg;
Thomas Graf339bf982006-11-10 14:10:15 -08002310 size_t payload = sizeof(*errmsg);
Christophe Ricard0a6a3a22015-08-28 07:07:48 +02002311 struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312
Christophe Ricard0a6a3a22015-08-28 07:07:48 +02002313 /* Error messages get the original request appened, unless the user
2314 * requests to cap the error message.
2315 */
2316 if (!(nlk->flags & NETLINK_F_CAP_ACK) && err)
Thomas Graf339bf982006-11-10 14:10:15 -08002317 payload += nlmsg_len(nlh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318
Florian Westphalc5b0db32016-02-18 15:03:28 +01002319 skb = nlmsg_new(payload, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320 if (!skb) {
2321 struct sock *sk;
2322
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002323 sk = netlink_lookup(sock_net(in_skb->sk),
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002324 in_skb->sk->sk_protocol,
Eric W. Biederman15e47302012-09-07 20:12:54 +00002325 NETLINK_CB(in_skb).portid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 if (sk) {
2327 sk->sk_err = ENOBUFS;
2328 sk->sk_error_report(sk);
2329 sock_put(sk);
2330 }
2331 return;
2332 }
2333
Eric W. Biederman15e47302012-09-07 20:12:54 +00002334 rep = __nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
John Fastabend5dba93a2009-09-25 13:11:44 +00002335 NLMSG_ERROR, payload, 0);
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002336 errmsg = nlmsg_data(rep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337 errmsg->error = err;
Christophe Ricard0a6a3a22015-08-28 07:07:48 +02002338 memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh));
Eric W. Biederman15e47302012-09-07 20:12:54 +00002339 netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid, MSG_DONTWAIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002341EXPORT_SYMBOL(netlink_ack);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07002343int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
Thomas Graf1d00a4e2007-03-22 23:30:12 -07002344 struct nlmsghdr *))
Thomas Graf82ace472005-11-10 02:25:53 +01002345{
Thomas Graf82ace472005-11-10 02:25:53 +01002346 struct nlmsghdr *nlh;
2347 int err;
2348
2349 while (skb->len >= nlmsg_total_size(0)) {
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07002350 int msglen;
2351
Arnaldo Carvalho de Melob529ccf2007-04-25 19:08:35 -07002352 nlh = nlmsg_hdr(skb);
Thomas Grafd35b6852007-03-22 23:28:46 -07002353 err = 0;
Thomas Graf82ace472005-11-10 02:25:53 +01002354
Martin Murrayad8e4b72006-01-10 13:02:29 -08002355 if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len)
Thomas Graf82ace472005-11-10 02:25:53 +01002356 return 0;
2357
Thomas Grafd35b6852007-03-22 23:28:46 -07002358 /* Only requests are handled by the kernel */
2359 if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
Denis V. Lunev5c582982007-10-23 20:29:25 -07002360 goto ack;
Thomas Grafd35b6852007-03-22 23:28:46 -07002361
Thomas Graf45e7ae72007-03-22 23:29:10 -07002362 /* Skip control messages */
2363 if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
Denis V. Lunev5c582982007-10-23 20:29:25 -07002364 goto ack;
Thomas Graf45e7ae72007-03-22 23:29:10 -07002365
Thomas Graf1d00a4e2007-03-22 23:30:12 -07002366 err = cb(skb, nlh);
Denis V. Lunev5c582982007-10-23 20:29:25 -07002367 if (err == -EINTR)
2368 goto skip;
2369
2370ack:
Thomas Grafd35b6852007-03-22 23:28:46 -07002371 if (nlh->nlmsg_flags & NLM_F_ACK || err)
Thomas Graf82ace472005-11-10 02:25:53 +01002372 netlink_ack(skb, nlh, err);
Thomas Graf82ace472005-11-10 02:25:53 +01002373
Denis V. Lunev5c582982007-10-23 20:29:25 -07002374skip:
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002375 msglen = NLMSG_ALIGN(nlh->nlmsg_len);
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07002376 if (msglen > skb->len)
2377 msglen = skb->len;
2378 skb_pull(skb, msglen);
Thomas Graf82ace472005-11-10 02:25:53 +01002379 }
2380
2381 return 0;
2382}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002383EXPORT_SYMBOL(netlink_rcv_skb);
Thomas Graf82ace472005-11-10 02:25:53 +01002384
2385/**
Thomas Grafd387f6a2006-08-15 00:31:06 -07002386 * nlmsg_notify - send a notification netlink message
2387 * @sk: netlink socket to use
2388 * @skb: notification message
Eric W. Biederman15e47302012-09-07 20:12:54 +00002389 * @portid: destination netlink portid for reports or 0
Thomas Grafd387f6a2006-08-15 00:31:06 -07002390 * @group: destination multicast group or 0
2391 * @report: 1 to report back, 0 to disable
2392 * @flags: allocation flags
2393 */
Eric W. Biederman15e47302012-09-07 20:12:54 +00002394int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid,
Thomas Grafd387f6a2006-08-15 00:31:06 -07002395 unsigned int group, int report, gfp_t flags)
2396{
2397 int err = 0;
2398
2399 if (group) {
Eric W. Biederman15e47302012-09-07 20:12:54 +00002400 int exclude_portid = 0;
Thomas Grafd387f6a2006-08-15 00:31:06 -07002401
2402 if (report) {
2403 atomic_inc(&skb->users);
Eric W. Biederman15e47302012-09-07 20:12:54 +00002404 exclude_portid = portid;
Thomas Grafd387f6a2006-08-15 00:31:06 -07002405 }
2406
Pablo Neira Ayuso1ce85fe2009-02-24 23:18:28 -08002407 /* errors reported via destination sk->sk_err, but propagate
2408 * delivery errors if NETLINK_BROADCAST_ERROR flag is set */
Eric W. Biederman15e47302012-09-07 20:12:54 +00002409 err = nlmsg_multicast(sk, skb, exclude_portid, group, flags);
Thomas Grafd387f6a2006-08-15 00:31:06 -07002410 }
2411
Pablo Neira Ayuso1ce85fe2009-02-24 23:18:28 -08002412 if (report) {
2413 int err2;
2414
Eric W. Biederman15e47302012-09-07 20:12:54 +00002415 err2 = nlmsg_unicast(sk, skb, portid);
Pablo Neira Ayuso1ce85fe2009-02-24 23:18:28 -08002416 if (!err || err == -ESRCH)
2417 err = err2;
2418 }
Thomas Grafd387f6a2006-08-15 00:31:06 -07002419
2420 return err;
2421}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002422EXPORT_SYMBOL(nlmsg_notify);
Thomas Grafd387f6a2006-08-15 00:31:06 -07002423
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424#ifdef CONFIG_PROC_FS
2425struct nl_seq_iter {
Denis V. Luneve372c412007-11-19 22:31:54 -08002426 struct seq_net_private p;
Herbert Xu56d28b12015-02-04 07:33:24 +11002427 struct rhashtable_iter hti;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002428 int link;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429};
2430
Herbert Xu56d28b12015-02-04 07:33:24 +11002431static int netlink_walk_start(struct nl_seq_iter *iter)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002432{
Herbert Xu56d28b12015-02-04 07:33:24 +11002433 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434
Bob Copeland8f6fd832016-03-02 10:09:19 -05002435 err = rhashtable_walk_init(&nl_table[iter->link].hash, &iter->hti,
2436 GFP_KERNEL);
Herbert Xu56d28b12015-02-04 07:33:24 +11002437 if (err) {
2438 iter->link = MAX_LINKS;
2439 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440 }
Herbert Xu56d28b12015-02-04 07:33:24 +11002441
2442 err = rhashtable_walk_start(&iter->hti);
2443 return err == -EAGAIN ? 0 : err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444}
2445
Herbert Xu56d28b12015-02-04 07:33:24 +11002446static void netlink_walk_stop(struct nl_seq_iter *iter)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447{
Herbert Xu56d28b12015-02-04 07:33:24 +11002448 rhashtable_walk_stop(&iter->hti);
2449 rhashtable_walk_exit(&iter->hti);
2450}
2451
2452static void *__netlink_seq_next(struct seq_file *seq)
2453{
2454 struct nl_seq_iter *iter = seq->private;
2455 struct netlink_sock *nlk;
2456
2457 do {
2458 for (;;) {
2459 int err;
2460
2461 nlk = rhashtable_walk_next(&iter->hti);
2462
2463 if (IS_ERR(nlk)) {
2464 if (PTR_ERR(nlk) == -EAGAIN)
2465 continue;
2466
2467 return nlk;
2468 }
2469
2470 if (nlk)
2471 break;
2472
2473 netlink_walk_stop(iter);
2474 if (++iter->link >= MAX_LINKS)
2475 return NULL;
2476
2477 err = netlink_walk_start(iter);
2478 if (err)
2479 return ERR_PTR(err);
2480 }
2481 } while (sock_net(&nlk->sk) != seq_file_net(seq));
2482
2483 return nlk;
2484}
2485
2486static void *netlink_seq_start(struct seq_file *seq, loff_t *posp)
2487{
2488 struct nl_seq_iter *iter = seq->private;
2489 void *obj = SEQ_START_TOKEN;
2490 loff_t pos;
2491 int err;
2492
2493 iter->link = 0;
2494
2495 err = netlink_walk_start(iter);
2496 if (err)
2497 return ERR_PTR(err);
2498
2499 for (pos = *posp; pos && obj && !IS_ERR(obj); pos--)
2500 obj = __netlink_seq_next(seq);
2501
2502 return obj;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503}
2504
2505static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2506{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507 ++*pos;
Herbert Xu56d28b12015-02-04 07:33:24 +11002508 return __netlink_seq_next(seq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509}
2510
2511static void netlink_seq_stop(struct seq_file *seq, void *v)
2512{
Herbert Xu56d28b12015-02-04 07:33:24 +11002513 struct nl_seq_iter *iter = seq->private;
2514
2515 if (iter->link >= MAX_LINKS)
2516 return;
2517
2518 netlink_walk_stop(iter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002519}
2520
2521
2522static int netlink_seq_show(struct seq_file *seq, void *v)
2523{
Eric Dumazet658cb352012-04-22 21:30:21 +00002524 if (v == SEQ_START_TOKEN) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525 seq_puts(seq,
2526 "sk Eth Pid Groups "
Masatake YAMATOcf0aa4e2010-02-27 19:45:37 +00002527 "Rmem Wmem Dump Locks Drops Inode\n");
Eric Dumazet658cb352012-04-22 21:30:21 +00002528 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 struct sock *s = v;
2530 struct netlink_sock *nlk = nlk_sk(s);
2531
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002532 seq_printf(seq, "%pK %-3d %-6u %08x %-8d %-8d %d %-8d %-8d %-8lu\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002533 s,
2534 s->sk_protocol,
Eric W. Biederman15e47302012-09-07 20:12:54 +00002535 nlk->portid,
Patrick McHardy513c2502005-09-06 15:43:59 -07002536 nlk->groups ? (u32)nlk->groups[0] : 0,
Eric Dumazet31e6d362009-06-17 19:05:41 -07002537 sk_rmem_alloc_get(s),
2538 sk_wmem_alloc_get(s),
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002539 nlk->cb_running,
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07002540 atomic_read(&s->sk_refcnt),
Masatake YAMATOcf0aa4e2010-02-27 19:45:37 +00002541 atomic_read(&s->sk_drops),
2542 sock_i_ino(s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 );
2544
2545 }
2546 return 0;
2547}
2548
Philippe De Muyter56b3d972007-07-10 23:07:31 -07002549static const struct seq_operations netlink_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002550 .start = netlink_seq_start,
2551 .next = netlink_seq_next,
2552 .stop = netlink_seq_stop,
2553 .show = netlink_seq_show,
2554};
2555
2556
2557static int netlink_seq_open(struct inode *inode, struct file *file)
2558{
Denis V. Luneve372c412007-11-19 22:31:54 -08002559 return seq_open_net(inode, file, &netlink_seq_ops,
2560 sizeof(struct nl_seq_iter));
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002561}
2562
Arjan van de Venda7071d2007-02-12 00:55:36 -08002563static const struct file_operations netlink_seq_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 .owner = THIS_MODULE,
2565 .open = netlink_seq_open,
2566 .read = seq_read,
2567 .llseek = seq_lseek,
Denis V. Luneve372c412007-11-19 22:31:54 -08002568 .release = seq_release_net,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569};
2570
2571#endif
2572
2573int netlink_register_notifier(struct notifier_block *nb)
2574{
Alan Sterne041c682006-03-27 01:16:30 -08002575 return atomic_notifier_chain_register(&netlink_chain, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002577EXPORT_SYMBOL(netlink_register_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578
2579int netlink_unregister_notifier(struct notifier_block *nb)
2580{
Alan Sterne041c682006-03-27 01:16:30 -08002581 return atomic_notifier_chain_unregister(&netlink_chain, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002583EXPORT_SYMBOL(netlink_unregister_notifier);
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09002584
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08002585static const struct proto_ops netlink_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002586 .family = PF_NETLINK,
2587 .owner = THIS_MODULE,
2588 .release = netlink_release,
2589 .bind = netlink_bind,
2590 .connect = netlink_connect,
2591 .socketpair = sock_no_socketpair,
2592 .accept = sock_no_accept,
2593 .getname = netlink_getname,
Florian Westphald1b4c682016-02-18 15:03:24 +01002594 .poll = datagram_poll,
David Decotigny025c6812016-03-21 10:15:35 -07002595 .ioctl = netlink_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596 .listen = sock_no_listen,
2597 .shutdown = sock_no_shutdown,
Patrick McHardy9a4595b2005-08-15 12:32:15 -07002598 .setsockopt = netlink_setsockopt,
2599 .getsockopt = netlink_getsockopt,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 .sendmsg = netlink_sendmsg,
2601 .recvmsg = netlink_recvmsg,
Florian Westphald1b4c682016-02-18 15:03:24 +01002602 .mmap = sock_no_mmap,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603 .sendpage = sock_no_sendpage,
2604};
2605
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00002606static const struct net_proto_family netlink_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607 .family = PF_NETLINK,
2608 .create = netlink_create,
2609 .owner = THIS_MODULE, /* for consistency 8) */
2610};
2611
Pavel Emelyanov46650792007-10-08 20:38:39 -07002612static int __net_init netlink_net_init(struct net *net)
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002613{
2614#ifdef CONFIG_PROC_FS
Gao fengd4beaa62013-02-18 01:34:54 +00002615 if (!proc_create("netlink", 0, net->proc_net, &netlink_seq_fops))
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002616 return -ENOMEM;
2617#endif
2618 return 0;
2619}
2620
Pavel Emelyanov46650792007-10-08 20:38:39 -07002621static void __net_exit netlink_net_exit(struct net *net)
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002622{
2623#ifdef CONFIG_PROC_FS
Gao fengece31ff2013-02-18 01:34:56 +00002624 remove_proc_entry("netlink", net->proc_net);
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002625#endif
2626}
2627
David S. Millerb963ea82010-08-30 19:08:01 -07002628static void __init netlink_add_usersock_entry(void)
2629{
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002630 struct listeners *listeners;
David S. Millerb963ea82010-08-30 19:08:01 -07002631 int groups = 32;
2632
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002633 listeners = kzalloc(sizeof(*listeners) + NLGRPSZ(groups), GFP_KERNEL);
David S. Millerb963ea82010-08-30 19:08:01 -07002634 if (!listeners)
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002635 panic("netlink_add_usersock_entry: Cannot allocate listeners\n");
David S. Millerb963ea82010-08-30 19:08:01 -07002636
2637 netlink_table_grab();
2638
2639 nl_table[NETLINK_USERSOCK].groups = groups;
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002640 rcu_assign_pointer(nl_table[NETLINK_USERSOCK].listeners, listeners);
David S. Millerb963ea82010-08-30 19:08:01 -07002641 nl_table[NETLINK_USERSOCK].module = THIS_MODULE;
2642 nl_table[NETLINK_USERSOCK].registered = 1;
Pablo Neira Ayuso9785e102012-09-08 02:53:53 +00002643 nl_table[NETLINK_USERSOCK].flags = NL_CFG_F_NONROOT_SEND;
David S. Millerb963ea82010-08-30 19:08:01 -07002644
2645 netlink_table_ungrab();
2646}
2647
Denis V. Lunev022cbae2007-11-13 03:23:50 -08002648static struct pernet_operations __net_initdata netlink_net_ops = {
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002649 .init = netlink_net_init,
2650 .exit = netlink_net_exit,
2651};
2652
Patrick McHardy49f7b332015-03-25 13:07:45 +00002653static inline u32 netlink_hash(const void *data, u32 len, u32 seed)
Herbert Xuc428ecd2015-03-20 21:57:01 +11002654{
2655 const struct netlink_sock *nlk = data;
2656 struct netlink_compare_arg arg;
2657
Herbert Xuda314c92015-09-22 11:38:56 +08002658 netlink_compare_arg_init(&arg, sock_net(&nlk->sk), nlk->portid);
Herbert Xu11b58ba2015-03-24 00:50:22 +11002659 return jhash2((u32 *)&arg, netlink_compare_arg_len / sizeof(u32), seed);
Herbert Xuc428ecd2015-03-20 21:57:01 +11002660}
2661
2662static const struct rhashtable_params netlink_rhashtable_params = {
2663 .head_offset = offsetof(struct netlink_sock, node),
2664 .key_len = netlink_compare_arg_len,
Herbert Xuc428ecd2015-03-20 21:57:01 +11002665 .obj_hashfn = netlink_hash,
2666 .obj_cmpfn = netlink_compare,
Thomas Grafb5e2c152015-03-24 20:42:19 +00002667 .automatic_shrinking = true,
Herbert Xuc428ecd2015-03-20 21:57:01 +11002668};
2669
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670static int __init netlink_proto_init(void)
2671{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002672 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 int err = proto_register(&netlink_proto, 0);
2674
2675 if (err != 0)
2676 goto out;
2677
YOSHIFUJI Hideaki / 吉藤英明fab25742013-01-09 07:19:48 +00002678 BUILD_BUG_ON(sizeof(struct netlink_skb_parms) > FIELD_SIZEOF(struct sk_buff, cb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679
Panagiotis Issaris0da974f2006-07-21 14:51:30 -07002680 nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);
Akinobu Mitafab2caf2006-08-29 02:15:24 -07002681 if (!nl_table)
2682 goto panic;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683
Linus Torvalds1da177e2005-04-16 15:20:36 -07002684 for (i = 0; i < MAX_LINKS; i++) {
Herbert Xuc428ecd2015-03-20 21:57:01 +11002685 if (rhashtable_init(&nl_table[i].hash,
2686 &netlink_rhashtable_params) < 0) {
Thomas Grafe3416942014-08-02 11:47:45 +02002687 while (--i > 0)
2688 rhashtable_destroy(&nl_table[i].hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002689 kfree(nl_table);
Akinobu Mitafab2caf2006-08-29 02:15:24 -07002690 goto panic;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692 }
2693
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +02002694 INIT_LIST_HEAD(&netlink_tap_all);
2695
David S. Millerb963ea82010-08-30 19:08:01 -07002696 netlink_add_usersock_entry();
2697
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698 sock_register(&netlink_family_ops);
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002699 register_pernet_subsys(&netlink_net_ops);
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09002700 /* The netlink device handler may be needed early. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701 rtnetlink_init();
2702out:
2703 return err;
Akinobu Mitafab2caf2006-08-29 02:15:24 -07002704panic:
2705 panic("netlink_init: Cannot allocate nl_table\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706}
2707
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708core_initcall(netlink_proto_init);