From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751351AbbIKBMM (ORCPT ); Thu, 10 Sep 2015 21:12:12 -0400 Received: from out01.mta.xmission.com ([166.70.13.231]:58684 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751196AbbIKBMK (ORCPT ); Thu, 10 Sep 2015 21:12:10 -0400 From: ebiederm@xmission.com (Eric W. Biederman) To: "Michael J. Coss" Cc: gregkh@linuxfoundation.org, davem@davemloft.net, linux-kernel@vger.kernel.org, containers@lists.linuxcontainers.org, serge.hallyn@ubuntu.com, stgraber@ubuntu.com References: Date: Thu, 10 Sep 2015 20:05:00 -0500 In-Reply-To: (Michael J. Coss's message of "Tue, 8 Sep 2015 22:10:30 -0400") Message-ID: <87si6lvk8z.fsf@x220.int.ebiederm.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-XM-AID: U2FsdGVkX1/RJt3c9GWjHfc2p/4jzrQieztjyUcSa3Y= X-SA-Exim-Connect-IP: 67.3.201.231 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Report: * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP * 1.5 XMNoVowels Alpha-numberic number with no vowels * 0.7 XMSubLong Long Subject * 0.0 TVD_RCVD_IP Message was received from an IP address * 0.0 T_TM2_M_HEADER_IN_MSG BODY: No description available. * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa04 1397; Body=1 Fuz1=1 Fuz2=1] X-Spam-DCC: XMission; sa04 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: **;"Michael J. Coss" X-Spam-Relay-Country: X-Spam-Timing: total 1115 ms - load_scoreonly_sql: 0.05 (0.0%), signal_user_changed: 5 (0.5%), b_tie_ro: 3.6 (0.3%), parse: 1.60 (0.1%), extract_message_metadata: 18 (1.7%), get_uri_detail_list: 8 (0.7%), tests_pri_-1000: 3.8 (0.3%), tests_pri_-950: 0.98 (0.1%), tests_pri_-900: 0.76 (0.1%), tests_pri_-400: 39 (3.5%), check_bayes: 38 (3.4%), b_tokenize: 12 (1.1%), b_tok_get_all: 12 (1.1%), b_comp_prob: 4.8 (0.4%), b_tok_touch_all: 6 (0.6%), b_finish: 0.71 (0.1%), tests_pri_0: 514 (46.1%), tests_pri_500: 527 (47.3%), poll_dns_idle: 519 (46.6%), rewrite_mail: 0.00 (0.0%) Subject: Re: [PATCH 3/3] net/udevns: Netlink module to forward uevent to containers X-Spam-Flag: No X-SA-Exim-Version: 4.2.1 (built Wed, 24 Sep 2014 11:00:52 -0600) X-SA-Exim-Scanned: Yes (on in01.mta.xmission.com) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org "Michael J. Coss" writes: > New generic netlink module to provide an interface with the new > forwarding interface for uevent. The driver allows a user to > direct a uevent as read from the kernel to a specific network > namespace by providing the uevent message, and a target process id. > The uapi header file provides the message format. If we can't just pass the message thourgh I don't expect genetlink is a particularly good interface for this. It would be nice if we could open some appropriate thing and the act of getting a file descriptor ould suppress all of the uevent broadcast messages in that network namespace. Further GENL_ADMIN_PERM is an unfortunate choice for a permission check. I don't see it as exploitable but I am not certain CAP_SYS_ADMIN is the best capability to check. Beyond that we probably want to arrange things so that we can use ns_capable so we can allow containers to hand off their devices to child containers. Implementations that do not allow for containers to nest bother me. > Signed-off-by: Michael J. Coss > --- > include/uapi/linux/Kbuild | 1 + > include/uapi/linux/udevns.h | 19 ++++++++ > net/Kconfig | 1 + > net/Makefile | 1 + > net/udevns/Kconfig | 9 ++++ > net/udevns/Makefile | 5 ++ > net/udevns/udevns.c | 112 ++++++++++++++++++++++++++++++++++++++++++++ > net/udevns/udevns.h | 19 ++++++++ > 8 files changed, 167 insertions(+) > create mode 100644 include/uapi/linux/udevns.h > create mode 100644 net/udevns/Kconfig > create mode 100644 net/udevns/Makefile > create mode 100644 net/udevns/udevns.c > create mode 100644 net/udevns/udevns.h > > diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild > index 1ff9942..9fb9c59 100644 > --- a/include/uapi/linux/Kbuild > +++ b/include/uapi/linux/Kbuild > @@ -404,6 +404,7 @@ header-y += toshiba.h > header-y += tty_flags.h > header-y += tty.h > header-y += types.h > +header-y += udevns.h > header-y += udf_fs_i.h > header-y += udp.h > header-y += uhid.h > diff --git a/include/uapi/linux/udevns.h b/include/uapi/linux/udevns.h > new file mode 100644 > index 0000000..f5702f5 > --- /dev/null > +++ b/include/uapi/linux/udevns.h > @@ -0,0 +1,19 @@ > +#ifndef _UDEVNS_H_ > +#define _UDEVNS_H_ > + > +enum udevns_msg_types { > + UDEVNS_FORWARD_MSG = 0x1, > + UDEVNS_CMD_MAX, > +}; > + > +enum udevns_attr { > + UDEVNS_UNSPEC, > + UDEVNS_PID, > + UDEVNS_MSG, > + __UDEVNS_ATTR_MAX, > +}; > + > +#define UDEVNS_ATTR_MAX (__UDEVNS_ATTR_MAX - 1) > +#define UDEVNS_VERSION 0x1 > + > +#endif > diff --git a/net/Kconfig b/net/Kconfig > index 57a7c5a..465e288 100644 > --- a/net/Kconfig > +++ b/net/Kconfig > @@ -54,6 +54,7 @@ source "net/packet/Kconfig" > source "net/unix/Kconfig" > source "net/xfrm/Kconfig" > source "net/iucv/Kconfig" > +source "net/udevns/Kconfig" > > config INET > bool "TCP/IP networking" > diff --git a/net/Makefile b/net/Makefile > index 3995613..bde7775 100644 > --- a/net/Makefile > +++ b/net/Makefile > @@ -74,3 +74,4 @@ obj-$(CONFIG_HSR) += hsr/ > ifneq ($(CONFIG_NET_SWITCHDEV),) > obj-y += switchdev/ > endif > +obj-$(CONFIG_UDEVNS) += udevns/ > diff --git a/net/udevns/Kconfig b/net/udevns/Kconfig > new file mode 100644 > index 0000000..367e650 > --- /dev/null > +++ b/net/udevns/Kconfig > @@ -0,0 +1,9 @@ > +config UDEVNS > + tristate "UDEV namespace bridge" > + depends on SYSFS > + default n > + help > + This option enables support for explicit forwarding of UDEV events to > + other network namespaces > + > + If unsure, say N. > diff --git a/net/udevns/Makefile b/net/udevns/Makefile > new file mode 100644 > index 0000000..44c6b12 > --- /dev/null > +++ b/net/udevns/Makefile > @@ -0,0 +1,5 @@ > +# > +# Makefile for the uevent namespace aware forwarder > +# > +# > +obj-$(CONFIG_UDEVNS) += udevns.o > diff --git a/net/udevns/udevns.c b/net/udevns/udevns.c > new file mode 100644 > index 0000000..8b23751 > --- /dev/null > +++ b/net/udevns/udevns.c > @@ -0,0 +1,112 @@ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "udevns.h" > + > +#define DRIVER_AUTHOR "Michael J Coss " > +#define DRIVER_DESC "new udev namespace bridge" > +#define DEVICE_NAME "udevns" > + > +#ifdef MODULE > +#define UDEVNS_NAME (THIS_MODULE->name) > +#else > +#define UDEVNS_NAME "udevns" > +#endif > + > +#define UDEVNS_INFO(fmt, args...) \ > + pr_info("[%s] " fmt, UDEVNS_NAME, ## args) > + > +#define UDEVNS_ERROR(fmt, args...) \ > + pr_err("[ERROR:%s:%s] " fmt, UDEVNS_NAME, __func__, ## args) > + > +#define UDEVNS_WARNING(fmt, args...) \ > + pr_warn("[WARNING:%s:%s] " fmt, UDEVNS_NAME, __func__, ## args) > + > +static struct genl_family udevns_genl_family = { > + .id = GENL_ID_GENERATE, > + .name = DEVICE_NAME, > + .hdrsize = 0, > + .version = UDEVNS_VERSION, > + .maxattr = UDEVNS_ATTR_MAX, > +}; > + > +static const struct nla_policy udevns_fmsgpolicy[UDEVNS_ATTR_MAX + 1] = { > + [UDEVNS_PID] = { .type = NLA_U32 }, > + [UDEVNS_MSG] = { .type = NLA_STRING, .len = UEVENT_BUFFER_SIZE}, > +}; > + > +static int udevns_forwardmsg(struct sk_buff *skb, struct genl_info *info) > +{ > + pid_t pid; > + char *msg; > + int msglen; > + int err; > + > + if (!info->attrs[UDEVNS_PID]) { > + UDEVNS_WARNING("missing PID from UDEVNS_FORWARD_MSG.\n"); > + return -EINVAL; > + } > + > + if (!info->attrs[UDEVNS_MSG]) { > + UDEVNS_WARNING("missing uevent from UDEVNS_FORWARD_MSG.\n"); > + return -EINVAL; > + } > + > + pid = nla_get_u32(info->attrs[UDEVNS_PID]); > + msg = nla_data(info->attrs[UDEVNS_MSG]); > + msglen = nla_len(info->attrs[UDEVNS_MSG]); > + > + if (msglen < 0) { > + UDEVNS_ERROR("Malformed uevent from UDEVNS_FORWARD_MSG.\n"); > + return -EINVAL; > + } > + > + err = kobject_uevent_forward(msg, msglen, pid); > + return err; > +} > + > +static struct genl_ops udevns_genl_ops[] = { > + { > + .cmd = UDEVNS_FORWARD_MSG, > + .flags = GENL_ADMIN_PERM, > + .doit = udevns_forwardmsg, > + .policy = udevns_fmsgpolicy, > + }, > +}; > + > +static int __init udevns_init(void) > +{ > + int rc; > + > + UDEVNS_INFO("Starting udevns module\n"); > + rc = genl_register_family_with_ops(&udevns_genl_family, > + udevns_genl_ops); > + if (rc) { > + UDEVNS_ERROR("Failed to register netlink interface\n"); > + return rc; > + } > + return 0; > +} > + > +static void __exit udevns_exit(void) > +{ > + UDEVNS_INFO("Exiting udevns module\n"); > + genl_unregister_family(&udevns_genl_family); > +} > + > +module_init(udevns_init); > +module_exit(udevns_exit); > + > +MODULE_LICENSE("GPL"); > +MODULE_DESCRIPTION(DRIVER_DESC); > +MODULE_AUTHOR(DRIVER_AUTHOR); > diff --git a/net/udevns/udevns.h b/net/udevns/udevns.h > new file mode 100644 > index 0000000..f5702f5 > --- /dev/null > +++ b/net/udevns/udevns.h > @@ -0,0 +1,19 @@ > +#ifndef _UDEVNS_H_ > +#define _UDEVNS_H_ > + > +enum udevns_msg_types { > + UDEVNS_FORWARD_MSG = 0x1, > + UDEVNS_CMD_MAX, > +}; > + > +enum udevns_attr { > + UDEVNS_UNSPEC, > + UDEVNS_PID, > + UDEVNS_MSG, > + __UDEVNS_ATTR_MAX, > +}; > + > +#define UDEVNS_ATTR_MAX (__UDEVNS_ATTR_MAX - 1) > +#define UDEVNS_VERSION 0x1 > + > +#endif