blob: 0254874364381f4fb8144ddee2da179268dbde03 [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
1006 for (group = 0; group < nlk->ngroups; group++) {
1007 if (!test_bit(group, &groups))
1008 continue;
Pablo Neira8b7c36d2015-01-29 10:51:53 +01001009 err = nlk->netlink_bind(net, group + 1);
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001010 if (!err)
1011 continue;
Johannes Berg023e2cf2014-12-23 21:00:06 +01001012 netlink_undo_bind(group, groups, sk);
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001013 return err;
1014 }
1015 }
1016
Herbert Xuda314c92015-09-22 11:38:56 +08001017 /* No need for barriers here as we return to user-space without
1018 * using any of the bound attributes.
1019 */
1020 if (!bound) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 err = nladdr->nl_pid ?
Herbert Xu8ea65f42015-01-26 14:02:56 +11001022 netlink_insert(sk, nladdr->nl_pid) :
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 netlink_autobind(sock);
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001024 if (err) {
Johannes Berg023e2cf2014-12-23 21:00:06 +01001025 netlink_undo_bind(nlk->ngroups, groups, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 return err;
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001027 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 }
1029
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001030 if (!groups && (nlk->groups == NULL || !(u32)nlk->groups[0]))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 return 0;
1032
1033 netlink_table_grab();
Patrick McHardyf7fa9b12005-08-15 12:29:13 -07001034 netlink_update_subscriptions(sk, nlk->subscriptions +
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001035 hweight32(groups) -
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09001036 hweight32(nlk->groups[0]));
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001037 nlk->groups[0] = (nlk->groups[0] & ~0xffffffffUL) | groups;
Patrick McHardy4277a082006-03-20 18:52:01 -08001038 netlink_update_listeners(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 netlink_table_ungrab();
1040
1041 return 0;
1042}
1043
1044static int netlink_connect(struct socket *sock, struct sockaddr *addr,
1045 int alen, int flags)
1046{
1047 int err = 0;
1048 struct sock *sk = sock->sk;
1049 struct netlink_sock *nlk = nlk_sk(sk);
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001050 struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051
Changli Gao6503d962010-03-31 22:58:26 +00001052 if (alen < sizeof(addr->sa_family))
1053 return -EINVAL;
1054
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 if (addr->sa_family == AF_UNSPEC) {
1056 sk->sk_state = NETLINK_UNCONNECTED;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001057 nlk->dst_portid = 0;
Patrick McHardyd629b832005-08-14 19:27:50 -07001058 nlk->dst_group = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 return 0;
1060 }
1061 if (addr->sa_family != AF_NETLINK)
1062 return -EINVAL;
1063
Alexander Potapenkocf105332018-03-23 13:49:02 +01001064 if (alen < sizeof(struct sockaddr_nl))
1065 return -EINVAL;
1066
Mike Pecovnik46833a82014-02-24 21:11:16 +01001067 if ((nladdr->nl_groups || nladdr->nl_pid) &&
Eric W. Biederman5187cd02014-04-23 14:25:48 -07001068 !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 return -EPERM;
1070
Herbert Xuda314c92015-09-22 11:38:56 +08001071 /* No need for barriers here as we return to user-space without
1072 * using any of the bound attributes.
1073 */
1074 if (!nlk->bound)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 err = netlink_autobind(sock);
1076
1077 if (err == 0) {
1078 sk->sk_state = NETLINK_CONNECTED;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001079 nlk->dst_portid = nladdr->nl_pid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001080 nlk->dst_group = ffs(nladdr->nl_groups);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 }
1082
1083 return err;
1084}
1085
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001086static int netlink_getname(struct socket *sock, struct sockaddr *addr,
1087 int *addr_len, int peer)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088{
1089 struct sock *sk = sock->sk;
1090 struct netlink_sock *nlk = nlk_sk(sk);
Cyrill Gorcunov13cfa972009-11-08 05:51:19 +00001091 DECLARE_SOCKADDR(struct sockaddr_nl *, nladdr, addr);
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09001092
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 nladdr->nl_family = AF_NETLINK;
1094 nladdr->nl_pad = 0;
1095 *addr_len = sizeof(*nladdr);
1096
1097 if (peer) {
Eric W. Biederman15e47302012-09-07 20:12:54 +00001098 nladdr->nl_pid = nlk->dst_portid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001099 nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 } else {
Eric W. Biederman15e47302012-09-07 20:12:54 +00001101 nladdr->nl_pid = nlk->portid;
Patrick McHardy513c2502005-09-06 15:43:59 -07001102 nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 }
1104 return 0;
1105}
1106
David Decotigny025c6812016-03-21 10:15:35 -07001107static int netlink_ioctl(struct socket *sock, unsigned int cmd,
1108 unsigned long arg)
1109{
1110 /* try to hand this ioctl down to the NIC drivers.
1111 */
1112 return -ENOIOCTLCMD;
1113}
1114
Eric W. Biederman15e47302012-09-07 20:12:54 +00001115static struct sock *netlink_getsockbyportid(struct sock *ssk, u32 portid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 struct sock *sock;
1118 struct netlink_sock *nlk;
1119
Eric W. Biederman15e47302012-09-07 20:12:54 +00001120 sock = netlink_lookup(sock_net(ssk), ssk->sk_protocol, portid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 if (!sock)
1122 return ERR_PTR(-ECONNREFUSED);
1123
1124 /* Don't bother queuing skb if kernel socket has no input function */
1125 nlk = nlk_sk(sock);
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001126 if (sock->sk_state == NETLINK_CONNECTED &&
Eric W. Biederman15e47302012-09-07 20:12:54 +00001127 nlk->dst_portid != nlk_sk(ssk)->portid) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 sock_put(sock);
1129 return ERR_PTR(-ECONNREFUSED);
1130 }
1131 return sock;
1132}
1133
1134struct sock *netlink_getsockbyfilp(struct file *filp)
1135{
Al Viro496ad9a2013-01-23 17:07:38 -05001136 struct inode *inode = file_inode(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 struct sock *sock;
1138
1139 if (!S_ISSOCK(inode->i_mode))
1140 return ERR_PTR(-ENOTSOCK);
1141
1142 sock = SOCKET_I(inode)->sk;
1143 if (sock->sk_family != AF_NETLINK)
1144 return ERR_PTR(-EINVAL);
1145
1146 sock_hold(sock);
1147 return sock;
1148}
1149
Pablo Neira3a365152013-06-28 03:04:23 +02001150static struct sk_buff *netlink_alloc_large_skb(unsigned int size,
1151 int broadcast)
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001152{
1153 struct sk_buff *skb;
1154 void *data;
1155
Pablo Neira3a365152013-06-28 03:04:23 +02001156 if (size <= NLMSG_GOODSIZE || broadcast)
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001157 return alloc_skb(size, GFP_KERNEL);
1158
Pablo Neira3a365152013-06-28 03:04:23 +02001159 size = SKB_DATA_ALIGN(size) +
1160 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001161
1162 data = vmalloc(size);
1163 if (data == NULL)
Pablo Neira3a365152013-06-28 03:04:23 +02001164 return NULL;
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001165
Eric Dumazet2ea2f622015-04-24 16:05:01 -07001166 skb = __build_skb(data, size);
Pablo Neira3a365152013-06-28 03:04:23 +02001167 if (skb == NULL)
1168 vfree(data);
Eric Dumazet2ea2f622015-04-24 16:05:01 -07001169 else
Pablo Neira3a365152013-06-28 03:04:23 +02001170 skb->destructor = netlink_skb_destructor;
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001171
1172 return skb;
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001173}
1174
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175/*
1176 * Attach a skb to a netlink socket.
1177 * The caller must hold a reference to the destination socket. On error, the
1178 * reference is dropped. The skb is not send to the destination, just all
1179 * all error checks are performed and memory in the queue is reserved.
1180 * Return values:
1181 * < 0: error. skb freed, reference to sock dropped.
1182 * 0: continue
1183 * 1: repeat lookup - reference dropped while waiting for socket memory.
1184 */
Denis V. Lunev9457afe2008-06-05 11:23:39 -07001185int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
Patrick McHardyc3d8d1e2007-11-07 02:42:09 -08001186 long *timeo, struct sock *ssk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187{
1188 struct netlink_sock *nlk;
1189
1190 nlk = nlk_sk(sk);
1191
Patrick McHardy5fd96122013-04-17 06:47:03 +00001192 if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
Florian Westphald1b4c682016-02-18 15:03:24 +01001193 test_bit(NETLINK_S_CONGESTED, &nlk->state))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 DECLARE_WAITQUEUE(wait, current);
Patrick McHardyc3d8d1e2007-11-07 02:42:09 -08001195 if (!*timeo) {
Denis V. Lunevaed81562007-10-10 21:14:32 -07001196 if (!ssk || netlink_is_kernel(ssk))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 netlink_overrun(sk);
1198 sock_put(sk);
1199 kfree_skb(skb);
1200 return -EAGAIN;
1201 }
1202
1203 __set_current_state(TASK_INTERRUPTIBLE);
1204 add_wait_queue(&nlk->wait, &wait);
1205
1206 if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001207 test_bit(NETLINK_S_CONGESTED, &nlk->state)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 !sock_flag(sk, SOCK_DEAD))
Patrick McHardyc3d8d1e2007-11-07 02:42:09 -08001209 *timeo = schedule_timeout(*timeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210
1211 __set_current_state(TASK_RUNNING);
1212 remove_wait_queue(&nlk->wait, &wait);
1213 sock_put(sk);
1214
1215 if (signal_pending(current)) {
1216 kfree_skb(skb);
Patrick McHardyc3d8d1e2007-11-07 02:42:09 -08001217 return sock_intr_errno(*timeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 }
1219 return 1;
1220 }
Patrick McHardycf0a0182013-04-17 06:47:00 +00001221 netlink_skb_set_owner_r(skb, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 return 0;
1223}
1224
Eric Dumazet4a7e7c22012-04-05 22:17:46 +00001225static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227 int len = skb->len;
1228
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +02001229 netlink_deliver_tap(skb);
1230
Florian Westphald1b4c682016-02-18 15:03:24 +01001231 skb_queue_tail(&sk->sk_receive_queue, skb);
David S. Miller676d2362014-04-11 16:15:36 -04001232 sk->sk_data_ready(sk);
Eric Dumazet4a7e7c22012-04-05 22:17:46 +00001233 return len;
1234}
1235
1236int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
1237{
1238 int len = __netlink_sendskb(sk, skb);
1239
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 sock_put(sk);
1241 return len;
1242}
1243
1244void netlink_detachskb(struct sock *sk, struct sk_buff *skb)
1245{
1246 kfree_skb(skb);
1247 sock_put(sk);
1248}
1249
stephen hemmingerb57ef81f2011-12-22 08:52:02 +00001250static struct sk_buff *netlink_trim(struct sk_buff *skb, gfp_t allocation)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251{
1252 int delta;
1253
Patrick McHardy1298ca42013-04-17 06:46:59 +00001254 WARN_ON(skb->sk != NULL);
Arnaldo Carvalho de Melo4305b542007-04-19 20:43:29 -07001255 delta = skb->end - skb->tail;
Pablo Neira Ayusoc05cdb12013-06-03 09:46:28 +00001256 if (is_vmalloc_addr(skb->head) || delta * 2 < skb->truesize)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257 return skb;
1258
1259 if (skb_shared(skb)) {
1260 struct sk_buff *nskb = skb_clone(skb, allocation);
1261 if (!nskb)
1262 return skb;
Eric Dumazet8460c002012-04-19 02:24:28 +00001263 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264 skb = nskb;
1265 }
1266
1267 if (!pskb_expand_head(skb, 0, -delta, allocation))
1268 skb->truesize -= delta;
1269
1270 return skb;
1271}
1272
Eric W. Biederman3fbc2902012-05-24 17:21:27 -06001273static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb,
1274 struct sock *ssk)
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001275{
1276 int ret;
1277 struct netlink_sock *nlk = nlk_sk(sk);
1278
1279 ret = -ECONNREFUSED;
1280 if (nlk->netlink_rcv != NULL) {
1281 ret = skb->len;
Patrick McHardycf0a0182013-04-17 06:47:00 +00001282 netlink_skb_set_owner_r(skb, sk);
Patrick McHardye32123e2013-04-17 06:46:57 +00001283 NETLINK_CB(skb).sk = ssk;
Daniel Borkmann73bfd372013-12-23 14:35:55 +01001284 netlink_deliver_tap_kernel(sk, ssk, skb);
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001285 nlk->netlink_rcv(skb);
Eric Dumazetbfb253c2012-04-22 21:30:29 +00001286 consume_skb(skb);
1287 } else {
1288 kfree_skb(skb);
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001289 }
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001290 sock_put(sk);
1291 return ret;
1292}
1293
1294int netlink_unicast(struct sock *ssk, struct sk_buff *skb,
Eric W. Biederman15e47302012-09-07 20:12:54 +00001295 u32 portid, int nonblock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296{
1297 struct sock *sk;
1298 int err;
1299 long timeo;
1300
1301 skb = netlink_trim(skb, gfp_any());
1302
1303 timeo = sock_sndtimeo(ssk, nonblock);
1304retry:
Eric W. Biederman15e47302012-09-07 20:12:54 +00001305 sk = netlink_getsockbyportid(ssk, portid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 if (IS_ERR(sk)) {
1307 kfree_skb(skb);
1308 return PTR_ERR(sk);
1309 }
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001310 if (netlink_is_kernel(sk))
Eric W. Biederman3fbc2902012-05-24 17:21:27 -06001311 return netlink_unicast_kernel(sk, skb, ssk);
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001312
Stephen Hemmingerb1153f22008-03-21 15:46:12 -07001313 if (sk_filter(sk, skb)) {
Wang Chen84874602008-07-01 19:55:09 -07001314 err = skb->len;
Stephen Hemmingerb1153f22008-03-21 15:46:12 -07001315 kfree_skb(skb);
1316 sock_put(sk);
1317 return err;
1318 }
1319
Denis V. Lunev9457afe2008-06-05 11:23:39 -07001320 err = netlink_attachskb(sk, skb, &timeo, ssk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 if (err == 1)
1322 goto retry;
1323 if (err)
1324 return err;
1325
Denis V. Lunev7ee015e2007-10-10 21:14:03 -07001326 return netlink_sendskb(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001328EXPORT_SYMBOL(netlink_unicast);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329
Patrick McHardy4277a082006-03-20 18:52:01 -08001330int netlink_has_listeners(struct sock *sk, unsigned int group)
1331{
1332 int res = 0;
Eric Dumazet5c398dc2010-10-24 04:27:10 +00001333 struct listeners *listeners;
Patrick McHardy4277a082006-03-20 18:52:01 -08001334
Denis V. Lunevaed81562007-10-10 21:14:32 -07001335 BUG_ON(!netlink_is_kernel(sk));
Johannes Bergb4ff4f02007-07-18 15:46:06 -07001336
1337 rcu_read_lock();
1338 listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners);
1339
Eric Dumazet6d772ac2012-10-18 03:21:55 +00001340 if (listeners && group - 1 < nl_table[sk->sk_protocol].groups)
Eric Dumazet5c398dc2010-10-24 04:27:10 +00001341 res = test_bit(group - 1, listeners->masks);
Johannes Bergb4ff4f02007-07-18 15:46:06 -07001342
1343 rcu_read_unlock();
1344
Patrick McHardy4277a082006-03-20 18:52:01 -08001345 return res;
1346}
1347EXPORT_SYMBOL_GPL(netlink_has_listeners);
1348
stephen hemmingerb57ef81f2011-12-22 08:52:02 +00001349static int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350{
1351 struct netlink_sock *nlk = nlk_sk(sk);
1352
1353 if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001354 !test_bit(NETLINK_S_CONGESTED, &nlk->state)) {
Patrick McHardycf0a0182013-04-17 06:47:00 +00001355 netlink_skb_set_owner_r(skb, sk);
Eric Dumazet4a7e7c22012-04-05 22:17:46 +00001356 __netlink_sendskb(sk, skb);
stephen hemminger2c6458002011-12-22 08:52:03 +00001357 return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 }
1359 return -1;
1360}
1361
1362struct netlink_broadcast_data {
1363 struct sock *exclude_sk;
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02001364 struct net *net;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001365 u32 portid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 u32 group;
1367 int failure;
Pablo Neira Ayusoff491a72009-02-05 23:56:36 -08001368 int delivery_failure;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 int congested;
1370 int delivered;
Al Viro7d877f32005-10-21 03:20:43 -04001371 gfp_t allocation;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 struct sk_buff *skb, *skb2;
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001373 int (*tx_filter)(struct sock *dsk, struct sk_buff *skb, void *data);
1374 void *tx_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375};
1376
Rami Rosen46c95212014-07-01 21:17:35 +03001377static void do_one_broadcast(struct sock *sk,
1378 struct netlink_broadcast_data *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379{
1380 struct netlink_sock *nlk = nlk_sk(sk);
1381 int val;
1382
1383 if (p->exclude_sk == sk)
Rami Rosen46c95212014-07-01 21:17:35 +03001384 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385
Eric W. Biederman15e47302012-09-07 20:12:54 +00001386 if (nlk->portid == p->portid || p->group - 1 >= nlk->ngroups ||
Patrick McHardyf7fa9b12005-08-15 12:29:13 -07001387 !test_bit(p->group - 1, nlk->groups))
Rami Rosen46c95212014-07-01 21:17:35 +03001388 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001390 if (!net_eq(sock_net(sk), p->net)) {
1391 if (!(nlk->flags & NETLINK_F_LISTEN_ALL_NSID))
1392 return;
1393
1394 if (!peernet_has_id(sock_net(sk), p->net))
1395 return;
1396
1397 if (!file_ns_capable(sk->sk_socket->file, p->net->user_ns,
1398 CAP_NET_BROADCAST))
1399 return;
1400 }
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02001401
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 if (p->failure) {
1403 netlink_overrun(sk);
Rami Rosen46c95212014-07-01 21:17:35 +03001404 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 }
1406
1407 sock_hold(sk);
1408 if (p->skb2 == NULL) {
Tommy S. Christensen68acc022005-05-19 13:06:35 -07001409 if (skb_shared(p->skb)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 p->skb2 = skb_clone(p->skb, p->allocation);
1411 } else {
Tommy S. Christensen68acc022005-05-19 13:06:35 -07001412 p->skb2 = skb_get(p->skb);
1413 /*
1414 * skb ownership may have been set when
1415 * delivered to a previous socket.
1416 */
1417 skb_orphan(p->skb2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 }
1419 }
1420 if (p->skb2 == NULL) {
1421 netlink_overrun(sk);
1422 /* Clone failed. Notify ALL listeners. */
1423 p->failure = 1;
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001424 if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR)
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001425 p->delivery_failure = 1;
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001426 goto out;
1427 }
1428 if (p->tx_filter && p->tx_filter(sk, p->skb2, p->tx_data)) {
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001429 kfree_skb(p->skb2);
1430 p->skb2 = NULL;
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001431 goto out;
1432 }
1433 if (sk_filter(sk, p->skb2)) {
Stephen Hemmingerb1153f22008-03-21 15:46:12 -07001434 kfree_skb(p->skb2);
1435 p->skb2 = NULL;
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001436 goto out;
1437 }
1438 NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
1439 NETLINK_CB(p->skb2).nsid_is_set = true;
1440 val = netlink_broadcast_deliver(sk, p->skb2);
1441 if (val < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 netlink_overrun(sk);
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001443 if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR)
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001444 p->delivery_failure = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445 } else {
1446 p->congested |= val;
1447 p->delivered = 1;
1448 p->skb2 = NULL;
1449 }
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001450out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 sock_put(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452}
1453
Eric W. Biederman15e47302012-09-07 20:12:54 +00001454int netlink_broadcast_filtered(struct sock *ssk, struct sk_buff *skb, u32 portid,
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001455 u32 group, gfp_t allocation,
1456 int (*filter)(struct sock *dsk, struct sk_buff *skb, void *data),
1457 void *filter_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458{
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001459 struct net *net = sock_net(ssk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 struct netlink_broadcast_data info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461 struct sock *sk;
1462
1463 skb = netlink_trim(skb, allocation);
1464
1465 info.exclude_sk = ssk;
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02001466 info.net = net;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001467 info.portid = portid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 info.group = group;
1469 info.failure = 0;
Pablo Neira Ayusoff491a72009-02-05 23:56:36 -08001470 info.delivery_failure = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471 info.congested = 0;
1472 info.delivered = 0;
1473 info.allocation = allocation;
1474 info.skb = skb;
1475 info.skb2 = NULL;
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001476 info.tx_filter = filter;
1477 info.tx_data = filter_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478
1479 /* While we sleep in clone, do not allow to change socket list */
1480
1481 netlink_lock_table();
1482
Sasha Levinb67bfe02013-02-27 17:06:00 -08001483 sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 do_one_broadcast(sk, &info);
1485
Neil Horman70d4bf62010-07-20 06:45:56 +00001486 consume_skb(skb);
Tommy S. Christensenaa1c6a62005-05-19 13:07:32 -07001487
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488 netlink_unlock_table();
1489
Neil Horman70d4bf62010-07-20 06:45:56 +00001490 if (info.delivery_failure) {
1491 kfree_skb(info.skb2);
Pablo Neira Ayusoff491a72009-02-05 23:56:36 -08001492 return -ENOBUFS;
Eric Dumazet658cb352012-04-22 21:30:21 +00001493 }
1494 consume_skb(info.skb2);
Pablo Neira Ayusoff491a72009-02-05 23:56:36 -08001495
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 if (info.delivered) {
Mel Gormand0164ad2015-11-06 16:28:21 -08001497 if (info.congested && gfpflags_allow_blocking(allocation))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 yield();
1499 return 0;
1500 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 return -ESRCH;
1502}
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001503EXPORT_SYMBOL(netlink_broadcast_filtered);
1504
Eric W. Biederman15e47302012-09-07 20:12:54 +00001505int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 portid,
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001506 u32 group, gfp_t allocation)
1507{
Eric W. Biederman15e47302012-09-07 20:12:54 +00001508 return netlink_broadcast_filtered(ssk, skb, portid, group, allocation,
Eric W. Biederman910a7e92010-05-04 17:36:46 -07001509 NULL, NULL);
1510}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001511EXPORT_SYMBOL(netlink_broadcast);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512
1513struct netlink_set_err_data {
1514 struct sock *exclude_sk;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001515 u32 portid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 u32 group;
1517 int code;
1518};
1519
stephen hemmingerb57ef81f2011-12-22 08:52:02 +00001520static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521{
1522 struct netlink_sock *nlk = nlk_sk(sk);
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001523 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524
1525 if (sk == p->exclude_sk)
1526 goto out;
1527
Octavian Purdila09ad9bc2009-11-25 15:14:13 -08001528 if (!net_eq(sock_net(sk), sock_net(p->exclude_sk)))
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02001529 goto out;
1530
Eric W. Biederman15e47302012-09-07 20:12:54 +00001531 if (nlk->portid == p->portid || p->group - 1 >= nlk->ngroups ||
Patrick McHardyf7fa9b12005-08-15 12:29:13 -07001532 !test_bit(p->group - 1, nlk->groups))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533 goto out;
1534
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001535 if (p->code == ENOBUFS && nlk->flags & NETLINK_F_RECV_NO_ENOBUFS) {
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001536 ret = 1;
1537 goto out;
1538 }
1539
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 sk->sk_err = p->code;
1541 sk->sk_error_report(sk);
1542out:
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001543 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544}
1545
Pablo Neira Ayuso4843b932009-03-03 23:37:30 -08001546/**
1547 * netlink_set_err - report error to broadcast listeners
1548 * @ssk: the kernel netlink socket, as returned by netlink_kernel_create()
Eric W. Biederman15e47302012-09-07 20:12:54 +00001549 * @portid: the PORTID of a process that we want to skip (if any)
Johannes Berg840e93f22013-11-19 10:35:40 +01001550 * @group: the broadcast group that will notice the error
Pablo Neira Ayuso4843b932009-03-03 23:37:30 -08001551 * @code: error code, must be negative (as usual in kernelspace)
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001552 *
1553 * This function returns the number of broadcast listeners that have set the
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001554 * NETLINK_NO_ENOBUFS socket option.
Pablo Neira Ayuso4843b932009-03-03 23:37:30 -08001555 */
Eric W. Biederman15e47302012-09-07 20:12:54 +00001556int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557{
1558 struct netlink_set_err_data info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 struct sock *sk;
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001560 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561
1562 info.exclude_sk = ssk;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001563 info.portid = portid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 info.group = group;
Pablo Neira Ayuso4843b932009-03-03 23:37:30 -08001565 /* sk->sk_err wants a positive error value */
1566 info.code = -code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567
1568 read_lock(&nl_table_lock);
1569
Sasha Levinb67bfe02013-02-27 17:06:00 -08001570 sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list)
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001571 ret += do_one_set_err(sk, &info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572
1573 read_unlock(&nl_table_lock);
Pablo Neira Ayuso1a503072010-03-18 14:24:42 +00001574 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575}
Pablo Neira Ayusodd5b6ce2009-03-23 13:21:06 +01001576EXPORT_SYMBOL(netlink_set_err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
Johannes Berg84659eb2007-07-18 15:47:05 -07001578/* must be called with netlink table grabbed */
1579static void netlink_update_socket_mc(struct netlink_sock *nlk,
1580 unsigned int group,
1581 int is_new)
1582{
1583 int old, new = !!is_new, subscriptions;
1584
1585 old = test_bit(group - 1, nlk->groups);
1586 subscriptions = nlk->subscriptions - old + new;
1587 if (new)
1588 __set_bit(group - 1, nlk->groups);
1589 else
1590 __clear_bit(group - 1, nlk->groups);
1591 netlink_update_subscriptions(&nlk->sk, subscriptions);
1592 netlink_update_listeners(&nlk->sk);
1593}
1594
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001595static int netlink_setsockopt(struct socket *sock, int level, int optname,
David S. Millerb7058842009-09-30 16:12:20 -07001596 char __user *optval, unsigned int optlen)
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001597{
1598 struct sock *sk = sock->sk;
1599 struct netlink_sock *nlk = nlk_sk(sk);
Johannes Bergeb496532007-07-18 02:07:51 -07001600 unsigned int val = 0;
1601 int err;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001602
1603 if (level != SOL_NETLINK)
1604 return -ENOPROTOOPT;
1605
Florian Westphald1b4c682016-02-18 15:03:24 +01001606 if (optlen >= sizeof(int) &&
Johannes Bergeb496532007-07-18 02:07:51 -07001607 get_user(val, (unsigned int __user *)optval))
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001608 return -EFAULT;
1609
1610 switch (optname) {
1611 case NETLINK_PKTINFO:
1612 if (val)
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001613 nlk->flags |= NETLINK_F_RECV_PKTINFO;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001614 else
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001615 nlk->flags &= ~NETLINK_F_RECV_PKTINFO;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001616 err = 0;
1617 break;
1618 case NETLINK_ADD_MEMBERSHIP:
1619 case NETLINK_DROP_MEMBERSHIP: {
Eric W. Biederman5187cd02014-04-23 14:25:48 -07001620 if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV))
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001621 return -EPERM;
Johannes Bergb4ff4f02007-07-18 15:46:06 -07001622 err = netlink_realloc_groups(sk);
1623 if (err)
1624 return err;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001625 if (!val || val - 1 >= nlk->ngroups)
1626 return -EINVAL;
Richard Guy Briggs7774d5e2014-04-22 21:31:55 -04001627 if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) {
Johannes Berg023e2cf2014-12-23 21:00:06 +01001628 err = nlk->netlink_bind(sock_net(sk), val);
Richard Guy Briggs4f520902014-04-22 21:31:54 -04001629 if (err)
1630 return err;
1631 }
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001632 netlink_table_grab();
Johannes Berg84659eb2007-07-18 15:47:05 -07001633 netlink_update_socket_mc(nlk, val,
1634 optname == NETLINK_ADD_MEMBERSHIP);
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001635 netlink_table_ungrab();
Richard Guy Briggs7774d5e2014-04-22 21:31:55 -04001636 if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind)
Johannes Berg023e2cf2014-12-23 21:00:06 +01001637 nlk->netlink_unbind(sock_net(sk), val);
Pablo Neira Ayuso03292742012-06-29 06:15:22 +00001638
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001639 err = 0;
1640 break;
1641 }
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001642 case NETLINK_BROADCAST_ERROR:
1643 if (val)
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001644 nlk->flags |= NETLINK_F_BROADCAST_SEND_ERROR;
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001645 else
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001646 nlk->flags &= ~NETLINK_F_BROADCAST_SEND_ERROR;
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001647 err = 0;
1648 break;
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07001649 case NETLINK_NO_ENOBUFS:
1650 if (val) {
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001651 nlk->flags |= NETLINK_F_RECV_NO_ENOBUFS;
1652 clear_bit(NETLINK_S_CONGESTED, &nlk->state);
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07001653 wake_up_interruptible(&nlk->wait);
Eric Dumazet658cb352012-04-22 21:30:21 +00001654 } else {
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001655 nlk->flags &= ~NETLINK_F_RECV_NO_ENOBUFS;
Eric Dumazet658cb352012-04-22 21:30:21 +00001656 }
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07001657 err = 0;
1658 break;
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001659 case NETLINK_LISTEN_ALL_NSID:
1660 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_BROADCAST))
1661 return -EPERM;
1662
1663 if (val)
1664 nlk->flags |= NETLINK_F_LISTEN_ALL_NSID;
1665 else
1666 nlk->flags &= ~NETLINK_F_LISTEN_ALL_NSID;
1667 err = 0;
1668 break;
Christophe Ricard0a6a3a22015-08-28 07:07:48 +02001669 case NETLINK_CAP_ACK:
1670 if (val)
1671 nlk->flags |= NETLINK_F_CAP_ACK;
1672 else
1673 nlk->flags &= ~NETLINK_F_CAP_ACK;
1674 err = 0;
1675 break;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001676 default:
1677 err = -ENOPROTOOPT;
1678 }
1679 return err;
1680}
1681
1682static int netlink_getsockopt(struct socket *sock, int level, int optname,
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09001683 char __user *optval, int __user *optlen)
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001684{
1685 struct sock *sk = sock->sk;
1686 struct netlink_sock *nlk = nlk_sk(sk);
1687 int len, val, err;
1688
1689 if (level != SOL_NETLINK)
1690 return -ENOPROTOOPT;
1691
1692 if (get_user(len, optlen))
1693 return -EFAULT;
1694 if (len < 0)
1695 return -EINVAL;
1696
1697 switch (optname) {
1698 case NETLINK_PKTINFO:
1699 if (len < sizeof(int))
1700 return -EINVAL;
1701 len = sizeof(int);
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001702 val = nlk->flags & NETLINK_F_RECV_PKTINFO ? 1 : 0;
Heiko Carstensa27b58f2006-10-30 15:06:12 -08001703 if (put_user(len, optlen) ||
1704 put_user(val, optval))
1705 return -EFAULT;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001706 err = 0;
1707 break;
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001708 case NETLINK_BROADCAST_ERROR:
1709 if (len < sizeof(int))
1710 return -EINVAL;
1711 len = sizeof(int);
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001712 val = nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR ? 1 : 0;
Pablo Neira Ayusobe0c22a2009-02-18 01:40:43 +00001713 if (put_user(len, optlen) ||
1714 put_user(val, optval))
1715 return -EFAULT;
1716 err = 0;
1717 break;
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07001718 case NETLINK_NO_ENOBUFS:
1719 if (len < sizeof(int))
1720 return -EINVAL;
1721 len = sizeof(int);
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001722 val = nlk->flags & NETLINK_F_RECV_NO_ENOBUFS ? 1 : 0;
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07001723 if (put_user(len, optlen) ||
1724 put_user(val, optval))
1725 return -EFAULT;
1726 err = 0;
1727 break;
David Herrmannb42be382015-06-17 17:14:33 +02001728 case NETLINK_LIST_MEMBERSHIPS: {
1729 int pos, idx, shift;
1730
1731 err = 0;
David Herrmann47191d62015-10-21 11:47:43 +02001732 netlink_lock_table();
David Herrmannb42be382015-06-17 17:14:33 +02001733 for (pos = 0; pos * 8 < nlk->ngroups; pos += sizeof(u32)) {
1734 if (len - pos < sizeof(u32))
1735 break;
1736
1737 idx = pos / sizeof(unsigned long);
1738 shift = (pos % sizeof(unsigned long)) * 8;
1739 if (put_user((u32)(nlk->groups[idx] >> shift),
1740 (u32 __user *)(optval + pos))) {
1741 err = -EFAULT;
1742 break;
1743 }
1744 }
1745 if (put_user(ALIGN(nlk->ngroups / 8, sizeof(u32)), optlen))
1746 err = -EFAULT;
David Herrmann47191d62015-10-21 11:47:43 +02001747 netlink_unlock_table();
David Herrmannb42be382015-06-17 17:14:33 +02001748 break;
1749 }
Christophe Ricard0a6a3a22015-08-28 07:07:48 +02001750 case NETLINK_CAP_ACK:
1751 if (len < sizeof(int))
1752 return -EINVAL;
1753 len = sizeof(int);
1754 val = nlk->flags & NETLINK_F_CAP_ACK ? 1 : 0;
1755 if (put_user(len, optlen) ||
1756 put_user(val, optval))
1757 return -EFAULT;
1758 err = 0;
1759 break;
Patrick McHardy9a4595b2005-08-15 12:32:15 -07001760 default:
1761 err = -ENOPROTOOPT;
1762 }
1763 return err;
1764}
1765
1766static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
1767{
1768 struct nl_pktinfo info;
1769
1770 info.group = NETLINK_CB(skb).dst_group;
1771 put_cmsg(msg, SOL_NETLINK, NETLINK_PKTINFO, sizeof(info), &info);
1772}
1773
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001774static void netlink_cmsg_listen_all_nsid(struct sock *sk, struct msghdr *msg,
1775 struct sk_buff *skb)
1776{
1777 if (!NETLINK_CB(skb).nsid_is_set)
1778 return;
1779
1780 put_cmsg(msg, SOL_NETLINK, NETLINK_LISTEN_ALL_NSID, sizeof(int),
1781 &NETLINK_CB(skb).nsid);
1782}
1783
Ying Xue1b784142015-03-02 15:37:48 +08001784static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 struct sock *sk = sock->sk;
1787 struct netlink_sock *nlk = nlk_sk(sk);
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001788 DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name);
Eric W. Biederman15e47302012-09-07 20:12:54 +00001789 u32 dst_portid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001790 u32 dst_group;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 struct sk_buff *skb;
1792 int err;
1793 struct scm_cookie scm;
Eric W. Biederman2d7a85f2014-05-30 11:04:00 -07001794 u32 netlink_skb_flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795
1796 if (msg->msg_flags&MSG_OOB)
1797 return -EOPNOTSUPP;
1798
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001799 err = scm_send(sock, msg, &scm, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 if (err < 0)
1801 return err;
1802
1803 if (msg->msg_namelen) {
Eric W. Biedermanb47030c2010-06-13 03:31:06 +00001804 err = -EINVAL;
Eric Dumazet473ac552018-04-07 13:42:37 -07001805 if (msg->msg_namelen < sizeof(struct sockaddr_nl))
1806 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 if (addr->nl_family != AF_NETLINK)
Eric W. Biedermanb47030c2010-06-13 03:31:06 +00001808 goto out;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001809 dst_portid = addr->nl_pid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001810 dst_group = ffs(addr->nl_groups);
Eric W. Biedermanb47030c2010-06-13 03:31:06 +00001811 err = -EPERM;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001812 if ((dst_group || dst_portid) &&
Eric W. Biederman5187cd02014-04-23 14:25:48 -07001813 !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
Eric W. Biedermanb47030c2010-06-13 03:31:06 +00001814 goto out;
Eric W. Biederman2d7a85f2014-05-30 11:04:00 -07001815 netlink_skb_flags |= NETLINK_SKB_DST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 } else {
Eric W. Biederman15e47302012-09-07 20:12:54 +00001817 dst_portid = nlk->dst_portid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001818 dst_group = nlk->dst_group;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 }
1820
Herbert Xuda314c92015-09-22 11:38:56 +08001821 if (!nlk->bound) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 err = netlink_autobind(sock);
1823 if (err)
1824 goto out;
Herbert Xuda314c92015-09-22 11:38:56 +08001825 } else {
1826 /* Ensure nlk is hashed and visible. */
1827 smp_rmb();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 }
1829
1830 err = -EMSGSIZE;
1831 if (len > sk->sk_sndbuf - 32)
1832 goto out;
1833 err = -ENOBUFS;
Pablo Neira3a365152013-06-28 03:04:23 +02001834 skb = netlink_alloc_large_skb(len, dst_group);
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001835 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 goto out;
1837
Eric W. Biederman15e47302012-09-07 20:12:54 +00001838 NETLINK_CB(skb).portid = nlk->portid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001839 NETLINK_CB(skb).dst_group = dst_group;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001840 NETLINK_CB(skb).creds = scm.creds;
Eric W. Biederman2d7a85f2014-05-30 11:04:00 -07001841 NETLINK_CB(skb).flags = netlink_skb_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 err = -EFAULT;
Al Viro6ce8e9c2014-04-06 21:25:44 -04001844 if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 kfree_skb(skb);
1846 goto out;
1847 }
1848
1849 err = security_netlink_send(sk, skb);
1850 if (err) {
1851 kfree_skb(skb);
1852 goto out;
1853 }
1854
Patrick McHardyd629b832005-08-14 19:27:50 -07001855 if (dst_group) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 atomic_inc(&skb->users);
Eric W. Biederman15e47302012-09-07 20:12:54 +00001857 netlink_broadcast(sk, skb, dst_portid, dst_group, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 }
Eric W. Biederman15e47302012-09-07 20:12:54 +00001859 err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags&MSG_DONTWAIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
1861out:
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001862 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 return err;
1864}
1865
Ying Xue1b784142015-03-02 15:37:48 +08001866static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 int flags)
1868{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 struct scm_cookie scm;
1870 struct sock *sk = sock->sk;
1871 struct netlink_sock *nlk = nlk_sk(sk);
1872 int noblock = flags&MSG_DONTWAIT;
1873 size_t copied;
Johannes Berg68d6ac62010-08-15 21:20:44 +00001874 struct sk_buff *skb, *data_skb;
Andrey Vaginb44d2112011-02-21 02:40:47 +00001875 int err, ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876
1877 if (flags&MSG_OOB)
1878 return -EOPNOTSUPP;
1879
1880 copied = 0;
1881
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001882 skb = skb_recv_datagram(sk, flags, noblock, &err);
1883 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 goto out;
1885
Johannes Berg68d6ac62010-08-15 21:20:44 +00001886 data_skb = skb;
1887
Johannes Berg1dacc762009-07-01 11:26:02 +00001888#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
1889 if (unlikely(skb_shinfo(skb)->frag_list)) {
Johannes Berg1dacc762009-07-01 11:26:02 +00001890 /*
Johannes Berg68d6ac62010-08-15 21:20:44 +00001891 * If this skb has a frag_list, then here that means that we
1892 * will have to use the frag_list skb's data for compat tasks
1893 * and the regular skb's data for normal (non-compat) tasks.
Johannes Berg1dacc762009-07-01 11:26:02 +00001894 *
Johannes Berg68d6ac62010-08-15 21:20:44 +00001895 * If we need to send the compat skb, assign it to the
1896 * 'data_skb' variable so that it will be used below for data
1897 * copying. We keep 'skb' for everything else, including
1898 * freeing both later.
Johannes Berg1dacc762009-07-01 11:26:02 +00001899 */
Johannes Berg68d6ac62010-08-15 21:20:44 +00001900 if (flags & MSG_CMSG_COMPAT)
1901 data_skb = skb_shinfo(skb)->frag_list;
Johannes Berg1dacc762009-07-01 11:26:02 +00001902 }
1903#endif
1904
Eric Dumazet9063e212014-03-07 12:02:33 -08001905 /* Record the max length of recvmsg() calls for future allocations */
1906 nlk->max_recvmsg_len = max(nlk->max_recvmsg_len, len);
1907 nlk->max_recvmsg_len = min_t(size_t, nlk->max_recvmsg_len,
Eric Dumazetd35c99f2016-10-06 04:13:18 +09001908 SKB_WITH_OVERHEAD(32768));
Eric Dumazet9063e212014-03-07 12:02:33 -08001909
Johannes Berg68d6ac62010-08-15 21:20:44 +00001910 copied = data_skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 if (len < copied) {
1912 msg->msg_flags |= MSG_TRUNC;
1913 copied = len;
1914 }
1915
Johannes Berg68d6ac62010-08-15 21:20:44 +00001916 skb_reset_transport_header(data_skb);
David S. Miller51f3d022014-11-05 16:46:40 -05001917 err = skb_copy_datagram_msg(data_skb, 0, msg, copied);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918
1919 if (msg->msg_name) {
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001920 DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 addr->nl_family = AF_NETLINK;
1922 addr->nl_pad = 0;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001923 addr->nl_pid = NETLINK_CB(skb).portid;
Patrick McHardyd629b832005-08-14 19:27:50 -07001924 addr->nl_groups = netlink_group_mask(NETLINK_CB(skb).dst_group);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 msg->msg_namelen = sizeof(*addr);
1926 }
1927
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02001928 if (nlk->flags & NETLINK_F_RECV_PKTINFO)
Patrick McHardycc9a06c2006-03-12 20:34:27 -08001929 netlink_cmsg_recv_pktinfo(msg, skb);
Nicolas Dichtel59324cf2015-05-07 11:02:53 +02001930 if (nlk->flags & NETLINK_F_LISTEN_ALL_NSID)
1931 netlink_cmsg_listen_all_nsid(sk, msg, skb);
Patrick McHardycc9a06c2006-03-12 20:34:27 -08001932
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001933 memset(&scm, 0, sizeof(scm));
1934 scm.creds = *NETLINK_CREDS(skb);
Patrick McHardy188ccb52007-05-03 03:27:01 -07001935 if (flags & MSG_TRUNC)
Johannes Berg68d6ac62010-08-15 21:20:44 +00001936 copied = data_skb->len;
David S. Millerdaa37662010-08-15 23:21:50 -07001937
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 skb_free_datagram(sk, skb);
1939
Pravin B Shelar16b304f2013-08-15 15:31:06 -07001940 if (nlk->cb_running &&
1941 atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
Andrey Vaginb44d2112011-02-21 02:40:47 +00001942 ret = netlink_dump(sk);
1943 if (ret) {
Ben Pfaffac30ef82014-07-09 10:31:22 -07001944 sk->sk_err = -ret;
Andrey Vaginb44d2112011-02-21 02:40:47 +00001945 sk->sk_error_report(sk);
1946 }
1947 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001949 scm_recv(sock, msg, &scm, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950out:
1951 netlink_rcv_wake(sk);
1952 return err ? : copied;
1953}
1954
David S. Miller676d2362014-04-11 16:15:36 -04001955static void netlink_data_ready(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956{
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07001957 BUG();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958}
1959
1960/*
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09001961 * We export these functions to other modules. They provide a
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 * complete set of kernel non-blocking support for message
1963 * queueing.
1964 */
1965
1966struct sock *
Pablo Neira Ayuso9f00d972012-09-08 02:53:54 +00001967__netlink_kernel_create(struct net *net, int unit, struct module *module,
1968 struct netlink_kernel_cfg *cfg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969{
1970 struct socket *sock;
1971 struct sock *sk;
Patrick McHardy77247bb2005-08-14 19:27:13 -07001972 struct netlink_sock *nlk;
Eric Dumazet5c398dc2010-10-24 04:27:10 +00001973 struct listeners *listeners = NULL;
Pablo Neira Ayusoa31f2d12012-06-29 06:15:21 +00001974 struct mutex *cb_mutex = cfg ? cfg->cb_mutex : NULL;
1975 unsigned int groups;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976
Akinobu Mitafab2caf2006-08-29 02:15:24 -07001977 BUG_ON(!nl_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978
Patrick McHardy6ac552f2007-12-04 00:19:38 -08001979 if (unit < 0 || unit >= MAX_LINKS)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980 return NULL;
1981
1982 if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
1983 return NULL;
Eric W. Biederman13d30782015-05-08 21:11:33 -05001984
1985 if (__netlink_create(net, sock, cb_mutex, unit, 1) < 0)
Pavel Emelyanov23fe1862008-01-30 19:31:06 -08001986 goto out_sock_release_nosk;
1987
1988 sk = sock->sk;
Harald Welte4fdb3bb2005-08-09 19:40:55 -07001989
Pablo Neira Ayusoa31f2d12012-06-29 06:15:21 +00001990 if (!cfg || cfg->groups < 32)
Patrick McHardy4277a082006-03-20 18:52:01 -08001991 groups = 32;
Pablo Neira Ayusoa31f2d12012-06-29 06:15:21 +00001992 else
1993 groups = cfg->groups;
Patrick McHardy4277a082006-03-20 18:52:01 -08001994
Eric Dumazet5c398dc2010-10-24 04:27:10 +00001995 listeners = kzalloc(sizeof(*listeners) + NLGRPSZ(groups), GFP_KERNEL);
Patrick McHardy4277a082006-03-20 18:52:01 -08001996 if (!listeners)
1997 goto out_sock_release;
1998
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999 sk->sk_data_ready = netlink_data_ready;
Pablo Neira Ayusoa31f2d12012-06-29 06:15:21 +00002000 if (cfg && cfg->input)
2001 nlk_sk(sk)->netlink_rcv = cfg->input;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002
Herbert Xu8ea65f42015-01-26 14:02:56 +11002003 if (netlink_insert(sk, 0))
Patrick McHardy77247bb2005-08-14 19:27:13 -07002004 goto out_sock_release;
2005
2006 nlk = nlk_sk(sk);
Nicolas Dichtelcc3a5722015-05-07 11:02:52 +02002007 nlk->flags |= NETLINK_F_KERNEL_SOCKET;
Patrick McHardy77247bb2005-08-14 19:27:13 -07002008
2009 netlink_table_grab();
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002010 if (!nl_table[unit].registered) {
2011 nl_table[unit].groups = groups;
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002012 rcu_assign_pointer(nl_table[unit].listeners, listeners);
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002013 nl_table[unit].cb_mutex = cb_mutex;
2014 nl_table[unit].module = module;
Pablo Neira Ayuso9785e102012-09-08 02:53:53 +00002015 if (cfg) {
2016 nl_table[unit].bind = cfg->bind;
Hiroaki SHIMODA6251edd2014-11-13 04:24:10 +09002017 nl_table[unit].unbind = cfg->unbind;
Pablo Neira Ayuso9785e102012-09-08 02:53:53 +00002018 nl_table[unit].flags = cfg->flags;
Gao fengda12c902013-06-06 14:49:11 +08002019 if (cfg->compare)
2020 nl_table[unit].compare = cfg->compare;
Pablo Neira Ayuso9785e102012-09-08 02:53:53 +00002021 }
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002022 nl_table[unit].registered = 1;
Jesper Juhlf937f1f462007-10-15 01:39:12 -07002023 } else {
2024 kfree(listeners);
Denis V. Lunev869e58f2008-01-18 23:53:31 -08002025 nl_table[unit].registered++;
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002026 }
Patrick McHardy77247bb2005-08-14 19:27:13 -07002027 netlink_table_ungrab();
Harald Welte4fdb3bb2005-08-09 19:40:55 -07002028 return sk;
2029
Harald Welte4fdb3bb2005-08-09 19:40:55 -07002030out_sock_release:
Patrick McHardy4277a082006-03-20 18:52:01 -08002031 kfree(listeners);
Denis V. Lunev9dfbec12008-02-29 11:17:56 -08002032 netlink_kernel_release(sk);
Pavel Emelyanov23fe1862008-01-30 19:31:06 -08002033 return NULL;
2034
2035out_sock_release_nosk:
Harald Welte4fdb3bb2005-08-09 19:40:55 -07002036 sock_release(sock);
Patrick McHardy77247bb2005-08-14 19:27:13 -07002037 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038}
Pablo Neira Ayuso9f00d972012-09-08 02:53:54 +00002039EXPORT_SYMBOL(__netlink_kernel_create);
Denis V. Lunevb7c6ba62008-01-28 14:41:19 -08002040
2041void
2042netlink_kernel_release(struct sock *sk)
2043{
Eric W. Biederman13d30782015-05-08 21:11:33 -05002044 if (sk == NULL || sk->sk_socket == NULL)
2045 return;
2046
2047 sock_release(sk->sk_socket);
Denis V. Lunevb7c6ba62008-01-28 14:41:19 -08002048}
2049EXPORT_SYMBOL(netlink_kernel_release);
2050
Johannes Bergd136f1b2009-09-12 03:03:15 +00002051int __netlink_change_ngroups(struct sock *sk, unsigned int groups)
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002052{
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002053 struct listeners *new, *old;
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002054 struct netlink_table *tbl = &nl_table[sk->sk_protocol];
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002055
2056 if (groups < 32)
2057 groups = 32;
2058
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002059 if (NLGRPSZ(tbl->groups) < NLGRPSZ(groups)) {
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002060 new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC);
2061 if (!new)
Johannes Bergd136f1b2009-09-12 03:03:15 +00002062 return -ENOMEM;
Eric Dumazet6d772ac2012-10-18 03:21:55 +00002063 old = nl_deref_protected(tbl->listeners);
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002064 memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups));
2065 rcu_assign_pointer(tbl->listeners, new);
2066
Lai Jiangshan37b6b932011-03-15 18:01:42 +08002067 kfree_rcu(old, rcu);
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002068 }
2069 tbl->groups = groups;
2070
Johannes Bergd136f1b2009-09-12 03:03:15 +00002071 return 0;
2072}
2073
2074/**
2075 * netlink_change_ngroups - change number of multicast groups
2076 *
2077 * This changes the number of multicast groups that are available
2078 * on a certain netlink family. Note that it is not possible to
2079 * change the number of groups to below 32. Also note that it does
2080 * not implicitly call netlink_clear_multicast_users() when the
2081 * number of groups is reduced.
2082 *
2083 * @sk: The kernel netlink socket, as returned by netlink_kernel_create().
2084 * @groups: The new number of groups.
2085 */
2086int netlink_change_ngroups(struct sock *sk, unsigned int groups)
2087{
2088 int err;
2089
2090 netlink_table_grab();
2091 err = __netlink_change_ngroups(sk, groups);
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002092 netlink_table_ungrab();
Johannes Bergd136f1b2009-09-12 03:03:15 +00002093
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002094 return err;
2095}
Johannes Bergb4ff4f02007-07-18 15:46:06 -07002096
Johannes Bergb8273572009-09-24 15:44:05 -07002097void __netlink_clear_multicast_users(struct sock *ksk, unsigned int group)
2098{
2099 struct sock *sk;
Johannes Bergb8273572009-09-24 15:44:05 -07002100 struct netlink_table *tbl = &nl_table[ksk->sk_protocol];
2101
Sasha Levinb67bfe02013-02-27 17:06:00 -08002102 sk_for_each_bound(sk, &tbl->mc_list)
Johannes Bergb8273572009-09-24 15:44:05 -07002103 netlink_update_socket_mc(nlk_sk(sk), group, 0);
2104}
2105
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002106struct nlmsghdr *
Eric W. Biederman15e47302012-09-07 20:12:54 +00002107__nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, int type, int len, int flags)
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002108{
2109 struct nlmsghdr *nlh;
Hong zhi guo573ce262013-03-27 06:47:04 +00002110 int size = nlmsg_msg_size(len);
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002111
Wang Yufen23b45672014-02-17 16:53:32 +08002112 nlh = (struct nlmsghdr *)skb_put(skb, NLMSG_ALIGN(size));
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002113 nlh->nlmsg_type = type;
2114 nlh->nlmsg_len = size;
2115 nlh->nlmsg_flags = flags;
Eric W. Biederman15e47302012-09-07 20:12:54 +00002116 nlh->nlmsg_pid = portid;
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002117 nlh->nlmsg_seq = seq;
2118 if (!__builtin_constant_p(size) || NLMSG_ALIGN(size) - size != 0)
Hong zhi guo573ce262013-03-27 06:47:04 +00002119 memset(nlmsg_data(nlh) + len, 0, NLMSG_ALIGN(size) - size);
Denys Vlasenkoa46621a2012-01-30 15:22:06 -05002120 return nlh;
2121}
2122EXPORT_SYMBOL(__nlmsg_put);
2123
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124/*
2125 * It looks a bit ugly.
2126 * It would be better to create kernel thread.
2127 */
2128
2129static int netlink_dump(struct sock *sk)
2130{
2131 struct netlink_sock *nlk = nlk_sk(sk);
2132 struct netlink_callback *cb;
Greg Rosec7ac8672011-06-10 01:27:09 +00002133 struct sk_buff *skb = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134 struct nlmsghdr *nlh;
Herbert Xu92964c72016-05-16 17:28:16 +08002135 struct module *module;
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002136 int err = -ENOBUFS;
Arad, Ronendb65a3a2015-10-15 01:55:17 -07002137 int alloc_min_size;
Greg Rosec7ac8672011-06-10 01:27:09 +00002138 int alloc_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139
Patrick McHardyaf65bdf2007-04-20 14:14:21 -07002140 mutex_lock(nlk->cb_mutex);
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002141 if (!nlk->cb_running) {
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002142 err = -EINVAL;
2143 goto errout_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 }
2145
Florian Westphald1b4c682016-02-18 15:03:24 +01002146 if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
Patrick McHardyf9c22882013-04-17 06:47:04 +00002147 goto errout_skb;
Eric Dumazet9063e212014-03-07 12:02:33 -08002148
2149 /* NLMSG_GOODSIZE is small to avoid high order allocations being
2150 * required, but it makes sense to _attempt_ a 16K bytes allocation
2151 * to reduce number of system calls on dump operations, if user
2152 * ever provided a big enough buffer.
2153 */
Arad, Ronendb65a3a2015-10-15 01:55:17 -07002154 cb = &nlk->cb;
2155 alloc_min_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
2156
2157 if (alloc_min_size < nlk->max_recvmsg_len) {
2158 alloc_size = nlk->max_recvmsg_len;
Eric Dumazetd35c99f2016-10-06 04:13:18 +09002159 skb = alloc_skb(alloc_size,
2160 (GFP_KERNEL & ~__GFP_DIRECT_RECLAIM) |
2161 __GFP_NOWARN | __GFP_NORETRY);
Eric Dumazet9063e212014-03-07 12:02:33 -08002162 }
Arad, Ronendb65a3a2015-10-15 01:55:17 -07002163 if (!skb) {
2164 alloc_size = alloc_min_size;
Florian Westphalc5b0db32016-02-18 15:03:28 +01002165 skb = alloc_skb(alloc_size, GFP_KERNEL);
Arad, Ronendb65a3a2015-10-15 01:55:17 -07002166 }
Greg Rosec7ac8672011-06-10 01:27:09 +00002167 if (!skb)
Dan Carpenterc63d6ea2011-06-15 03:11:42 +00002168 goto errout_skb;
Arad, Ronendb65a3a2015-10-15 01:55:17 -07002169
2170 /* Trim skb to allocated size. User is expected to provide buffer as
2171 * large as max(min_dump_alloc, 16KiB (mac_recvmsg_len capped at
2172 * netlink_recvmsg())). dump will pack as many smaller messages as
2173 * could fit within the allocated skb. skb is typically allocated
2174 * with larger space than required (could be as much as near 2x the
2175 * requested size with align to next power of 2 approach). Allowing
2176 * dump to use the excess space makes it difficult for a user to have a
2177 * reasonable static buffer based on the expected largest dump of a
2178 * single netdev. The outcome is MSG_TRUNC error.
2179 */
Florian Westphald1b4c682016-02-18 15:03:24 +01002180 skb_reserve(skb, skb_tailroom(skb) - alloc_size);
Patrick McHardyf9c22882013-04-17 06:47:04 +00002181 netlink_skb_set_owner_r(skb, sk);
Greg Rosec7ac8672011-06-10 01:27:09 +00002182
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002183 if (nlk->dump_done_errno > 0)
2184 nlk->dump_done_errno = cb->dump(skb, cb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002185
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002186 if (nlk->dump_done_errno > 0 ||
2187 skb_tailroom(skb) < nlmsg_total_size(sizeof(nlk->dump_done_errno))) {
Patrick McHardyaf65bdf2007-04-20 14:14:21 -07002188 mutex_unlock(nlk->cb_mutex);
Stephen Hemmingerb1153f22008-03-21 15:46:12 -07002189
2190 if (sk_filter(sk, skb))
2191 kfree_skb(skb);
Eric Dumazet4a7e7c22012-04-05 22:17:46 +00002192 else
2193 __netlink_sendskb(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194 return 0;
2195 }
2196
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002197 nlh = nlmsg_put_answer(skb, cb, NLMSG_DONE,
2198 sizeof(nlk->dump_done_errno), NLM_F_MULTI);
2199 if (WARN_ON(!nlh))
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002200 goto errout_skb;
2201
Johannes Berg670dc282011-06-20 13:40:46 +02002202 nl_dump_check_consistent(cb, nlh);
2203
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002204 memcpy(nlmsg_data(nlh), &nlk->dump_done_errno,
2205 sizeof(nlk->dump_done_errno));
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002206
Stephen Hemmingerb1153f22008-03-21 15:46:12 -07002207 if (sk_filter(sk, skb))
2208 kfree_skb(skb);
Eric Dumazet4a7e7c22012-04-05 22:17:46 +00002209 else
2210 __netlink_sendskb(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211
Thomas Grafa8f74b22005-11-10 02:25:52 +01002212 if (cb->done)
2213 cb->done(cb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002215 nlk->cb_running = false;
Herbert Xu92964c72016-05-16 17:28:16 +08002216 module = cb->module;
2217 skb = cb->skb;
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002218 mutex_unlock(nlk->cb_mutex);
Herbert Xu92964c72016-05-16 17:28:16 +08002219 module_put(module);
2220 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221 return 0;
Thomas Graf17977542005-06-18 22:53:48 -07002222
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002223errout_skb:
Patrick McHardyaf65bdf2007-04-20 14:14:21 -07002224 mutex_unlock(nlk->cb_mutex);
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002225 kfree_skb(skb);
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002226 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227}
2228
Gao feng6dc878a2012-10-04 20:15:48 +00002229int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
2230 const struct nlmsghdr *nlh,
2231 struct netlink_dump_control *control)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232{
2233 struct netlink_callback *cb;
2234 struct sock *sk;
2235 struct netlink_sock *nlk;
Andrey Vaginb44d2112011-02-21 02:40:47 +00002236 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237
Florian Westphald1b4c682016-02-18 15:03:24 +01002238 atomic_inc(&skb->users);
Patrick McHardyf9c22882013-04-17 06:47:04 +00002239
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002240 sk = netlink_lookup(sock_net(ssk), ssk->sk_protocol, NETLINK_CB(skb).portid);
2241 if (sk == NULL) {
2242 ret = -ECONNREFUSED;
2243 goto error_free;
2244 }
2245
2246 nlk = nlk_sk(sk);
2247 mutex_lock(nlk->cb_mutex);
2248 /* A dump is in progress... */
2249 if (nlk->cb_running) {
2250 ret = -EBUSY;
2251 goto error_unlock;
2252 }
2253 /* add reference of module which cb->dump belongs to */
2254 if (!try_module_get(control->module)) {
2255 ret = -EPROTONOSUPPORT;
2256 goto error_unlock;
2257 }
2258
2259 cb = &nlk->cb;
2260 memset(cb, 0, sizeof(*cb));
Tom Herbertfc9e50f2015-12-15 15:41:37 -08002261 cb->start = control->start;
Pablo Neira Ayuso80d326f2012-02-24 14:30:15 +00002262 cb->dump = control->dump;
2263 cb->done = control->done;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264 cb->nlh = nlh;
Pablo Neira Ayuso7175c882012-02-24 14:30:16 +00002265 cb->data = control->data;
Gao feng6dc878a2012-10-04 20:15:48 +00002266 cb->module = control->module;
Pablo Neira Ayuso80d326f2012-02-24 14:30:15 +00002267 cb->min_dump_alloc = control->min_dump_alloc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268 cb->skb = skb;
2269
Jason A. Donenfeld4cd69ad2017-10-09 14:14:51 +02002270 if (cb->start) {
2271 ret = cb->start(cb);
2272 if (ret)
Jason A. Donenfelde7b12ef2018-02-21 04:41:59 +01002273 goto error_put;
Jason A. Donenfeld4cd69ad2017-10-09 14:14:51 +02002274 }
2275
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002276 nlk->cb_running = true;
Jason A. Donenfeld99aa74c2017-11-09 13:04:44 +09002277 nlk->dump_done_errno = INT_MAX;
Gao feng6dc878a2012-10-04 20:15:48 +00002278
Patrick McHardyaf65bdf2007-04-20 14:14:21 -07002279 mutex_unlock(nlk->cb_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280
Jason A. Donenfeld4cd69ad2017-10-09 14:14:51 +02002281 ret = netlink_dump(sk);
Jason A. Donenfeldb4a11922017-09-28 00:41:44 +02002282
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283 sock_put(sk);
Denis V. Lunev5c582982007-10-23 20:29:25 -07002284
Andrey Vaginb44d2112011-02-21 02:40:47 +00002285 if (ret)
2286 return ret;
2287
Denis V. Lunev5c582982007-10-23 20:29:25 -07002288 /* We successfully started a dump, by returning -EINTR we
2289 * signal not to send ACK even if it was requested.
2290 */
2291 return -EINTR;
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002292
Jason A. Donenfelde7b12ef2018-02-21 04:41:59 +01002293error_put:
2294 module_put(control->module);
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002295error_unlock:
2296 sock_put(sk);
2297 mutex_unlock(nlk->cb_mutex);
2298error_free:
2299 kfree_skb(skb);
2300 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002301}
Gao feng6dc878a2012-10-04 20:15:48 +00002302EXPORT_SYMBOL(__netlink_dump_start);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303
2304void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
2305{
2306 struct sk_buff *skb;
2307 struct nlmsghdr *rep;
2308 struct nlmsgerr *errmsg;
Thomas Graf339bf982006-11-10 14:10:15 -08002309 size_t payload = sizeof(*errmsg);
Christophe Ricard0a6a3a22015-08-28 07:07:48 +02002310 struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002311
Christophe Ricard0a6a3a22015-08-28 07:07:48 +02002312 /* Error messages get the original request appened, unless the user
2313 * requests to cap the error message.
2314 */
2315 if (!(nlk->flags & NETLINK_F_CAP_ACK) && err)
Thomas Graf339bf982006-11-10 14:10:15 -08002316 payload += nlmsg_len(nlh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317
Florian Westphalc5b0db32016-02-18 15:03:28 +01002318 skb = nlmsg_new(payload, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 if (!skb) {
2320 struct sock *sk;
2321
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09002322 sk = netlink_lookup(sock_net(in_skb->sk),
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002323 in_skb->sk->sk_protocol,
Eric W. Biederman15e47302012-09-07 20:12:54 +00002324 NETLINK_CB(in_skb).portid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325 if (sk) {
2326 sk->sk_err = ENOBUFS;
2327 sk->sk_error_report(sk);
2328 sock_put(sk);
2329 }
2330 return;
2331 }
2332
Eric W. Biederman15e47302012-09-07 20:12:54 +00002333 rep = __nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
John Fastabend5dba93a2009-09-25 13:11:44 +00002334 NLMSG_ERROR, payload, 0);
Thomas Grafbf8b79e2006-08-04 23:03:29 -07002335 errmsg = nlmsg_data(rep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336 errmsg->error = err;
Christophe Ricard0a6a3a22015-08-28 07:07:48 +02002337 memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh));
Eric W. Biederman15e47302012-09-07 20:12:54 +00002338 netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid, MSG_DONTWAIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002340EXPORT_SYMBOL(netlink_ack);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07002342int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
Thomas Graf1d00a4e2007-03-22 23:30:12 -07002343 struct nlmsghdr *))
Thomas Graf82ace472005-11-10 02:25:53 +01002344{
Thomas Graf82ace472005-11-10 02:25:53 +01002345 struct nlmsghdr *nlh;
2346 int err;
2347
2348 while (skb->len >= nlmsg_total_size(0)) {
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07002349 int msglen;
2350
Arnaldo Carvalho de Melob529ccf2007-04-25 19:08:35 -07002351 nlh = nlmsg_hdr(skb);
Thomas Grafd35b6852007-03-22 23:28:46 -07002352 err = 0;
Thomas Graf82ace472005-11-10 02:25:53 +01002353
Martin Murrayad8e4b72006-01-10 13:02:29 -08002354 if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len)
Thomas Graf82ace472005-11-10 02:25:53 +01002355 return 0;
2356
Thomas Grafd35b6852007-03-22 23:28:46 -07002357 /* Only requests are handled by the kernel */
2358 if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
Denis V. Lunev5c582982007-10-23 20:29:25 -07002359 goto ack;
Thomas Grafd35b6852007-03-22 23:28:46 -07002360
Thomas Graf45e7ae72007-03-22 23:29:10 -07002361 /* Skip control messages */
2362 if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
Denis V. Lunev5c582982007-10-23 20:29:25 -07002363 goto ack;
Thomas Graf45e7ae72007-03-22 23:29:10 -07002364
Thomas Graf1d00a4e2007-03-22 23:30:12 -07002365 err = cb(skb, nlh);
Denis V. Lunev5c582982007-10-23 20:29:25 -07002366 if (err == -EINTR)
2367 goto skip;
2368
2369ack:
Thomas Grafd35b6852007-03-22 23:28:46 -07002370 if (nlh->nlmsg_flags & NLM_F_ACK || err)
Thomas Graf82ace472005-11-10 02:25:53 +01002371 netlink_ack(skb, nlh, err);
Thomas Graf82ace472005-11-10 02:25:53 +01002372
Denis V. Lunev5c582982007-10-23 20:29:25 -07002373skip:
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002374 msglen = NLMSG_ALIGN(nlh->nlmsg_len);
Denis V. Lunevcd40b7d2007-10-10 21:15:29 -07002375 if (msglen > skb->len)
2376 msglen = skb->len;
2377 skb_pull(skb, msglen);
Thomas Graf82ace472005-11-10 02:25:53 +01002378 }
2379
2380 return 0;
2381}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002382EXPORT_SYMBOL(netlink_rcv_skb);
Thomas Graf82ace472005-11-10 02:25:53 +01002383
2384/**
Thomas Grafd387f6a2006-08-15 00:31:06 -07002385 * nlmsg_notify - send a notification netlink message
2386 * @sk: netlink socket to use
2387 * @skb: notification message
Eric W. Biederman15e47302012-09-07 20:12:54 +00002388 * @portid: destination netlink portid for reports or 0
Thomas Grafd387f6a2006-08-15 00:31:06 -07002389 * @group: destination multicast group or 0
2390 * @report: 1 to report back, 0 to disable
2391 * @flags: allocation flags
2392 */
Eric W. Biederman15e47302012-09-07 20:12:54 +00002393int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid,
Thomas Grafd387f6a2006-08-15 00:31:06 -07002394 unsigned int group, int report, gfp_t flags)
2395{
2396 int err = 0;
2397
2398 if (group) {
Eric W. Biederman15e47302012-09-07 20:12:54 +00002399 int exclude_portid = 0;
Thomas Grafd387f6a2006-08-15 00:31:06 -07002400
2401 if (report) {
2402 atomic_inc(&skb->users);
Eric W. Biederman15e47302012-09-07 20:12:54 +00002403 exclude_portid = portid;
Thomas Grafd387f6a2006-08-15 00:31:06 -07002404 }
2405
Pablo Neira Ayuso1ce85fe2009-02-24 23:18:28 -08002406 /* errors reported via destination sk->sk_err, but propagate
2407 * delivery errors if NETLINK_BROADCAST_ERROR flag is set */
Eric W. Biederman15e47302012-09-07 20:12:54 +00002408 err = nlmsg_multicast(sk, skb, exclude_portid, group, flags);
Thomas Grafd387f6a2006-08-15 00:31:06 -07002409 }
2410
Pablo Neira Ayuso1ce85fe2009-02-24 23:18:28 -08002411 if (report) {
2412 int err2;
2413
Eric W. Biederman15e47302012-09-07 20:12:54 +00002414 err2 = nlmsg_unicast(sk, skb, portid);
Pablo Neira Ayuso1ce85fe2009-02-24 23:18:28 -08002415 if (!err || err == -ESRCH)
2416 err = err2;
2417 }
Thomas Grafd387f6a2006-08-15 00:31:06 -07002418
2419 return err;
2420}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002421EXPORT_SYMBOL(nlmsg_notify);
Thomas Grafd387f6a2006-08-15 00:31:06 -07002422
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423#ifdef CONFIG_PROC_FS
2424struct nl_seq_iter {
Denis V. Luneve372c412007-11-19 22:31:54 -08002425 struct seq_net_private p;
Herbert Xu56d28b12015-02-04 07:33:24 +11002426 struct rhashtable_iter hti;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427 int link;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002428};
2429
Herbert Xu56d28b12015-02-04 07:33:24 +11002430static int netlink_walk_start(struct nl_seq_iter *iter)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002431{
Herbert Xu56d28b12015-02-04 07:33:24 +11002432 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433
Bob Copeland8f6fd832016-03-02 10:09:19 -05002434 err = rhashtable_walk_init(&nl_table[iter->link].hash, &iter->hti,
2435 GFP_KERNEL);
Herbert Xu56d28b12015-02-04 07:33:24 +11002436 if (err) {
2437 iter->link = MAX_LINKS;
2438 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439 }
Herbert Xu56d28b12015-02-04 07:33:24 +11002440
2441 err = rhashtable_walk_start(&iter->hti);
2442 return err == -EAGAIN ? 0 : err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443}
2444
Herbert Xu56d28b12015-02-04 07:33:24 +11002445static void netlink_walk_stop(struct nl_seq_iter *iter)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446{
Herbert Xu56d28b12015-02-04 07:33:24 +11002447 rhashtable_walk_stop(&iter->hti);
2448 rhashtable_walk_exit(&iter->hti);
2449}
2450
2451static void *__netlink_seq_next(struct seq_file *seq)
2452{
2453 struct nl_seq_iter *iter = seq->private;
2454 struct netlink_sock *nlk;
2455
2456 do {
2457 for (;;) {
2458 int err;
2459
2460 nlk = rhashtable_walk_next(&iter->hti);
2461
2462 if (IS_ERR(nlk)) {
2463 if (PTR_ERR(nlk) == -EAGAIN)
2464 continue;
2465
2466 return nlk;
2467 }
2468
2469 if (nlk)
2470 break;
2471
2472 netlink_walk_stop(iter);
2473 if (++iter->link >= MAX_LINKS)
2474 return NULL;
2475
2476 err = netlink_walk_start(iter);
2477 if (err)
2478 return ERR_PTR(err);
2479 }
2480 } while (sock_net(&nlk->sk) != seq_file_net(seq));
2481
2482 return nlk;
2483}
2484
2485static void *netlink_seq_start(struct seq_file *seq, loff_t *posp)
2486{
2487 struct nl_seq_iter *iter = seq->private;
2488 void *obj = SEQ_START_TOKEN;
2489 loff_t pos;
2490 int err;
2491
2492 iter->link = 0;
2493
2494 err = netlink_walk_start(iter);
2495 if (err)
2496 return ERR_PTR(err);
2497
2498 for (pos = *posp; pos && obj && !IS_ERR(obj); pos--)
2499 obj = __netlink_seq_next(seq);
2500
2501 return obj;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502}
2503
2504static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2505{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506 ++*pos;
Herbert Xu56d28b12015-02-04 07:33:24 +11002507 return __netlink_seq_next(seq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508}
2509
2510static void netlink_seq_stop(struct seq_file *seq, void *v)
2511{
Herbert Xu56d28b12015-02-04 07:33:24 +11002512 struct nl_seq_iter *iter = seq->private;
2513
2514 if (iter->link >= MAX_LINKS)
2515 return;
2516
2517 netlink_walk_stop(iter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002518}
2519
2520
2521static int netlink_seq_show(struct seq_file *seq, void *v)
2522{
Eric Dumazet658cb352012-04-22 21:30:21 +00002523 if (v == SEQ_START_TOKEN) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524 seq_puts(seq,
2525 "sk Eth Pid Groups "
Masatake YAMATOcf0aa4e2010-02-27 19:45:37 +00002526 "Rmem Wmem Dump Locks Drops Inode\n");
Eric Dumazet658cb352012-04-22 21:30:21 +00002527 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528 struct sock *s = v;
2529 struct netlink_sock *nlk = nlk_sk(s);
2530
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002531 seq_printf(seq, "%pK %-3d %-6u %08x %-8d %-8d %d %-8d %-8d %-8lu\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532 s,
2533 s->sk_protocol,
Eric W. Biederman15e47302012-09-07 20:12:54 +00002534 nlk->portid,
Patrick McHardy513c2502005-09-06 15:43:59 -07002535 nlk->groups ? (u32)nlk->groups[0] : 0,
Eric Dumazet31e6d362009-06-17 19:05:41 -07002536 sk_rmem_alloc_get(s),
2537 sk_wmem_alloc_get(s),
Pravin B Shelar16b304f2013-08-15 15:31:06 -07002538 nlk->cb_running,
Pablo Neira Ayuso38938bf2009-03-24 16:37:55 -07002539 atomic_read(&s->sk_refcnt),
Masatake YAMATOcf0aa4e2010-02-27 19:45:37 +00002540 atomic_read(&s->sk_drops),
2541 sock_i_ino(s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002542 );
2543
2544 }
2545 return 0;
2546}
2547
Philippe De Muyter56b3d972007-07-10 23:07:31 -07002548static const struct seq_operations netlink_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 .start = netlink_seq_start,
2550 .next = netlink_seq_next,
2551 .stop = netlink_seq_stop,
2552 .show = netlink_seq_show,
2553};
2554
2555
2556static int netlink_seq_open(struct inode *inode, struct file *file)
2557{
Denis V. Luneve372c412007-11-19 22:31:54 -08002558 return seq_open_net(inode, file, &netlink_seq_ops,
2559 sizeof(struct nl_seq_iter));
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002560}
2561
Arjan van de Venda7071d2007-02-12 00:55:36 -08002562static const struct file_operations netlink_seq_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563 .owner = THIS_MODULE,
2564 .open = netlink_seq_open,
2565 .read = seq_read,
2566 .llseek = seq_lseek,
Denis V. Luneve372c412007-11-19 22:31:54 -08002567 .release = seq_release_net,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568};
2569
2570#endif
2571
2572int netlink_register_notifier(struct notifier_block *nb)
2573{
Alan Sterne041c682006-03-27 01:16:30 -08002574 return atomic_notifier_chain_register(&netlink_chain, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002576EXPORT_SYMBOL(netlink_register_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577
2578int netlink_unregister_notifier(struct notifier_block *nb)
2579{
Alan Sterne041c682006-03-27 01:16:30 -08002580 return atomic_notifier_chain_unregister(&netlink_chain, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002581}
Patrick McHardy6ac552f2007-12-04 00:19:38 -08002582EXPORT_SYMBOL(netlink_unregister_notifier);
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09002583
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08002584static const struct proto_ops netlink_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585 .family = PF_NETLINK,
2586 .owner = THIS_MODULE,
2587 .release = netlink_release,
2588 .bind = netlink_bind,
2589 .connect = netlink_connect,
2590 .socketpair = sock_no_socketpair,
2591 .accept = sock_no_accept,
2592 .getname = netlink_getname,
Florian Westphald1b4c682016-02-18 15:03:24 +01002593 .poll = datagram_poll,
David Decotigny025c6812016-03-21 10:15:35 -07002594 .ioctl = netlink_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002595 .listen = sock_no_listen,
2596 .shutdown = sock_no_shutdown,
Patrick McHardy9a4595b2005-08-15 12:32:15 -07002597 .setsockopt = netlink_setsockopt,
2598 .getsockopt = netlink_getsockopt,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002599 .sendmsg = netlink_sendmsg,
2600 .recvmsg = netlink_recvmsg,
Florian Westphald1b4c682016-02-18 15:03:24 +01002601 .mmap = sock_no_mmap,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602 .sendpage = sock_no_sendpage,
2603};
2604
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00002605static const struct net_proto_family netlink_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606 .family = PF_NETLINK,
2607 .create = netlink_create,
2608 .owner = THIS_MODULE, /* for consistency 8) */
2609};
2610
Pavel Emelyanov46650792007-10-08 20:38:39 -07002611static int __net_init netlink_net_init(struct net *net)
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002612{
2613#ifdef CONFIG_PROC_FS
Gao fengd4beaa62013-02-18 01:34:54 +00002614 if (!proc_create("netlink", 0, net->proc_net, &netlink_seq_fops))
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002615 return -ENOMEM;
2616#endif
2617 return 0;
2618}
2619
Pavel Emelyanov46650792007-10-08 20:38:39 -07002620static void __net_exit netlink_net_exit(struct net *net)
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002621{
2622#ifdef CONFIG_PROC_FS
Gao fengece31ff2013-02-18 01:34:56 +00002623 remove_proc_entry("netlink", net->proc_net);
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002624#endif
2625}
2626
David S. Millerb963ea82010-08-30 19:08:01 -07002627static void __init netlink_add_usersock_entry(void)
2628{
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002629 struct listeners *listeners;
David S. Millerb963ea82010-08-30 19:08:01 -07002630 int groups = 32;
2631
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002632 listeners = kzalloc(sizeof(*listeners) + NLGRPSZ(groups), GFP_KERNEL);
David S. Millerb963ea82010-08-30 19:08:01 -07002633 if (!listeners)
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002634 panic("netlink_add_usersock_entry: Cannot allocate listeners\n");
David S. Millerb963ea82010-08-30 19:08:01 -07002635
2636 netlink_table_grab();
2637
2638 nl_table[NETLINK_USERSOCK].groups = groups;
Eric Dumazet5c398dc2010-10-24 04:27:10 +00002639 rcu_assign_pointer(nl_table[NETLINK_USERSOCK].listeners, listeners);
David S. Millerb963ea82010-08-30 19:08:01 -07002640 nl_table[NETLINK_USERSOCK].module = THIS_MODULE;
2641 nl_table[NETLINK_USERSOCK].registered = 1;
Pablo Neira Ayuso9785e102012-09-08 02:53:53 +00002642 nl_table[NETLINK_USERSOCK].flags = NL_CFG_F_NONROOT_SEND;
David S. Millerb963ea82010-08-30 19:08:01 -07002643
2644 netlink_table_ungrab();
2645}
2646
Denis V. Lunev022cbae2007-11-13 03:23:50 -08002647static struct pernet_operations __net_initdata netlink_net_ops = {
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002648 .init = netlink_net_init,
2649 .exit = netlink_net_exit,
2650};
2651
Patrick McHardy49f7b332015-03-25 13:07:45 +00002652static inline u32 netlink_hash(const void *data, u32 len, u32 seed)
Herbert Xuc428ecd2015-03-20 21:57:01 +11002653{
2654 const struct netlink_sock *nlk = data;
2655 struct netlink_compare_arg arg;
2656
Herbert Xuda314c92015-09-22 11:38:56 +08002657 netlink_compare_arg_init(&arg, sock_net(&nlk->sk), nlk->portid);
Herbert Xu11b58ba2015-03-24 00:50:22 +11002658 return jhash2((u32 *)&arg, netlink_compare_arg_len / sizeof(u32), seed);
Herbert Xuc428ecd2015-03-20 21:57:01 +11002659}
2660
2661static const struct rhashtable_params netlink_rhashtable_params = {
2662 .head_offset = offsetof(struct netlink_sock, node),
2663 .key_len = netlink_compare_arg_len,
Herbert Xuc428ecd2015-03-20 21:57:01 +11002664 .obj_hashfn = netlink_hash,
2665 .obj_cmpfn = netlink_compare,
Thomas Grafb5e2c152015-03-24 20:42:19 +00002666 .automatic_shrinking = true,
Herbert Xuc428ecd2015-03-20 21:57:01 +11002667};
2668
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669static int __init netlink_proto_init(void)
2670{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002672 int err = proto_register(&netlink_proto, 0);
2673
2674 if (err != 0)
2675 goto out;
2676
YOSHIFUJI Hideaki / 吉藤英明fab25742013-01-09 07:19:48 +00002677 BUILD_BUG_ON(sizeof(struct netlink_skb_parms) > FIELD_SIZEOF(struct sk_buff, cb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678
Panagiotis Issaris0da974f2006-07-21 14:51:30 -07002679 nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);
Akinobu Mitafab2caf2006-08-29 02:15:24 -07002680 if (!nl_table)
2681 goto panic;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002682
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683 for (i = 0; i < MAX_LINKS; i++) {
Herbert Xuc428ecd2015-03-20 21:57:01 +11002684 if (rhashtable_init(&nl_table[i].hash,
2685 &netlink_rhashtable_params) < 0) {
Thomas Grafe3416942014-08-02 11:47:45 +02002686 while (--i > 0)
2687 rhashtable_destroy(&nl_table[i].hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688 kfree(nl_table);
Akinobu Mitafab2caf2006-08-29 02:15:24 -07002689 goto panic;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691 }
2692
Daniel Borkmannbcbde0d2013-06-21 19:38:07 +02002693 INIT_LIST_HEAD(&netlink_tap_all);
2694
David S. Millerb963ea82010-08-30 19:08:01 -07002695 netlink_add_usersock_entry();
2696
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697 sock_register(&netlink_family_ops);
Eric W. Biedermanb4b51022007-09-12 13:05:38 +02002698 register_pernet_subsys(&netlink_net_ops);
YOSHIFUJI Hideaki746fac42007-02-09 23:25:07 +09002699 /* The netlink device handler may be needed early. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002700 rtnetlink_init();
2701out:
2702 return err;
Akinobu Mitafab2caf2006-08-29 02:15:24 -07002703panic:
2704 panic("netlink_init: Cannot allocate nl_table\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705}
2706
Linus Torvalds1da177e2005-04-16 15:20:36 -07002707core_initcall(netlink_proto_init);