1/*
2 * kernel userspace event delivery
3 *
4 * Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
5 * Copyright (C) 2004 Novell, Inc.  All rights reserved.
6 * Copyright (C) 2004 IBM, Inc. All rights reserved.
7 *
8 * Licensed under the GNU GPL v2.
9 *
10 * Authors:
11 *	Robert Love		<rml@novell.com>
12 *	Kay Sievers		<kay.sievers@vrfy.org>
13 *	Arjan van de Ven	<arjanv@redhat.com>
14 *	Greg Kroah-Hartman	<greg@kroah.com>
15 */
16
17#include <linux/spinlock.h>
18#include <linux/string.h>
19#include <linux/kobject.h>
20#include <linux/export.h>
21#include <linux/kmod.h>
22#include <linux/slab.h>
23#include <linux/socket.h>
24#include <linux/skbuff.h>
25#include <linux/netlink.h>
26#include <net/sock.h>
27#include <net/net_namespace.h>
28
29
30u64 uevent_seqnum;
31#ifdef CONFIG_UEVENT_HELPER
32char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
33#endif
34#ifdef CONFIG_NET
35struct uevent_sock {
36	struct list_head list;
37	struct sock *sk;
38};
39static LIST_HEAD(uevent_sock_list);
40#endif
41
42/* This lock protects uevent_seqnum and uevent_sock_list */
43static DEFINE_MUTEX(uevent_sock_mutex);
44
45/* the strings here must match the enum in include/linux/kobject.h */
46static const char *kobject_actions[] = {
47	[KOBJ_ADD] =		"add",
48	[KOBJ_REMOVE] =		"remove",
49	[KOBJ_CHANGE] =		"change",
50	[KOBJ_MOVE] =		"move",
51	[KOBJ_ONLINE] =		"online",
52	[KOBJ_OFFLINE] =	"offline",
53};
54
55/**
56 * kobject_action_type - translate action string to numeric type
57 *
58 * @buf: buffer containing the action string, newline is ignored
59 * @len: length of buffer
60 * @type: pointer to the location to store the action type
61 *
62 * Returns 0 if the action string was recognized.
63 */
64int kobject_action_type(const char *buf, size_t count,
65			enum kobject_action *type)
66{
67	enum kobject_action action;
68	int ret = -EINVAL;
69
70	if (count && (buf[count-1] == '\n' || buf[count-1] == '\0'))
71		count--;
72
73	if (!count)
74		goto out;
75
76	for (action = 0; action < ARRAY_SIZE(kobject_actions); action++) {
77		if (strncmp(kobject_actions[action], buf, count) != 0)
78			continue;
79		if (kobject_actions[action][count] != '\0')
80			continue;
81		*type = action;
82		ret = 0;
83		break;
84	}
85out:
86	return ret;
87}
88
89#ifdef CONFIG_NET
90static int kobj_bcast_filter(struct sock *dsk, struct sk_buff *skb, void *data)
91{
92	struct kobject *kobj = data, *ksobj;
93	const struct kobj_ns_type_operations *ops;
94
95	ops = kobj_ns_ops(kobj);
96	if (!ops && kobj->kset) {
97		ksobj = &kobj->kset->kobj;
98		if (ksobj->parent != NULL)
99			ops = kobj_ns_ops(ksobj->parent);
100	}
101
102	if (ops && ops->netlink_ns && kobj->ktype->namespace) {
103		const void *sock_ns, *ns;
104		ns = kobj->ktype->namespace(kobj);
105		sock_ns = ops->netlink_ns(dsk);
106		return sock_ns != ns;
107	}
108
109	return 0;
110}
111#endif
112
113#ifdef CONFIG_UEVENT_HELPER
114static int kobj_usermode_filter(struct kobject *kobj)
115{
116	const struct kobj_ns_type_operations *ops;
117
118	ops = kobj_ns_ops(kobj);
119	if (ops) {
120		const void *init_ns, *ns;
121		ns = kobj->ktype->namespace(kobj);
122		init_ns = ops->initial_ns();
123		return ns != init_ns;
124	}
125
126	return 0;
127}
128
129static int init_uevent_argv(struct kobj_uevent_env *env, const char *subsystem)
130{
131	int len;
132
133	len = strlcpy(&env->buf[env->buflen], subsystem,
134		      sizeof(env->buf) - env->buflen);
135	if (len >= (sizeof(env->buf) - env->buflen)) {
136		WARN(1, KERN_ERR "init_uevent_argv: buffer size too small\n");
137		return -ENOMEM;
138	}
139
140	env->argv[0] = uevent_helper;
141	env->argv[1] = &env->buf[env->buflen];
142	env->argv[2] = NULL;
143
144	env->buflen += len + 1;
145	return 0;
146}
147
148static void cleanup_uevent_env(struct subprocess_info *info)
149{
150	kfree(info->data);
151}
152#endif
153
154/**
155 * kobject_uevent_env - send an uevent with environmental data
156 *
157 * @action: action that is happening
158 * @kobj: struct kobject that the action is happening to
159 * @envp_ext: pointer to environmental data
160 *
161 * Returns 0 if kobject_uevent_env() is completed with success or the
162 * corresponding error when it fails.
163 */
164int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
165		       char *envp_ext[])
166{
167	struct kobj_uevent_env *env;
168	const char *action_string = kobject_actions[action];
169	const char *devpath = NULL;
170	const char *subsystem;
171	struct kobject *top_kobj;
172	struct kset *kset;
173	const struct kset_uevent_ops *uevent_ops;
174	int i = 0;
175	int retval = 0;
176#ifdef CONFIG_NET
177	struct uevent_sock *ue_sk;
178#endif
179
180	pr_debug("kobject: '%s' (%p): %s\n",
181		 kobject_name(kobj), kobj, __func__);
182
183	/* search the kset we belong to */
184	top_kobj = kobj;
185	while (!top_kobj->kset && top_kobj->parent)
186		top_kobj = top_kobj->parent;
187
188	if (!top_kobj->kset) {
189		pr_debug("kobject: '%s' (%p): %s: attempted to send uevent "
190			 "without kset!\n", kobject_name(kobj), kobj,
191			 __func__);
192		return -EINVAL;
193	}
194
195	kset = top_kobj->kset;
196	uevent_ops = kset->uevent_ops;
197
198	/* skip the event, if uevent_suppress is set*/
199	if (kobj->uevent_suppress) {
200		pr_debug("kobject: '%s' (%p): %s: uevent_suppress "
201				 "caused the event to drop!\n",
202				 kobject_name(kobj), kobj, __func__);
203		return 0;
204	}
205	/* skip the event, if the filter returns zero. */
206	if (uevent_ops && uevent_ops->filter)
207		if (!uevent_ops->filter(kset, kobj)) {
208			pr_debug("kobject: '%s' (%p): %s: filter function "
209				 "caused the event to drop!\n",
210				 kobject_name(kobj), kobj, __func__);
211			return 0;
212		}
213
214	/* originating subsystem */
215	if (uevent_ops && uevent_ops->name)
216		subsystem = uevent_ops->name(kset, kobj);
217	else
218		subsystem = kobject_name(&kset->kobj);
219	if (!subsystem) {
220		pr_debug("kobject: '%s' (%p): %s: unset subsystem caused the "
221			 "event to drop!\n", kobject_name(kobj), kobj,
222			 __func__);
223		return 0;
224	}
225
226	/* environment buffer */
227	env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
228	if (!env)
229		return -ENOMEM;
230
231	/* complete object path */
232	devpath = kobject_get_path(kobj, GFP_KERNEL);
233	if (!devpath) {
234		retval = -ENOENT;
235		goto exit;
236	}
237
238	/* default keys */
239	retval = add_uevent_var(env, "ACTION=%s", action_string);
240	if (retval)
241		goto exit;
242	retval = add_uevent_var(env, "DEVPATH=%s", devpath);
243	if (retval)
244		goto exit;
245	retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);
246	if (retval)
247		goto exit;
248
249	/* keys passed in from the caller */
250	if (envp_ext) {
251		for (i = 0; envp_ext[i]; i++) {
252			retval = add_uevent_var(env, "%s", envp_ext[i]);
253			if (retval)
254				goto exit;
255		}
256	}
257
258	/* let the kset specific function add its stuff */
259	if (uevent_ops && uevent_ops->uevent) {
260		retval = uevent_ops->uevent(kset, kobj, env);
261		if (retval) {
262			pr_debug("kobject: '%s' (%p): %s: uevent() returned "
263				 "%d\n", kobject_name(kobj), kobj,
264				 __func__, retval);
265			goto exit;
266		}
267	}
268
269	/*
270	 * Mark "add" and "remove" events in the object to ensure proper
271	 * events to userspace during automatic cleanup. If the object did
272	 * send an "add" event, "remove" will automatically generated by
273	 * the core, if not already done by the caller.
274	 */
275	if (action == KOBJ_ADD)
276		kobj->state_add_uevent_sent = 1;
277	else if (action == KOBJ_REMOVE)
278		kobj->state_remove_uevent_sent = 1;
279
280	mutex_lock(&uevent_sock_mutex);
281	/* we will send an event, so request a new sequence number */
282	retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)++uevent_seqnum);
283	if (retval) {
284		mutex_unlock(&uevent_sock_mutex);
285		goto exit;
286	}
287
288#if defined(CONFIG_NET)
289	/* send netlink message */
290	list_for_each_entry(ue_sk, &uevent_sock_list, list) {
291		struct sock *uevent_sock = ue_sk->sk;
292		struct sk_buff *skb;
293		size_t len;
294
295		if (!netlink_has_listeners(uevent_sock, 1))
296			continue;
297
298		/* allocate message with the maximum possible size */
299		len = strlen(action_string) + strlen(devpath) + 2;
300		skb = alloc_skb(len + env->buflen, GFP_KERNEL);
301		if (skb) {
302			char *scratch;
303
304			/* add header */
305			scratch = skb_put(skb, len);
306			sprintf(scratch, "%s@%s", action_string, devpath);
307
308			/* copy keys to our continuous event payload buffer */
309			for (i = 0; i < env->envp_idx; i++) {
310				len = strlen(env->envp[i]) + 1;
311				scratch = skb_put(skb, len);
312				strcpy(scratch, env->envp[i]);
313			}
314
315			NETLINK_CB(skb).dst_group = 1;
316			retval = netlink_broadcast_filtered(uevent_sock, skb,
317							    0, 1, GFP_KERNEL,
318							    kobj_bcast_filter,
319							    kobj);
320			/* ENOBUFS should be handled in userspace */
321			if (retval == -ENOBUFS || retval == -ESRCH)
322				retval = 0;
323		} else
324			retval = -ENOMEM;
325	}
326#endif
327	mutex_unlock(&uevent_sock_mutex);
328
329#ifdef CONFIG_UEVENT_HELPER
330	/* call uevent_helper, usually only enabled during early boot */
331	if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {
332		struct subprocess_info *info;
333
334		retval = add_uevent_var(env, "HOME=/");
335		if (retval)
336			goto exit;
337		retval = add_uevent_var(env,
338					"PATH=/sbin:/bin:/usr/sbin:/usr/bin");
339		if (retval)
340			goto exit;
341		retval = init_uevent_argv(env, subsystem);
342		if (retval)
343			goto exit;
344
345		retval = -ENOMEM;
346		info = call_usermodehelper_setup(env->argv[0], env->argv,
347						 env->envp, GFP_KERNEL,
348						 NULL, cleanup_uevent_env, env);
349		if (info) {
350			retval = call_usermodehelper_exec(info, UMH_NO_WAIT);
351			env = NULL;	/* freed by cleanup_uevent_env */
352		}
353	}
354#endif
355
356exit:
357	kfree(devpath);
358	kfree(env);
359	return retval;
360}
361EXPORT_SYMBOL_GPL(kobject_uevent_env);
362
363/**
364 * kobject_uevent - notify userspace by sending an uevent
365 *
366 * @action: action that is happening
367 * @kobj: struct kobject that the action is happening to
368 *
369 * Returns 0 if kobject_uevent() is completed with success or the
370 * corresponding error when it fails.
371 */
372int kobject_uevent(struct kobject *kobj, enum kobject_action action)
373{
374	return kobject_uevent_env(kobj, action, NULL);
375}
376EXPORT_SYMBOL_GPL(kobject_uevent);
377
378/**
379 * add_uevent_var - add key value string to the environment buffer
380 * @env: environment buffer structure
381 * @format: printf format for the key=value pair
382 *
383 * Returns 0 if environment variable was added successfully or -ENOMEM
384 * if no space was available.
385 */
386int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
387{
388	va_list args;
389	int len;
390
391	if (env->envp_idx >= ARRAY_SIZE(env->envp)) {
392		WARN(1, KERN_ERR "add_uevent_var: too many keys\n");
393		return -ENOMEM;
394	}
395
396	va_start(args, format);
397	len = vsnprintf(&env->buf[env->buflen],
398			sizeof(env->buf) - env->buflen,
399			format, args);
400	va_end(args);
401
402	if (len >= (sizeof(env->buf) - env->buflen)) {
403		WARN(1, KERN_ERR "add_uevent_var: buffer size too small\n");
404		return -ENOMEM;
405	}
406
407	env->envp[env->envp_idx++] = &env->buf[env->buflen];
408	env->buflen += len + 1;
409	return 0;
410}
411EXPORT_SYMBOL_GPL(add_uevent_var);
412
413#if defined(CONFIG_NET)
414static int uevent_net_init(struct net *net)
415{
416	struct uevent_sock *ue_sk;
417	struct netlink_kernel_cfg cfg = {
418		.groups	= 1,
419		.flags	= NL_CFG_F_NONROOT_RECV,
420	};
421
422	ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL);
423	if (!ue_sk)
424		return -ENOMEM;
425
426	ue_sk->sk = netlink_kernel_create(net, NETLINK_KOBJECT_UEVENT, &cfg);
427	if (!ue_sk->sk) {
428		printk(KERN_ERR
429		       "kobject_uevent: unable to create netlink socket!\n");
430		kfree(ue_sk);
431		return -ENODEV;
432	}
433	mutex_lock(&uevent_sock_mutex);
434	list_add_tail(&ue_sk->list, &uevent_sock_list);
435	mutex_unlock(&uevent_sock_mutex);
436	return 0;
437}
438
439static void uevent_net_exit(struct net *net)
440{
441	struct uevent_sock *ue_sk;
442
443	mutex_lock(&uevent_sock_mutex);
444	list_for_each_entry(ue_sk, &uevent_sock_list, list) {
445		if (sock_net(ue_sk->sk) == net)
446			goto found;
447	}
448	mutex_unlock(&uevent_sock_mutex);
449	return;
450
451found:
452	list_del(&ue_sk->list);
453	mutex_unlock(&uevent_sock_mutex);
454
455	netlink_kernel_release(ue_sk->sk);
456	kfree(ue_sk);
457}
458
459static struct pernet_operations uevent_net_ops = {
460	.init	= uevent_net_init,
461	.exit	= uevent_net_exit,
462};
463
464static int __init kobject_uevent_init(void)
465{
466	return register_pernet_subsys(&uevent_net_ops);
467}
468
469
470postcore_initcall(kobject_uevent_init);
471#endif
472