| From: Linus Lüssing <linus.luessing@c0d3.blue> | 
 | Date: Mon, 1 Nov 2021 21:46:17 +0100 | 
 | Subject: batman-adv: allow netlink usage in unprivileged containers | 
 |  | 
 | Currently, creating a batman-adv interface in an unprivileged LXD | 
 | container and attaching secondary interfaces to it with "ip" or "batctl" | 
 | works fine. However all batctl debug and configuration commands | 
 | fail: | 
 |  | 
 |   root@container:~# batctl originators | 
 |   Error received: Operation not permitted | 
 |   root@container:~# batctl orig_interval | 
 |   1000 | 
 |   root@container:~# batctl orig_interval 2000 | 
 |   root@container:~# batctl orig_interval | 
 |   1000 | 
 |  | 
 | To fix this change the generic netlink permissions from GENL_ADMIN_PERM | 
 | to GENL_UNS_ADMIN_PERM. This way a batman-adv interface is fully | 
 | maintainable as root from within a user namespace, from an unprivileged | 
 | container. | 
 |  | 
 | All except one batman-adv netlink setting are per interface and do not | 
 | leak information or change settings from the host system and are | 
 | therefore save to retrieve or modify as root from within an unprivileged | 
 | container. | 
 |  | 
 | "batctl routing_algo" / BATADV_CMD_GET_ROUTING_ALGOS is the only | 
 | exception: It provides the batman-adv kernel module wide default routing | 
 | algorithm. However it is read-only from netlink and an unprivileged | 
 | container is still not allowed to modify | 
 | /sys/module/batman_adv/parameters/routing_algo. Instead it is advised to | 
 | use the newly introduced "batctl if create routing_algo RA_NAME" / | 
 | IFLA_BATADV_ALGO_NAME to set the routing algorithm on interface | 
 | creation, which already works fine in an unprivileged container. | 
 |  | 
 | Cc: Tycho Andersen <tycho@tycho.pizza> | 
 | Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue> | 
 | Signed-off-by: Sven Eckelmann <sven@narfation.org> | 
 | Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/055fa41b73ca8dae1c1ed41777e32a8f02e80c82 | 
 |  | 
 | --- /dev/null | 
 | +++ b/compat-include/uapi/linux/genetlink.h | 
 | @@ -0,0 +1,22 @@ | 
 | +/* SPDX-License-Identifier: GPL-2.0 */ | 
 | +/* Copyright (C) B.A.T.M.A.N. contributors: | 
 | + * | 
 | + * Marek Lindner, Simon Wunderlich | 
 | + * | 
 | + * This file contains macros for maintaining compatibility with older versions | 
 | + * of the Linux kernel. | 
 | + */ | 
 | + | 
 | +#ifndef _NET_BATMAN_ADV_COMPAT_UAPI_LINUX_GENETLINK_H_ | 
 | +#define _NET_BATMAN_ADV_COMPAT_UAPI_LINUX_GENETLINK_H_ | 
 | + | 
 | +#include <linux/version.h> | 
 | +#include_next <uapi/linux/genetlink.h> | 
 | + | 
 | +#if LINUX_VERSION_IS_LESS(4, 6, 0) | 
 | + | 
 | +#define GENL_UNS_ADMIN_PERM GENL_ADMIN_PERM | 
 | + | 
 | +#endif /* LINUX_VERSION_IS_LESS(4, 6, 0) */ | 
 | + | 
 | +#endif /* _NET_BATMAN_ADV_COMPAT_UAPI_LINUX_GENETLINK_H_ */ | 
 | --- a/net/batman-adv/netlink.c | 
 | +++ b/net/batman-adv/netlink.c | 
 | @@ -1369,21 +1369,21 @@ static const struct genl_ops batadv_netl | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_TP_METER, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.doit = batadv_netlink_tp_meter_start, | 
 |  		.internal_flags = BATADV_FLAG_NEED_MESH, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_TP_METER_CANCEL, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.doit = batadv_netlink_tp_meter_cancel, | 
 |  		.internal_flags = BATADV_FLAG_NEED_MESH, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_GET_ROUTING_ALGOS, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.dumpit = batadv_algo_dump, | 
 |  	}, | 
 |  	{ | 
 | @@ -1398,68 +1398,68 @@ static const struct genl_ops batadv_netl | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.dumpit = batadv_tt_local_dump, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.dumpit = batadv_tt_global_dump, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_GET_ORIGINATORS, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.dumpit = batadv_orig_dump, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_GET_NEIGHBORS, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.dumpit = batadv_hardif_neigh_dump, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_GET_GATEWAYS, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.dumpit = batadv_gw_dump, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_GET_BLA_CLAIM, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.dumpit = batadv_bla_claim_dump, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_GET_BLA_BACKBONE, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.dumpit = batadv_bla_backbone_dump, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_GET_DAT_CACHE, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.dumpit = batadv_dat_cache_dump, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_GET_MCAST_FLAGS, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.dumpit = batadv_mcast_flags_dump, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_SET_MESH, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.doit = batadv_netlink_set_mesh, | 
 |  		.internal_flags = BATADV_FLAG_NEED_MESH, | 
 |  	}, | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_SET_HARDIF, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.doit = batadv_netlink_set_hardif, | 
 |  		.internal_flags = BATADV_FLAG_NEED_MESH | | 
 |  				  BATADV_FLAG_NEED_HARDIF, | 
 | @@ -1475,7 +1475,7 @@ static const struct genl_ops batadv_netl | 
 |  	{ | 
 |  		.cmd = BATADV_CMD_SET_VLAN, | 
 |  		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 
 | -		.flags = GENL_ADMIN_PERM, | 
 | +		.flags = GENL_UNS_ADMIN_PERM, | 
 |  		.doit = batadv_netlink_set_vlan, | 
 |  		.internal_flags = BATADV_FLAG_NEED_MESH | | 
 |  				  BATADV_FLAG_NEED_VLAN, |