1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * NetLabel Unlabeled Support
4 *
5 * This file defines functions for dealing with unlabeled packets for the
6 * NetLabel system.  The NetLabel system manages static and dynamic label
7 * mappings for network protocols such as CIPSO and RIPSO.
8 *
9 * Author: Paul Moore <paul@paul-moore.com>
10 */
11
12/*
13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2008
14 */
15
16#include <linux/types.h>
17#include <linux/rcupdate.h>
18#include <linux/list.h>
19#include <linux/spinlock.h>
20#include <linux/socket.h>
21#include <linux/string.h>
22#include <linux/skbuff.h>
23#include <linux/audit.h>
24#include <linux/in.h>
25#include <linux/in6.h>
26#include <linux/ip.h>
27#include <linux/ipv6.h>
28#include <linux/notifier.h>
29#include <linux/netdevice.h>
30#include <linux/security.h>
31#include <linux/slab.h>
32#include <net/sock.h>
33#include <net/netlink.h>
34#include <net/genetlink.h>
35#include <net/ip.h>
36#include <net/ipv6.h>
37#include <net/net_namespace.h>
38#include <net/netlabel.h>
39#include <asm/bug.h>
40#include <linux/atomic.h>
41
42#include "netlabel_user.h"
43#include "netlabel_addrlist.h"
44#include "netlabel_domainhash.h"
45#include "netlabel_unlabeled.h"
46#include "netlabel_mgmt.h"
47
48/* NOTE: at present we always use init's network namespace since we don't
49 *       presently support different namespaces even though the majority of
50 *       the functions in this file are "namespace safe" */
51
52/* The unlabeled connection hash table which we use to map network interfaces
53 * and addresses of unlabeled packets to a user specified secid value for the
54 * LSM.  The hash table is used to lookup the network interface entry
55 * (struct netlbl_unlhsh_iface) and then the interface entry is used to
56 * lookup an IP address match from an ordered list.  If a network interface
57 * match can not be found in the hash table then the default entry
58 * (netlbl_unlhsh_def) is used.  The IP address entry list
59 * (struct netlbl_unlhsh_addr) is ordered such that the entries with a
60 * larger netmask come first.
61 */
62struct netlbl_unlhsh_tbl {
63	struct list_head *tbl;
64	u32 size;
65};
66#define netlbl_unlhsh_addr4_entry(iter) \
67	container_of(iter, struct netlbl_unlhsh_addr4, list)
68struct netlbl_unlhsh_addr4 {
69	u32 secid;
70
71	struct netlbl_af4list list;
72	struct rcu_head rcu;
73};
74#define netlbl_unlhsh_addr6_entry(iter) \
75	container_of(iter, struct netlbl_unlhsh_addr6, list)
76struct netlbl_unlhsh_addr6 {
77	u32 secid;
78
79	struct netlbl_af6list list;
80	struct rcu_head rcu;
81};
82struct netlbl_unlhsh_iface {
83	int ifindex;
84	struct list_head addr4_list;
85	struct list_head addr6_list;
86
87	u32 valid;
88	struct list_head list;
89	struct rcu_head rcu;
90};
91
92/* Argument struct for netlbl_unlhsh_walk() */
93struct netlbl_unlhsh_walk_arg {
94	struct netlink_callback *nl_cb;
95	struct sk_buff *skb;
96	u32 seq;
97};
98
99/* Unlabeled connection hash table */
100/* updates should be so rare that having one spinlock for the entire
101 * hash table should be okay */
102static DEFINE_SPINLOCK(netlbl_unlhsh_lock);
103#define netlbl_unlhsh_rcu_deref(p) \
104	rcu_dereference_check(p, lockdep_is_held(&netlbl_unlhsh_lock))
105static struct netlbl_unlhsh_tbl __rcu *netlbl_unlhsh;
106static struct netlbl_unlhsh_iface __rcu *netlbl_unlhsh_def;
107
108/* Accept unlabeled packets flag */
109static u8 netlabel_unlabel_acceptflg;
110
111/* NetLabel Generic NETLINK unlabeled family */
112static struct genl_family netlbl_unlabel_gnl_family;
113
114/* NetLabel Netlink attribute policy */
115static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
116	[NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
117	[NLBL_UNLABEL_A_IPV6ADDR] = { .type = NLA_BINARY,
118				      .len = sizeof(struct in6_addr) },
119	[NLBL_UNLABEL_A_IPV6MASK] = { .type = NLA_BINARY,
120				      .len = sizeof(struct in6_addr) },
121	[NLBL_UNLABEL_A_IPV4ADDR] = { .type = NLA_BINARY,
122				      .len = sizeof(struct in_addr) },
123	[NLBL_UNLABEL_A_IPV4MASK] = { .type = NLA_BINARY,
124				      .len = sizeof(struct in_addr) },
125	[NLBL_UNLABEL_A_IFACE] = { .type = NLA_NUL_STRING,
126				   .len = IFNAMSIZ - 1 },
127	[NLBL_UNLABEL_A_SECCTX] = { .type = NLA_BINARY }
128};
129
130/*
131 * Unlabeled Connection Hash Table Functions
132 */
133
134/**
135 * netlbl_unlhsh_free_iface - Frees an interface entry from the hash table
136 * @entry: the entry's RCU field
137 *
138 * Description:
139 * This function is designed to be used as a callback to the call_rcu()
140 * function so that memory allocated to a hash table interface entry can be
141 * released safely.  It is important to note that this function does not free
142 * the IPv4 and IPv6 address lists contained as part of an interface entry.  It
143 * is up to the rest of the code to make sure an interface entry is only freed
144 * once it's address lists are empty.
145 *
146 */
147static void netlbl_unlhsh_free_iface(struct rcu_head *entry)
148{
149	struct netlbl_unlhsh_iface *iface;
150	struct netlbl_af4list *iter4;
151	struct netlbl_af4list *tmp4;
152#if IS_ENABLED(CONFIG_IPV6)
153	struct netlbl_af6list *iter6;
154	struct netlbl_af6list *tmp6;
155#endif /* IPv6 */
156
157	iface = container_of(entry, struct netlbl_unlhsh_iface, rcu);
158
159	/* no need for locks here since we are the only one with access to this
160	 * structure */
161
162	netlbl_af4list_foreach_safe(iter4, tmp4, &iface->addr4_list) {
163		netlbl_af4list_remove_entry(iter4);
164		kfree(netlbl_unlhsh_addr4_entry(iter4));
165	}
166#if IS_ENABLED(CONFIG_IPV6)
167	netlbl_af6list_foreach_safe(iter6, tmp6, &iface->addr6_list) {
168		netlbl_af6list_remove_entry(iter6);
169		kfree(netlbl_unlhsh_addr6_entry(iter6));
170	}
171#endif /* IPv6 */
172	kfree(iface);
173}
174
175/**
176 * netlbl_unlhsh_hash - Hashing function for the hash table
177 * @ifindex: the network interface/device to hash
178 *
179 * Description:
180 * This is the hashing function for the unlabeled hash table, it returns the
181 * bucket number for the given device/interface.  The caller is responsible for
182 * ensuring that the hash table is protected with either a RCU read lock or
183 * the hash table lock.
184 *
185 */
186static u32 netlbl_unlhsh_hash(int ifindex)
187{
188	return ifindex & (netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->size - 1);
189}
190
191/**
192 * netlbl_unlhsh_search_iface - Search for a matching interface entry
193 * @ifindex: the network interface
194 *
195 * Description:
196 * Searches the unlabeled connection hash table and returns a pointer to the
197 * interface entry which matches @ifindex, otherwise NULL is returned.  The
198 * caller is responsible for ensuring that the hash table is protected with
199 * either a RCU read lock or the hash table lock.
200 *
201 */
202static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
203{
204	u32 bkt;
205	struct list_head *bkt_list;
206	struct netlbl_unlhsh_iface *iter;
207
208	bkt = netlbl_unlhsh_hash(ifindex);
209	bkt_list = &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt];
210	list_for_each_entry_rcu(iter, bkt_list, list,
211				lockdep_is_held(&netlbl_unlhsh_lock))
212		if (iter->valid && iter->ifindex == ifindex)
213			return iter;
214
215	return NULL;
216}
217
218/**
219 * netlbl_unlhsh_add_addr4 - Add a new IPv4 address entry to the hash table
220 * @iface: the associated interface entry
221 * @addr: IPv4 address in network byte order
222 * @mask: IPv4 address mask in network byte order
223 * @secid: LSM secid value for entry
224 *
225 * Description:
226 * Add a new address entry into the unlabeled connection hash table using the
227 * interface entry specified by @iface.  On success zero is returned, otherwise
228 * a negative value is returned.
229 *
230 */
231static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
232				   const struct in_addr *addr,
233				   const struct in_addr *mask,
234				   u32 secid)
235{
236	int ret_val;
237	struct netlbl_unlhsh_addr4 *entry;
238
239	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
240	if (entry == NULL)
241		return -ENOMEM;
242
243	entry->list.addr = addr->s_addr & mask->s_addr;
244	entry->list.mask = mask->s_addr;
245	entry->list.valid = 1;
246	entry->secid = secid;
247
248	spin_lock(&netlbl_unlhsh_lock);
249	ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list);
250	spin_unlock(&netlbl_unlhsh_lock);
251
252	if (ret_val != 0)
253		kfree(entry);
254	return ret_val;
255}
256
257#if IS_ENABLED(CONFIG_IPV6)
258/**
259 * netlbl_unlhsh_add_addr6 - Add a new IPv6 address entry to the hash table
260 * @iface: the associated interface entry
261 * @addr: IPv6 address in network byte order
262 * @mask: IPv6 address mask in network byte order
263 * @secid: LSM secid value for entry
264 *
265 * Description:
266 * Add a new address entry into the unlabeled connection hash table using the
267 * interface entry specified by @iface.  On success zero is returned, otherwise
268 * a negative value is returned.
269 *
270 */
271static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
272				   const struct in6_addr *addr,
273				   const struct in6_addr *mask,
274				   u32 secid)
275{
276	int ret_val;
277	struct netlbl_unlhsh_addr6 *entry;
278
279	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
280	if (entry == NULL)
281		return -ENOMEM;
282
283	entry->list.addr = *addr;
284	entry->list.addr.s6_addr32[0] &= mask->s6_addr32[0];
285	entry->list.addr.s6_addr32[1] &= mask->s6_addr32[1];
286	entry->list.addr.s6_addr32[2] &= mask->s6_addr32[2];
287	entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
288	entry->list.mask = *mask;
289	entry->list.valid = 1;
290	entry->secid = secid;
291
292	spin_lock(&netlbl_unlhsh_lock);
293	ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list);
294	spin_unlock(&netlbl_unlhsh_lock);
295
296	if (ret_val != 0)
297		kfree(entry);
298	return 0;
299}
300#endif /* IPv6 */
301
302/**
303 * netlbl_unlhsh_add_iface - Adds a new interface entry to the hash table
304 * @ifindex: network interface
305 *
306 * Description:
307 * Add a new, empty, interface entry into the unlabeled connection hash table.
308 * On success a pointer to the new interface entry is returned, on failure NULL
309 * is returned.
310 *
311 */
312static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
313{
314	u32 bkt;
315	struct netlbl_unlhsh_iface *iface;
316
317	iface = kzalloc(sizeof(*iface), GFP_ATOMIC);
318	if (iface == NULL)
319		return NULL;
320
321	iface->ifindex = ifindex;
322	INIT_LIST_HEAD(&iface->addr4_list);
323	INIT_LIST_HEAD(&iface->addr6_list);
324	iface->valid = 1;
325
326	spin_lock(&netlbl_unlhsh_lock);
327	if (ifindex > 0) {
328		bkt = netlbl_unlhsh_hash(ifindex);
329		if (netlbl_unlhsh_search_iface(ifindex) != NULL)
330			goto add_iface_failure;
331		list_add_tail_rcu(&iface->list,
332			     &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt]);
333	} else {
334		INIT_LIST_HEAD(&iface->list);
335		if (netlbl_unlhsh_rcu_deref(netlbl_unlhsh_def) != NULL)
336			goto add_iface_failure;
337		rcu_assign_pointer(netlbl_unlhsh_def, iface);
338	}
339	spin_unlock(&netlbl_unlhsh_lock);
340
341	return iface;
342
343add_iface_failure:
344	spin_unlock(&netlbl_unlhsh_lock);
345	kfree(iface);
346	return NULL;
347}
348
349/**
350 * netlbl_unlhsh_add - Adds a new entry to the unlabeled connection hash table
351 * @net: network namespace
352 * @dev_name: interface name
353 * @addr: IP address in network byte order
354 * @mask: address mask in network byte order
355 * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6)
356 * @secid: LSM secid value for the entry
357 * @audit_info: NetLabel audit information
358 *
359 * Description:
360 * Adds a new entry to the unlabeled connection hash table.  Returns zero on
361 * success, negative values on failure.
362 *
363 */
364int netlbl_unlhsh_add(struct net *net,
365		      const char *dev_name,
366		      const void *addr,
367		      const void *mask,
368		      u32 addr_len,
369		      u32 secid,
370		      struct netlbl_audit *audit_info)
371{
372	int ret_val;
373	int ifindex;
374	struct net_device *dev;
375	struct netlbl_unlhsh_iface *iface;
376	struct audit_buffer *audit_buf = NULL;
377	char *secctx = NULL;
378	u32 secctx_len;
379
380	if (addr_len != sizeof(struct in_addr) &&
381	    addr_len != sizeof(struct in6_addr))
382		return -EINVAL;
383
384	rcu_read_lock();
385	if (dev_name != NULL) {
386		dev = dev_get_by_name_rcu(net, dev_name);
387		if (dev == NULL) {
388			ret_val = -ENODEV;
389			goto unlhsh_add_return;
390		}
391		ifindex = dev->ifindex;
392		iface = netlbl_unlhsh_search_iface(ifindex);
393	} else {
394		ifindex = 0;
395		iface = rcu_dereference(netlbl_unlhsh_def);
396	}
397	if (iface == NULL) {
398		iface = netlbl_unlhsh_add_iface(ifindex);
399		if (iface == NULL) {
400			ret_val = -ENOMEM;
401			goto unlhsh_add_return;
402		}
403	}
404	audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCADD,
405					      audit_info);
406	switch (addr_len) {
407	case sizeof(struct in_addr): {
408		const struct in_addr *addr4 = addr;
409		const struct in_addr *mask4 = mask;
410
411		ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid);
412		if (audit_buf != NULL)
413			netlbl_af4list_audit_addr(audit_buf, 1,
414						  dev_name,
415						  addr4->s_addr,
416						  mask4->s_addr);
417		break;
418	}
419#if IS_ENABLED(CONFIG_IPV6)
420	case sizeof(struct in6_addr): {
421		const struct in6_addr *addr6 = addr;
422		const struct in6_addr *mask6 = mask;
423
424		ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid);
425		if (audit_buf != NULL)
426			netlbl_af6list_audit_addr(audit_buf, 1,
427						  dev_name,
428						  addr6, mask6);
429		break;
430	}
431#endif /* IPv6 */
432	default:
433		ret_val = -EINVAL;
434	}
435	if (ret_val == 0)
436		atomic_inc(&netlabel_mgmt_protocount);
437
438unlhsh_add_return:
439	rcu_read_unlock();
440	if (audit_buf != NULL) {
441		if (security_secid_to_secctx(secid,
442					     &secctx,
443					     &secctx_len) == 0) {
444			audit_log_format(audit_buf, " sec_obj=%s", secctx);
445			security_release_secctx(secctx, secctx_len);
446		}
447		audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
448		audit_log_end(audit_buf);
449	}
450	return ret_val;
451}
452
453/**
454 * netlbl_unlhsh_remove_addr4 - Remove an IPv4 address entry
455 * @net: network namespace
456 * @iface: interface entry
457 * @addr: IP address
458 * @mask: IP address mask
459 * @audit_info: NetLabel audit information
460 *
461 * Description:
462 * Remove an IP address entry from the unlabeled connection hash table.
463 * Returns zero on success, negative values on failure.
464 *
465 */
466static int netlbl_unlhsh_remove_addr4(struct net *net,
467				      struct netlbl_unlhsh_iface *iface,
468				      const struct in_addr *addr,
469				      const struct in_addr *mask,
470				      struct netlbl_audit *audit_info)
471{
472	struct netlbl_af4list *list_entry;
473	struct netlbl_unlhsh_addr4 *entry;
474	struct audit_buffer *audit_buf;
475	struct net_device *dev;
476	char *secctx;
477	u32 secctx_len;
478
479	spin_lock(&netlbl_unlhsh_lock);
480	list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
481					   &iface->addr4_list);
482	spin_unlock(&netlbl_unlhsh_lock);
483	if (list_entry != NULL)
484		entry = netlbl_unlhsh_addr4_entry(list_entry);
485	else
486		entry = NULL;
487
488	audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
489					      audit_info);
490	if (audit_buf != NULL) {
491		dev = dev_get_by_index(net, iface->ifindex);
492		netlbl_af4list_audit_addr(audit_buf, 1,
493					  (dev != NULL ? dev->name : NULL),
494					  addr->s_addr, mask->s_addr);
495		if (dev != NULL)
496			dev_put(dev);
497		if (entry != NULL &&
498		    security_secid_to_secctx(entry->secid,
499					     &secctx, &secctx_len) == 0) {
500			audit_log_format(audit_buf, " sec_obj=%s", secctx);
501			security_release_secctx(secctx, secctx_len);
502		}
503		audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0);
504		audit_log_end(audit_buf);
505	}
506
507	if (entry == NULL)
508		return -ENOENT;
509
510	kfree_rcu(entry, rcu);
511	return 0;
512}
513
514#if IS_ENABLED(CONFIG_IPV6)
515/**
516 * netlbl_unlhsh_remove_addr6 - Remove an IPv6 address entry
517 * @net: network namespace
518 * @iface: interface entry
519 * @addr: IP address
520 * @mask: IP address mask
521 * @audit_info: NetLabel audit information
522 *
523 * Description:
524 * Remove an IP address entry from the unlabeled connection hash table.
525 * Returns zero on success, negative values on failure.
526 *
527 */
528static int netlbl_unlhsh_remove_addr6(struct net *net,
529				      struct netlbl_unlhsh_iface *iface,
530				      const struct in6_addr *addr,
531				      const struct in6_addr *mask,
532				      struct netlbl_audit *audit_info)
533{
534	struct netlbl_af6list *list_entry;
535	struct netlbl_unlhsh_addr6 *entry;
536	struct audit_buffer *audit_buf;
537	struct net_device *dev;
538	char *secctx;
539	u32 secctx_len;
540
541	spin_lock(&netlbl_unlhsh_lock);
542	list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list);
543	spin_unlock(&netlbl_unlhsh_lock);
544	if (list_entry != NULL)
545		entry = netlbl_unlhsh_addr6_entry(list_entry);
546	else
547		entry = NULL;
548
549	audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
550					      audit_info);
551	if (audit_buf != NULL) {
552		dev = dev_get_by_index(net, iface->ifindex);
553		netlbl_af6list_audit_addr(audit_buf, 1,
554					  (dev != NULL ? dev->name : NULL),
555					  addr, mask);
556		if (dev != NULL)
557			dev_put(dev);
558		if (entry != NULL &&
559		    security_secid_to_secctx(entry->secid,
560					     &secctx, &secctx_len) == 0) {
561			audit_log_format(audit_buf, " sec_obj=%s", secctx);
562			security_release_secctx(secctx, secctx_len);
563		}
564		audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0);
565		audit_log_end(audit_buf);
566	}
567
568	if (entry == NULL)
569		return -ENOENT;
570
571	kfree_rcu(entry, rcu);
572	return 0;
573}
574#endif /* IPv6 */
575
576/**
577 * netlbl_unlhsh_condremove_iface - Remove an interface entry
578 * @iface: the interface entry
579 *
580 * Description:
581 * Remove an interface entry from the unlabeled connection hash table if it is
582 * empty.  An interface entry is considered to be empty if there are no
583 * address entries assigned to it.
584 *
585 */
586static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface)
587{
588	struct netlbl_af4list *iter4;
589#if IS_ENABLED(CONFIG_IPV6)
590	struct netlbl_af6list *iter6;
591#endif /* IPv6 */
592
593	spin_lock(&netlbl_unlhsh_lock);
594	netlbl_af4list_foreach_rcu(iter4, &iface->addr4_list)
595		goto unlhsh_condremove_failure;
596#if IS_ENABLED(CONFIG_IPV6)
597	netlbl_af6list_foreach_rcu(iter6, &iface->addr6_list)
598		goto unlhsh_condremove_failure;
599#endif /* IPv6 */
600	iface->valid = 0;
601	if (iface->ifindex > 0)
602		list_del_rcu(&iface->list);
603	else
604		RCU_INIT_POINTER(netlbl_unlhsh_def, NULL);
605	spin_unlock(&netlbl_unlhsh_lock);
606
607	call_rcu(&iface->rcu, netlbl_unlhsh_free_iface);
608	return;
609
610unlhsh_condremove_failure:
611	spin_unlock(&netlbl_unlhsh_lock);
612}
613
614/**
615 * netlbl_unlhsh_remove - Remove an entry from the unlabeled hash table
616 * @net: network namespace
617 * @dev_name: interface name
618 * @addr: IP address in network byte order
619 * @mask: address mask in network byte order
620 * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6)
621 * @audit_info: NetLabel audit information
622 *
623 * Description:
624 * Removes and existing entry from the unlabeled connection hash table.
625 * Returns zero on success, negative values on failure.
626 *
627 */
628int netlbl_unlhsh_remove(struct net *net,
629			 const char *dev_name,
630			 const void *addr,
631			 const void *mask,
632			 u32 addr_len,
633			 struct netlbl_audit *audit_info)
634{
635	int ret_val;
636	struct net_device *dev;
637	struct netlbl_unlhsh_iface *iface;
638
639	if (addr_len != sizeof(struct in_addr) &&
640	    addr_len != sizeof(struct in6_addr))
641		return -EINVAL;
642
643	rcu_read_lock();
644	if (dev_name != NULL) {
645		dev = dev_get_by_name_rcu(net, dev_name);
646		if (dev == NULL) {
647			ret_val = -ENODEV;
648			goto unlhsh_remove_return;
649		}
650		iface = netlbl_unlhsh_search_iface(dev->ifindex);
651	} else
652		iface = rcu_dereference(netlbl_unlhsh_def);
653	if (iface == NULL) {
654		ret_val = -ENOENT;
655		goto unlhsh_remove_return;
656	}
657	switch (addr_len) {
658	case sizeof(struct in_addr):
659		ret_val = netlbl_unlhsh_remove_addr4(net,
660						     iface, addr, mask,
661						     audit_info);
662		break;
663#if IS_ENABLED(CONFIG_IPV6)
664	case sizeof(struct in6_addr):
665		ret_val = netlbl_unlhsh_remove_addr6(net,
666						     iface, addr, mask,
667						     audit_info);
668		break;
669#endif /* IPv6 */
670	default:
671		ret_val = -EINVAL;
672	}
673	if (ret_val == 0) {
674		netlbl_unlhsh_condremove_iface(iface);
675		atomic_dec(&netlabel_mgmt_protocount);
676	}
677
678unlhsh_remove_return:
679	rcu_read_unlock();
680	return ret_val;
681}
682
683/*
684 * General Helper Functions
685 */
686
687/**
688 * netlbl_unlhsh_netdev_handler - Network device notification handler
689 * @this: notifier block
690 * @event: the event
691 * @ptr: the netdevice notifier info (cast to void)
692 *
693 * Description:
694 * Handle network device events, although at present all we care about is a
695 * network device going away.  In the case of a device going away we clear any
696 * related entries from the unlabeled connection hash table.
697 *
698 */
699static int netlbl_unlhsh_netdev_handler(struct notifier_block *this,
700					unsigned long event, void *ptr)
701{
702	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
703	struct netlbl_unlhsh_iface *iface = NULL;
704
705	if (!net_eq(dev_net(dev), &init_net))
706		return NOTIFY_DONE;
707
708	/* XXX - should this be a check for NETDEV_DOWN or _UNREGISTER? */
709	if (event == NETDEV_DOWN) {
710		spin_lock(&netlbl_unlhsh_lock);
711		iface = netlbl_unlhsh_search_iface(dev->ifindex);
712		if (iface != NULL && iface->valid) {
713			iface->valid = 0;
714			list_del_rcu(&iface->list);
715		} else
716			iface = NULL;
717		spin_unlock(&netlbl_unlhsh_lock);
718	}
719
720	if (iface != NULL)
721		call_rcu(&iface->rcu, netlbl_unlhsh_free_iface);
722
723	return NOTIFY_DONE;
724}
725
726/**
727 * netlbl_unlabel_acceptflg_set - Set the unlabeled accept flag
728 * @value: desired value
729 * @audit_info: NetLabel audit information
730 *
731 * Description:
732 * Set the value of the unlabeled accept flag to @value.
733 *
734 */
735static void netlbl_unlabel_acceptflg_set(u8 value,
736					 struct netlbl_audit *audit_info)
737{
738	struct audit_buffer *audit_buf;
739	u8 old_val;
740
741	old_val = netlabel_unlabel_acceptflg;
742	netlabel_unlabel_acceptflg = value;
743	audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW,
744					      audit_info);
745	if (audit_buf != NULL) {
746		audit_log_format(audit_buf,
747				 " unlbl_accept=%u old=%u", value, old_val);
748		audit_log_end(audit_buf);
749	}
750}
751
752/**
753 * netlbl_unlabel_addrinfo_get - Get the IPv4/6 address information
754 * @info: the Generic NETLINK info block
755 * @addr: the IP address
756 * @mask: the IP address mask
757 * @len: the address length
758 *
759 * Description:
760 * Examine the Generic NETLINK message and extract the IP address information.
761 * Returns zero on success, negative values on failure.
762 *
763 */
764static int netlbl_unlabel_addrinfo_get(struct genl_info *info,
765				       void **addr,
766				       void **mask,
767				       u32 *len)
768{
769	u32 addr_len;
770
771	if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR] &&
772	    info->attrs[NLBL_UNLABEL_A_IPV4MASK]) {
773		addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
774		if (addr_len != sizeof(struct in_addr) &&
775		    addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK]))
776			return -EINVAL;
777		*len = addr_len;
778		*addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
779		*mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4MASK]);
780		return 0;
781	} else if (info->attrs[NLBL_UNLABEL_A_IPV6ADDR]) {
782		addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
783		if (addr_len != sizeof(struct in6_addr) &&
784		    addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV6MASK]))
785			return -EINVAL;
786		*len = addr_len;
787		*addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
788		*mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6MASK]);
789		return 0;
790	}
791
792	return -EINVAL;
793}
794
795/*
796 * NetLabel Command Handlers
797 */
798
799/**
800 * netlbl_unlabel_accept - Handle an ACCEPT message
801 * @skb: the NETLINK buffer
802 * @info: the Generic NETLINK info block
803 *
804 * Description:
805 * Process a user generated ACCEPT message and set the accept flag accordingly.
806 * Returns zero on success, negative values on failure.
807 *
808 */
809static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info)
810{
811	u8 value;
812	struct netlbl_audit audit_info;
813
814	if (info->attrs[NLBL_UNLABEL_A_ACPTFLG]) {
815		value = nla_get_u8(info->attrs[NLBL_UNLABEL_A_ACPTFLG]);
816		if (value == 1 || value == 0) {
817			netlbl_netlink_auditinfo(&audit_info);
818			netlbl_unlabel_acceptflg_set(value, &audit_info);
819			return 0;
820		}
821	}
822
823	return -EINVAL;
824}
825
826/**
827 * netlbl_unlabel_list - Handle a LIST message
828 * @skb: the NETLINK buffer
829 * @info: the Generic NETLINK info block
830 *
831 * Description:
832 * Process a user generated LIST message and respond with the current status.
833 * Returns zero on success, negative values on failure.
834 *
835 */
836static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info)
837{
838	int ret_val = -EINVAL;
839	struct sk_buff *ans_skb;
840	void *data;
841
842	ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
843	if (ans_skb == NULL)
844		goto list_failure;
845	data = genlmsg_put_reply(ans_skb, info, &netlbl_unlabel_gnl_family,
846				 0, NLBL_UNLABEL_C_LIST);
847	if (data == NULL) {
848		ret_val = -ENOMEM;
849		goto list_failure;
850	}
851
852	ret_val = nla_put_u8(ans_skb,
853			     NLBL_UNLABEL_A_ACPTFLG,
854			     netlabel_unlabel_acceptflg);
855	if (ret_val != 0)
856		goto list_failure;
857
858	genlmsg_end(ans_skb, data);
859	return genlmsg_reply(ans_skb, info);
860
861list_failure:
862	kfree_skb(ans_skb);
863	return ret_val;
864}
865
866/**
867 * netlbl_unlabel_staticadd - Handle a STATICADD message
868 * @skb: the NETLINK buffer
869 * @info: the Generic NETLINK info block
870 *
871 * Description:
872 * Process a user generated STATICADD message and add a new unlabeled
873 * connection entry to the hash table.  Returns zero on success, negative
874 * values on failure.
875 *
876 */
877static int netlbl_unlabel_staticadd(struct sk_buff *skb,
878				    struct genl_info *info)
879{
880	int ret_val;
881	char *dev_name;
882	void *addr;
883	void *mask;
884	u32 addr_len;
885	u32 secid;
886	struct netlbl_audit audit_info;
887
888	/* Don't allow users to add both IPv4 and IPv6 addresses for a
889	 * single entry.  However, allow users to create two entries, one each
890	 * for IPv4 and IPv4, with the same LSM security context which should
891	 * achieve the same result. */
892	if (!info->attrs[NLBL_UNLABEL_A_SECCTX] ||
893	    !info->attrs[NLBL_UNLABEL_A_IFACE] ||
894	    !((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] ||
895	       !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^
896	      (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] ||
897	       !info->attrs[NLBL_UNLABEL_A_IPV6MASK])))
898		return -EINVAL;
899
900	netlbl_netlink_auditinfo(&audit_info);
901
902	ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len);
903	if (ret_val != 0)
904		return ret_val;
905	dev_name = nla_data(info->attrs[NLBL_UNLABEL_A_IFACE]);
906	ret_val = security_secctx_to_secid(
907		                  nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]),
908				  nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]),
909				  &secid);
910	if (ret_val != 0)
911		return ret_val;
912
913	return netlbl_unlhsh_add(&init_net,
914				 dev_name, addr, mask, addr_len, secid,
915				 &audit_info);
916}
917
918/**
919 * netlbl_unlabel_staticadddef - Handle a STATICADDDEF message
920 * @skb: the NETLINK buffer
921 * @info: the Generic NETLINK info block
922 *
923 * Description:
924 * Process a user generated STATICADDDEF message and add a new default
925 * unlabeled connection entry.  Returns zero on success, negative values on
926 * failure.
927 *
928 */
929static int netlbl_unlabel_staticadddef(struct sk_buff *skb,
930				       struct genl_info *info)
931{
932	int ret_val;
933	void *addr;
934	void *mask;
935	u32 addr_len;
936	u32 secid;
937	struct netlbl_audit audit_info;
938
939	/* Don't allow users to add both IPv4 and IPv6 addresses for a
940	 * single entry.  However, allow users to create two entries, one each
941	 * for IPv4 and IPv6, with the same LSM security context which should
942	 * achieve the same result. */
943	if (!info->attrs[NLBL_UNLABEL_A_SECCTX] ||
944	    !((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] ||
945	       !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^
946	      (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] ||
947	       !info->attrs[NLBL_UNLABEL_A_IPV6MASK])))
948		return -EINVAL;
949
950	netlbl_netlink_auditinfo(&audit_info);
951
952	ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len);
953	if (ret_val != 0)
954		return ret_val;
955	ret_val = security_secctx_to_secid(
956		                  nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]),
957				  nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]),
958				  &secid);
959	if (ret_val != 0)
960		return ret_val;
961
962	return netlbl_unlhsh_add(&init_net,
963				 NULL, addr, mask, addr_len, secid,
964				 &audit_info);
965}
966
967/**
968 * netlbl_unlabel_staticremove - Handle a STATICREMOVE message
969 * @skb: the NETLINK buffer
970 * @info: the Generic NETLINK info block
971 *
972 * Description:
973 * Process a user generated STATICREMOVE message and remove the specified
974 * unlabeled connection entry.  Returns zero on success, negative values on
975 * failure.
976 *
977 */
978static int netlbl_unlabel_staticremove(struct sk_buff *skb,
979				       struct genl_info *info)
980{
981	int ret_val;
982	char *dev_name;
983	void *addr;
984	void *mask;
985	u32 addr_len;
986	struct netlbl_audit audit_info;
987
988	/* See the note in netlbl_unlabel_staticadd() about not allowing both
989	 * IPv4 and IPv6 in the same entry. */
990	if (!info->attrs[NLBL_UNLABEL_A_IFACE] ||
991	    !((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] ||
992	       !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^
993	      (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] ||
994	       !info->attrs[NLBL_UNLABEL_A_IPV6MASK])))
995		return -EINVAL;
996
997	netlbl_netlink_auditinfo(&audit_info);
998
999	ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len);
1000	if (ret_val != 0)
1001		return ret_val;
1002	dev_name = nla_data(info->attrs[NLBL_UNLABEL_A_IFACE]);
1003
1004	return netlbl_unlhsh_remove(&init_net,
1005				    dev_name, addr, mask, addr_len,
1006				    &audit_info);
1007}
1008
1009/**
1010 * netlbl_unlabel_staticremovedef - Handle a STATICREMOVEDEF message
1011 * @skb: the NETLINK buffer
1012 * @info: the Generic NETLINK info block
1013 *
1014 * Description:
1015 * Process a user generated STATICREMOVEDEF message and remove the default
1016 * unlabeled connection entry.  Returns zero on success, negative values on
1017 * failure.
1018 *
1019 */
1020static int netlbl_unlabel_staticremovedef(struct sk_buff *skb,
1021					  struct genl_info *info)
1022{
1023	int ret_val;
1024	void *addr;
1025	void *mask;
1026	u32 addr_len;
1027	struct netlbl_audit audit_info;
1028
1029	/* See the note in netlbl_unlabel_staticadd() about not allowing both
1030	 * IPv4 and IPv6 in the same entry. */
1031	if (!((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] ||
1032	       !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^
1033	      (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] ||
1034	       !info->attrs[NLBL_UNLABEL_A_IPV6MASK])))
1035		return -EINVAL;
1036
1037	netlbl_netlink_auditinfo(&audit_info);
1038
1039	ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len);
1040	if (ret_val != 0)
1041		return ret_val;
1042
1043	return netlbl_unlhsh_remove(&init_net,
1044				    NULL, addr, mask, addr_len,
1045				    &audit_info);
1046}
1047
1048
1049/**
1050 * netlbl_unlabel_staticlist_gen - Generate messages for STATICLIST[DEF]
1051 * @cmd: command/message
1052 * @iface: the interface entry
1053 * @addr4: the IPv4 address entry
1054 * @addr6: the IPv6 address entry
1055 * @arg: the netlbl_unlhsh_walk_arg structure
1056 *
1057 * Description:
1058 * This function is designed to be used to generate a response for a
1059 * STATICLIST or STATICLISTDEF message.  When called either @addr4 or @addr6
1060 * can be specified, not both, the other unspecified entry should be set to
1061 * NULL by the caller.  Returns the size of the message on success, negative
1062 * values on failure.
1063 *
1064 */
1065static int netlbl_unlabel_staticlist_gen(u32 cmd,
1066				       const struct netlbl_unlhsh_iface *iface,
1067				       const struct netlbl_unlhsh_addr4 *addr4,
1068				       const struct netlbl_unlhsh_addr6 *addr6,
1069				       void *arg)
1070{
1071	int ret_val = -ENOMEM;
1072	struct netlbl_unlhsh_walk_arg *cb_arg = arg;
1073	struct net_device *dev;
1074	void *data;
1075	u32 secid;
1076	char *secctx;
1077	u32 secctx_len;
1078
1079	data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
1080			   cb_arg->seq, &netlbl_unlabel_gnl_family,
1081			   NLM_F_MULTI, cmd);
1082	if (data == NULL)
1083		goto list_cb_failure;
1084
1085	if (iface->ifindex > 0) {
1086		dev = dev_get_by_index(&init_net, iface->ifindex);
1087		if (!dev) {
1088			ret_val = -ENODEV;
1089			goto list_cb_failure;
1090		}
1091		ret_val = nla_put_string(cb_arg->skb,
1092					 NLBL_UNLABEL_A_IFACE, dev->name);
1093		dev_put(dev);
1094		if (ret_val != 0)
1095			goto list_cb_failure;
1096	}
1097
1098	if (addr4) {
1099		struct in_addr addr_struct;
1100
1101		addr_struct.s_addr = addr4->list.addr;
1102		ret_val = nla_put_in_addr(cb_arg->skb,
1103					  NLBL_UNLABEL_A_IPV4ADDR,
1104					  addr_struct.s_addr);
1105		if (ret_val != 0)
1106			goto list_cb_failure;
1107
1108		addr_struct.s_addr = addr4->list.mask;
1109		ret_val = nla_put_in_addr(cb_arg->skb,
1110					  NLBL_UNLABEL_A_IPV4MASK,
1111					  addr_struct.s_addr);
1112		if (ret_val != 0)
1113			goto list_cb_failure;
1114
1115		secid = addr4->secid;
1116	} else {
1117		ret_val = nla_put_in6_addr(cb_arg->skb,
1118					   NLBL_UNLABEL_A_IPV6ADDR,
1119					   &addr6->list.addr);
1120		if (ret_val != 0)
1121			goto list_cb_failure;
1122
1123		ret_val = nla_put_in6_addr(cb_arg->skb,
1124					   NLBL_UNLABEL_A_IPV6MASK,
1125					   &addr6->list.mask);
1126		if (ret_val != 0)
1127			goto list_cb_failure;
1128
1129		secid = addr6->secid;
1130	}
1131
1132	ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len);
1133	if (ret_val != 0)
1134		goto list_cb_failure;
1135	ret_val = nla_put(cb_arg->skb,
1136			  NLBL_UNLABEL_A_SECCTX,
1137			  secctx_len,
1138			  secctx);
1139	security_release_secctx(secctx, secctx_len);
1140	if (ret_val != 0)
1141		goto list_cb_failure;
1142
1143	cb_arg->seq++;
1144	genlmsg_end(cb_arg->skb, data);
1145	return 0;
1146
1147list_cb_failure:
1148	genlmsg_cancel(cb_arg->skb, data);
1149	return ret_val;
1150}
1151
1152/**
1153 * netlbl_unlabel_staticlist - Handle a STATICLIST message
1154 * @skb: the NETLINK buffer
1155 * @cb: the NETLINK callback
1156 *
1157 * Description:
1158 * Process a user generated STATICLIST message and dump the unlabeled
1159 * connection hash table in a form suitable for use in a kernel generated
1160 * STATICLIST message.  Returns the length of @skb.
1161 *
1162 */
1163static int netlbl_unlabel_staticlist(struct sk_buff *skb,
1164				     struct netlink_callback *cb)
1165{
1166	struct netlbl_unlhsh_walk_arg cb_arg;
1167	u32 skip_bkt = cb->args[0];
1168	u32 skip_chain = cb->args[1];
1169	u32 skip_addr4 = cb->args[2];
1170	u32 iter_bkt, iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0;
1171	struct netlbl_unlhsh_iface *iface;
1172	struct list_head *iter_list;
1173	struct netlbl_af4list *addr4;
1174#if IS_ENABLED(CONFIG_IPV6)
1175	u32 skip_addr6 = cb->args[3];
1176	struct netlbl_af6list *addr6;
1177#endif
1178
1179	cb_arg.nl_cb = cb;
1180	cb_arg.skb = skb;
1181	cb_arg.seq = cb->nlh->nlmsg_seq;
1182
1183	rcu_read_lock();
1184	for (iter_bkt = skip_bkt;
1185	     iter_bkt < rcu_dereference(netlbl_unlhsh)->size;
1186	     iter_bkt++) {
1187		iter_list = &rcu_dereference(netlbl_unlhsh)->tbl[iter_bkt];
1188		list_for_each_entry_rcu(iface, iter_list, list) {
1189			if (!iface->valid ||
1190			    iter_chain++ < skip_chain)
1191				continue;
1192			netlbl_af4list_foreach_rcu(addr4,
1193						   &iface->addr4_list) {
1194				if (iter_addr4++ < skip_addr4)
1195					continue;
1196				if (netlbl_unlabel_staticlist_gen(
1197					      NLBL_UNLABEL_C_STATICLIST,
1198					      iface,
1199					      netlbl_unlhsh_addr4_entry(addr4),
1200					      NULL,
1201					      &cb_arg) < 0) {
1202					iter_addr4--;
1203					iter_chain--;
1204					goto unlabel_staticlist_return;
1205				}
1206			}
1207			iter_addr4 = 0;
1208			skip_addr4 = 0;
1209#if IS_ENABLED(CONFIG_IPV6)
1210			netlbl_af6list_foreach_rcu(addr6,
1211						   &iface->addr6_list) {
1212				if (iter_addr6++ < skip_addr6)
1213					continue;
1214				if (netlbl_unlabel_staticlist_gen(
1215					      NLBL_UNLABEL_C_STATICLIST,
1216					      iface,
1217					      NULL,
1218					      netlbl_unlhsh_addr6_entry(addr6),
1219					      &cb_arg) < 0) {
1220					iter_addr6--;
1221					iter_chain--;
1222					goto unlabel_staticlist_return;
1223				}
1224			}
1225			iter_addr6 = 0;
1226			skip_addr6 = 0;
1227#endif /* IPv6 */
1228		}
1229		iter_chain = 0;
1230		skip_chain = 0;
1231	}
1232
1233unlabel_staticlist_return:
1234	rcu_read_unlock();
1235	cb->args[0] = iter_bkt;
1236	cb->args[1] = iter_chain;
1237	cb->args[2] = iter_addr4;
1238	cb->args[3] = iter_addr6;
1239	return skb->len;
1240}
1241
1242/**
1243 * netlbl_unlabel_staticlistdef - Handle a STATICLISTDEF message
1244 * @skb: the NETLINK buffer
1245 * @cb: the NETLINK callback
1246 *
1247 * Description:
1248 * Process a user generated STATICLISTDEF message and dump the default
1249 * unlabeled connection entry in a form suitable for use in a kernel generated
1250 * STATICLISTDEF message.  Returns the length of @skb.
1251 *
1252 */
1253static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
1254					struct netlink_callback *cb)
1255{
1256	struct netlbl_unlhsh_walk_arg cb_arg;
1257	struct netlbl_unlhsh_iface *iface;
1258	u32 iter_addr4 = 0, iter_addr6 = 0;
1259	struct netlbl_af4list *addr4;
1260#if IS_ENABLED(CONFIG_IPV6)
1261	struct netlbl_af6list *addr6;
1262#endif
1263
1264	cb_arg.nl_cb = cb;
1265	cb_arg.skb = skb;
1266	cb_arg.seq = cb->nlh->nlmsg_seq;
1267
1268	rcu_read_lock();
1269	iface = rcu_dereference(netlbl_unlhsh_def);
1270	if (iface == NULL || !iface->valid)
1271		goto unlabel_staticlistdef_return;
1272
1273	netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) {
1274		if (iter_addr4++ < cb->args[0])
1275			continue;
1276		if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
1277					      iface,
1278					      netlbl_unlhsh_addr4_entry(addr4),
1279					      NULL,
1280					      &cb_arg) < 0) {
1281			iter_addr4--;
1282			goto unlabel_staticlistdef_return;
1283		}
1284	}
1285#if IS_ENABLED(CONFIG_IPV6)
1286	netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) {
1287		if (iter_addr6++ < cb->args[1])
1288			continue;
1289		if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
1290					      iface,
1291					      NULL,
1292					      netlbl_unlhsh_addr6_entry(addr6),
1293					      &cb_arg) < 0) {
1294			iter_addr6--;
1295			goto unlabel_staticlistdef_return;
1296		}
1297	}
1298#endif /* IPv6 */
1299
1300unlabel_staticlistdef_return:
1301	rcu_read_unlock();
1302	cb->args[0] = iter_addr4;
1303	cb->args[1] = iter_addr6;
1304	return skb->len;
1305}
1306
1307/*
1308 * NetLabel Generic NETLINK Command Definitions
1309 */
1310
1311static const struct genl_small_ops netlbl_unlabel_genl_ops[] = {
1312	{
1313	.cmd = NLBL_UNLABEL_C_STATICADD,
1314	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1315	.flags = GENL_ADMIN_PERM,
1316	.doit = netlbl_unlabel_staticadd,
1317	.dumpit = NULL,
1318	},
1319	{
1320	.cmd = NLBL_UNLABEL_C_STATICREMOVE,
1321	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1322	.flags = GENL_ADMIN_PERM,
1323	.doit = netlbl_unlabel_staticremove,
1324	.dumpit = NULL,
1325	},
1326	{
1327	.cmd = NLBL_UNLABEL_C_STATICLIST,
1328	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1329	.flags = 0,
1330	.doit = NULL,
1331	.dumpit = netlbl_unlabel_staticlist,
1332	},
1333	{
1334	.cmd = NLBL_UNLABEL_C_STATICADDDEF,
1335	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1336	.flags = GENL_ADMIN_PERM,
1337	.doit = netlbl_unlabel_staticadddef,
1338	.dumpit = NULL,
1339	},
1340	{
1341	.cmd = NLBL_UNLABEL_C_STATICREMOVEDEF,
1342	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1343	.flags = GENL_ADMIN_PERM,
1344	.doit = netlbl_unlabel_staticremovedef,
1345	.dumpit = NULL,
1346	},
1347	{
1348	.cmd = NLBL_UNLABEL_C_STATICLISTDEF,
1349	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1350	.flags = 0,
1351	.doit = NULL,
1352	.dumpit = netlbl_unlabel_staticlistdef,
1353	},
1354	{
1355	.cmd = NLBL_UNLABEL_C_ACCEPT,
1356	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1357	.flags = GENL_ADMIN_PERM,
1358	.doit = netlbl_unlabel_accept,
1359	.dumpit = NULL,
1360	},
1361	{
1362	.cmd = NLBL_UNLABEL_C_LIST,
1363	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1364	.flags = 0,
1365	.doit = netlbl_unlabel_list,
1366	.dumpit = NULL,
1367	},
1368};
1369
1370static struct genl_family netlbl_unlabel_gnl_family __ro_after_init = {
1371	.hdrsize = 0,
1372	.name = NETLBL_NLTYPE_UNLABELED_NAME,
1373	.version = NETLBL_PROTO_VERSION,
1374	.maxattr = NLBL_UNLABEL_A_MAX,
1375	.policy = netlbl_unlabel_genl_policy,
1376	.module = THIS_MODULE,
1377	.small_ops = netlbl_unlabel_genl_ops,
1378	.n_small_ops = ARRAY_SIZE(netlbl_unlabel_genl_ops),
1379};
1380
1381/*
1382 * NetLabel Generic NETLINK Protocol Functions
1383 */
1384
1385/**
1386 * netlbl_unlabel_genl_init - Register the Unlabeled NetLabel component
1387 *
1388 * Description:
1389 * Register the unlabeled packet NetLabel component with the Generic NETLINK
1390 * mechanism.  Returns zero on success, negative values on failure.
1391 *
1392 */
1393int __init netlbl_unlabel_genl_init(void)
1394{
1395	return genl_register_family(&netlbl_unlabel_gnl_family);
1396}
1397
1398/*
1399 * NetLabel KAPI Hooks
1400 */
1401
1402static struct notifier_block netlbl_unlhsh_netdev_notifier = {
1403	.notifier_call = netlbl_unlhsh_netdev_handler,
1404};
1405
1406/**
1407 * netlbl_unlabel_init - Initialize the unlabeled connection hash table
1408 * @size: the number of bits to use for the hash buckets
1409 *
1410 * Description:
1411 * Initializes the unlabeled connection hash table and registers a network
1412 * device notification handler.  This function should only be called by the
1413 * NetLabel subsystem itself during initialization.  Returns zero on success,
1414 * non-zero values on error.
1415 *
1416 */
1417int __init netlbl_unlabel_init(u32 size)
1418{
1419	u32 iter;
1420	struct netlbl_unlhsh_tbl *hsh_tbl;
1421
1422	if (size == 0)
1423		return -EINVAL;
1424
1425	hsh_tbl = kmalloc(sizeof(*hsh_tbl), GFP_KERNEL);
1426	if (hsh_tbl == NULL)
1427		return -ENOMEM;
1428	hsh_tbl->size = 1 << size;
1429	hsh_tbl->tbl = kcalloc(hsh_tbl->size,
1430			       sizeof(struct list_head),
1431			       GFP_KERNEL);
1432	if (hsh_tbl->tbl == NULL) {
1433		kfree(hsh_tbl);
1434		return -ENOMEM;
1435	}
1436	for (iter = 0; iter < hsh_tbl->size; iter++)
1437		INIT_LIST_HEAD(&hsh_tbl->tbl[iter]);
1438
1439	spin_lock(&netlbl_unlhsh_lock);
1440	rcu_assign_pointer(netlbl_unlhsh, hsh_tbl);
1441	spin_unlock(&netlbl_unlhsh_lock);
1442
1443	register_netdevice_notifier(&netlbl_unlhsh_netdev_notifier);
1444
1445	return 0;
1446}
1447
1448/**
1449 * netlbl_unlabel_getattr - Get the security attributes for an unlabled packet
1450 * @skb: the packet
1451 * @family: protocol family
1452 * @secattr: the security attributes
1453 *
1454 * Description:
1455 * Determine the security attributes, if any, for an unlabled packet and return
1456 * them in @secattr.  Returns zero on success and negative values on failure.
1457 *
1458 */
1459int netlbl_unlabel_getattr(const struct sk_buff *skb,
1460			   u16 family,
1461			   struct netlbl_lsm_secattr *secattr)
1462{
1463	struct netlbl_unlhsh_iface *iface;
1464
1465	rcu_read_lock();
1466	iface = netlbl_unlhsh_search_iface(skb->skb_iif);
1467	if (iface == NULL)
1468		iface = rcu_dereference(netlbl_unlhsh_def);
1469	if (iface == NULL || !iface->valid)
1470		goto unlabel_getattr_nolabel;
1471
1472#if IS_ENABLED(CONFIG_IPV6)
1473	/* When resolving a fallback label, check the sk_buff version as
1474	 * it is possible (e.g. SCTP) to have family = PF_INET6 while
1475	 * receiving ip_hdr(skb)->version = 4.
1476	 */
1477	if (family == PF_INET6 && ip_hdr(skb)->version == 4)
1478		family = PF_INET;
1479#endif /* IPv6 */
1480
1481	switch (family) {
1482	case PF_INET: {
1483		struct iphdr *hdr4;
1484		struct netlbl_af4list *addr4;
1485
1486		hdr4 = ip_hdr(skb);
1487		addr4 = netlbl_af4list_search(hdr4->saddr,
1488					      &iface->addr4_list);
1489		if (addr4 == NULL)
1490			goto unlabel_getattr_nolabel;
1491		secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid;
1492		break;
1493	}
1494#if IS_ENABLED(CONFIG_IPV6)
1495	case PF_INET6: {
1496		struct ipv6hdr *hdr6;
1497		struct netlbl_af6list *addr6;
1498
1499		hdr6 = ipv6_hdr(skb);
1500		addr6 = netlbl_af6list_search(&hdr6->saddr,
1501					      &iface->addr6_list);
1502		if (addr6 == NULL)
1503			goto unlabel_getattr_nolabel;
1504		secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid;
1505		break;
1506	}
1507#endif /* IPv6 */
1508	default:
1509		goto unlabel_getattr_nolabel;
1510	}
1511	rcu_read_unlock();
1512
1513	secattr->flags |= NETLBL_SECATTR_SECID;
1514	secattr->type = NETLBL_NLTYPE_UNLABELED;
1515	return 0;
1516
1517unlabel_getattr_nolabel:
1518	rcu_read_unlock();
1519	if (netlabel_unlabel_acceptflg == 0)
1520		return -ENOMSG;
1521	secattr->type = NETLBL_NLTYPE_UNLABELED;
1522	return 0;
1523}
1524
1525/**
1526 * netlbl_unlabel_defconf - Set the default config to allow unlabeled packets
1527 *
1528 * Description:
1529 * Set the default NetLabel configuration to allow incoming unlabeled packets
1530 * and to send unlabeled network traffic by default.
1531 *
1532 */
1533int __init netlbl_unlabel_defconf(void)
1534{
1535	int ret_val;
1536	struct netlbl_dom_map *entry;
1537	struct netlbl_audit audit_info;
1538
1539	/* Only the kernel is allowed to call this function and the only time
1540	 * it is called is at bootup before the audit subsystem is reporting
1541	 * messages so don't worry to much about these values. */
1542	security_task_getsecid(current, &audit_info.secid);
1543	audit_info.loginuid = GLOBAL_ROOT_UID;
1544	audit_info.sessionid = 0;
1545
1546	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
1547	if (entry == NULL)
1548		return -ENOMEM;
1549	entry->family = AF_UNSPEC;
1550	entry->def.type = NETLBL_NLTYPE_UNLABELED;
1551	ret_val = netlbl_domhsh_add_default(entry, &audit_info);
1552	if (ret_val != 0)
1553		return ret_val;
1554
1555	netlbl_unlabel_acceptflg_set(1, &audit_info);
1556
1557	return 0;
1558}
1559