829 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * kernel userspace event delivery4 *5 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.6 * Copyright (C) 2004 Novell, Inc. All rights reserved.7 * Copyright (C) 2004 IBM, Inc. All rights reserved.8 *9 * Authors:10 * Robert Love <rml@novell.com>11 * Kay Sievers <kay.sievers@vrfy.org>12 * Arjan van de Ven <arjanv@redhat.com>13 * Greg Kroah-Hartman <greg@kroah.com>14 */15 16#include <linux/spinlock.h>17#include <linux/string.h>18#include <linux/kobject.h>19#include <linux/export.h>20#include <linux/kmod.h>21#include <linux/slab.h>22#include <linux/socket.h>23#include <linux/skbuff.h>24#include <linux/netlink.h>25#include <linux/uidgid.h>26#include <linux/uuid.h>27#include <linux/ctype.h>28#include <net/sock.h>29#include <net/netlink.h>30#include <net/net_namespace.h>31 32 33atomic64_t uevent_seqnum;34#ifdef CONFIG_UEVENT_HELPER35char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;36#endif37 38struct uevent_sock {39 struct list_head list;40 struct sock *sk;41};42 43#ifdef CONFIG_NET44static LIST_HEAD(uevent_sock_list);45/* This lock protects uevent_sock_list */46static DEFINE_MUTEX(uevent_sock_mutex);47#endif48 49/* the strings here must match the enum in include/linux/kobject.h */50static const char *kobject_actions[] = {51 [KOBJ_ADD] = "add",52 [KOBJ_REMOVE] = "remove",53 [KOBJ_CHANGE] = "change",54 [KOBJ_MOVE] = "move",55 [KOBJ_ONLINE] = "online",56 [KOBJ_OFFLINE] = "offline",57 [KOBJ_BIND] = "bind",58 [KOBJ_UNBIND] = "unbind",59};60 61static int kobject_action_type(const char *buf, size_t count,62 enum kobject_action *type,63 const char **args)64{65 enum kobject_action action;66 size_t count_first;67 const char *args_start;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 args_start = strnchr(buf, count, ' ');77 if (args_start) {78 count_first = args_start - buf;79 args_start = args_start + 1;80 } else81 count_first = count;82 83 for (action = 0; action < ARRAY_SIZE(kobject_actions); action++) {84 if (strncmp(kobject_actions[action], buf, count_first) != 0)85 continue;86 if (kobject_actions[action][count_first] != '\0')87 continue;88 if (args)89 *args = args_start;90 *type = action;91 ret = 0;92 break;93 }94out:95 return ret;96}97 98static const char *action_arg_word_end(const char *buf, const char *buf_end,99 char delim)100{101 const char *next = buf;102 103 while (next <= buf_end && *next != delim)104 if (!isalnum(*next++))105 return NULL;106 107 if (next == buf)108 return NULL;109 110 return next;111}112 113static int kobject_action_args(const char *buf, size_t count,114 struct kobj_uevent_env **ret_env)115{116 struct kobj_uevent_env *env = NULL;117 const char *next, *buf_end, *key;118 int key_len;119 int r = -EINVAL;120 121 if (count && (buf[count - 1] == '\n' || buf[count - 1] == '\0'))122 count--;123 124 if (!count)125 return -EINVAL;126 127 env = kzalloc(sizeof(*env), GFP_KERNEL);128 if (!env)129 return -ENOMEM;130 131 /* first arg is UUID */132 if (count < UUID_STRING_LEN || !uuid_is_valid(buf) ||133 add_uevent_var(env, "SYNTH_UUID=%.*s", UUID_STRING_LEN, buf))134 goto out;135 136 /*137 * the rest are custom environment variables in KEY=VALUE138 * format with ' ' delimiter between each KEY=VALUE pair139 */140 next = buf + UUID_STRING_LEN;141 buf_end = buf + count - 1;142 143 while (next <= buf_end) {144 if (*next != ' ')145 goto out;146 147 /* skip the ' ', key must follow */148 key = ++next;149 if (key > buf_end)150 goto out;151 152 buf = next;153 next = action_arg_word_end(buf, buf_end, '=');154 if (!next || next > buf_end || *next != '=')155 goto out;156 key_len = next - buf;157 158 /* skip the '=', value must follow */159 if (++next > buf_end)160 goto out;161 162 buf = next;163 next = action_arg_word_end(buf, buf_end, ' ');164 if (!next)165 goto out;166 167 if (add_uevent_var(env, "SYNTH_ARG_%.*s=%.*s",168 key_len, key, (int) (next - buf), buf))169 goto out;170 }171 172 r = 0;173out:174 if (r)175 kfree(env);176 else177 *ret_env = env;178 return r;179}180 181/**182 * kobject_synth_uevent - send synthetic uevent with arguments183 *184 * @kobj: struct kobject for which synthetic uevent is to be generated185 * @buf: buffer containing action type and action args, newline is ignored186 * @count: length of buffer187 *188 * Returns 0 if kobject_synthetic_uevent() is completed with success or the189 * corresponding error when it fails.190 */191int kobject_synth_uevent(struct kobject *kobj, const char *buf, size_t count)192{193 char *no_uuid_envp[] = { "SYNTH_UUID=0", NULL };194 enum kobject_action action;195 const char *action_args;196 struct kobj_uevent_env *env;197 const char *msg = NULL, *devpath;198 int r;199 200 r = kobject_action_type(buf, count, &action, &action_args);201 if (r) {202 msg = "unknown uevent action string";203 goto out;204 }205 206 if (!action_args) {207 r = kobject_uevent_env(kobj, action, no_uuid_envp);208 goto out;209 }210 211 r = kobject_action_args(action_args,212 count - (action_args - buf), &env);213 if (r == -EINVAL) {214 msg = "incorrect uevent action arguments";215 goto out;216 }217 218 if (r)219 goto out;220 221 r = kobject_uevent_env(kobj, action, env->envp);222 kfree(env);223out:224 if (r) {225 devpath = kobject_get_path(kobj, GFP_KERNEL);226 pr_warn("synth uevent: %s: %s\n",227 devpath ?: "unknown device",228 msg ?: "failed to send uevent");229 kfree(devpath);230 }231 return r;232}233 234#ifdef CONFIG_UEVENT_HELPER235static int kobj_usermode_filter(struct kobject *kobj)236{237 const struct kobj_ns_type_operations *ops;238 239 ops = kobj_ns_ops(kobj);240 if (ops) {241 const void *init_ns, *ns;242 243 ns = kobj->ktype->namespace(kobj);244 init_ns = ops->initial_ns();245 return ns != init_ns;246 }247 248 return 0;249}250 251static int init_uevent_argv(struct kobj_uevent_env *env, const char *subsystem)252{253 int buffer_size = sizeof(env->buf) - env->buflen;254 int len;255 256 len = strscpy(&env->buf[env->buflen], subsystem, buffer_size);257 if (len < 0) {258 pr_warn("%s: insufficient buffer space (%u left) for %s\n",259 __func__, buffer_size, subsystem);260 return -ENOMEM;261 }262 263 env->argv[0] = uevent_helper;264 env->argv[1] = &env->buf[env->buflen];265 env->argv[2] = NULL;266 267 env->buflen += len + 1;268 return 0;269}270 271static void cleanup_uevent_env(struct subprocess_info *info)272{273 kfree(info->data);274}275#endif276 277#ifdef CONFIG_NET278static struct sk_buff *alloc_uevent_skb(struct kobj_uevent_env *env,279 const char *action_string,280 const char *devpath)281{282 struct netlink_skb_parms *parms;283 struct sk_buff *skb = NULL;284 char *scratch;285 size_t len;286 287 /* allocate message with maximum possible size */288 len = strlen(action_string) + strlen(devpath) + 2;289 skb = alloc_skb(len + env->buflen, GFP_KERNEL);290 if (!skb)291 return NULL;292 293 /* add header */294 scratch = skb_put(skb, len);295 sprintf(scratch, "%s@%s", action_string, devpath);296 297 skb_put_data(skb, env->buf, env->buflen);298 299 parms = &NETLINK_CB(skb);300 parms->creds.uid = GLOBAL_ROOT_UID;301 parms->creds.gid = GLOBAL_ROOT_GID;302 parms->dst_group = 1;303 parms->portid = 0;304 305 return skb;306}307 308static int uevent_net_broadcast_untagged(struct kobj_uevent_env *env,309 const char *action_string,310 const char *devpath)311{312 struct sk_buff *skb = NULL;313 struct uevent_sock *ue_sk;314 int retval = 0;315 316 /* send netlink message */317 mutex_lock(&uevent_sock_mutex);318 list_for_each_entry(ue_sk, &uevent_sock_list, list) {319 struct sock *uevent_sock = ue_sk->sk;320 321 if (!netlink_has_listeners(uevent_sock, 1))322 continue;323 324 if (!skb) {325 retval = -ENOMEM;326 skb = alloc_uevent_skb(env, action_string, devpath);327 if (!skb)328 continue;329 }330 331 retval = netlink_broadcast(uevent_sock, skb_get(skb), 0, 1,332 GFP_KERNEL);333 /* ENOBUFS should be handled in userspace */334 if (retval == -ENOBUFS || retval == -ESRCH)335 retval = 0;336 }337 mutex_unlock(&uevent_sock_mutex);338 consume_skb(skb);339 340 return retval;341}342 343static int uevent_net_broadcast_tagged(struct sock *usk,344 struct kobj_uevent_env *env,345 const char *action_string,346 const char *devpath)347{348 struct user_namespace *owning_user_ns = sock_net(usk)->user_ns;349 struct sk_buff *skb = NULL;350 int ret = 0;351 352 skb = alloc_uevent_skb(env, action_string, devpath);353 if (!skb)354 return -ENOMEM;355 356 /* fix credentials */357 if (owning_user_ns != &init_user_ns) {358 struct netlink_skb_parms *parms = &NETLINK_CB(skb);359 kuid_t root_uid;360 kgid_t root_gid;361 362 /* fix uid */363 root_uid = make_kuid(owning_user_ns, 0);364 if (uid_valid(root_uid))365 parms->creds.uid = root_uid;366 367 /* fix gid */368 root_gid = make_kgid(owning_user_ns, 0);369 if (gid_valid(root_gid))370 parms->creds.gid = root_gid;371 }372 373 ret = netlink_broadcast(usk, skb, 0, 1, GFP_KERNEL);374 /* ENOBUFS should be handled in userspace */375 if (ret == -ENOBUFS || ret == -ESRCH)376 ret = 0;377 378 return ret;379}380#endif381 382static int kobject_uevent_net_broadcast(struct kobject *kobj,383 struct kobj_uevent_env *env,384 const char *action_string,385 const char *devpath)386{387 int ret = 0;388 389#ifdef CONFIG_NET390 const struct kobj_ns_type_operations *ops;391 const struct net *net = NULL;392 393 ops = kobj_ns_ops(kobj);394 if (!ops && kobj->kset) {395 struct kobject *ksobj = &kobj->kset->kobj;396 397 if (ksobj->parent != NULL)398 ops = kobj_ns_ops(ksobj->parent);399 }400 401 /* kobjects currently only carry network namespace tags and they402 * are the only tag relevant here since we want to decide which403 * network namespaces to broadcast the uevent into.404 */405 if (ops && ops->netlink_ns && kobj->ktype->namespace)406 if (ops->type == KOBJ_NS_TYPE_NET)407 net = kobj->ktype->namespace(kobj);408 409 if (!net)410 ret = uevent_net_broadcast_untagged(env, action_string,411 devpath);412 else413 ret = uevent_net_broadcast_tagged(net->uevent_sock->sk, env,414 action_string, devpath);415#endif416 417 return ret;418}419 420static void zap_modalias_env(struct kobj_uevent_env *env)421{422 static const char modalias_prefix[] = "MODALIAS=";423 size_t len;424 int i, j;425 426 for (i = 0; i < env->envp_idx;) {427 if (strncmp(env->envp[i], modalias_prefix,428 sizeof(modalias_prefix) - 1)) {429 i++;430 continue;431 }432 433 len = strlen(env->envp[i]) + 1;434 435 if (i != env->envp_idx - 1) {436 /* @env->envp[] contains pointers to @env->buf[]437 * with @env->buflen chars, and we are removing438 * variable MODALIAS here pointed by @env->envp[i]439 * with length @len as shown below:440 *441 * 0 @env->buf[] @env->buflen442 * ---------------------------------------------443 * ^ ^ ^ ^444 * | |-> @len <-| target block |445 * @env->envp[0] @env->envp[i] @env->envp[i + 1]446 *447 * so the "target block" indicated above is moved448 * backward by @len, and its right size is449 * @env->buflen - (@env->envp[i + 1] - @env->envp[0]).450 */451 memmove(env->envp[i], env->envp[i + 1],452 env->buflen - (env->envp[i + 1] - env->envp[0]));453 454 for (j = i; j < env->envp_idx - 1; j++)455 env->envp[j] = env->envp[j + 1] - len;456 }457 458 env->envp_idx--;459 env->buflen -= len;460 }461}462 463/**464 * kobject_uevent_env - send an uevent with environmental data465 *466 * @kobj: struct kobject that the action is happening to467 * @action: action that is happening468 * @envp_ext: pointer to environmental data469 *470 * Returns 0 if kobject_uevent_env() is completed with success or the471 * corresponding error when it fails.472 */473int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,474 char *envp_ext[])475{476 struct kobj_uevent_env *env;477 const char *action_string = kobject_actions[action];478 const char *devpath = NULL;479 const char *subsystem;480 struct kobject *top_kobj;481 struct kset *kset;482 const struct kset_uevent_ops *uevent_ops;483 int i = 0;484 int retval = 0;485 486 /*487 * Mark "remove" event done regardless of result, for some subsystems488 * do not want to re-trigger "remove" event via automatic cleanup.489 */490 if (action == KOBJ_REMOVE)491 kobj->state_remove_uevent_sent = 1;492 493 pr_debug("kobject: '%s' (%p): %s\n",494 kobject_name(kobj), kobj, __func__);495 496 /* search the kset we belong to */497 top_kobj = kobj;498 while (!top_kobj->kset && top_kobj->parent)499 top_kobj = top_kobj->parent;500 501 if (!top_kobj->kset) {502 pr_debug("kobject: '%s' (%p): %s: attempted to send uevent "503 "without kset!\n", kobject_name(kobj), kobj,504 __func__);505 return -EINVAL;506 }507 508 kset = top_kobj->kset;509 uevent_ops = kset->uevent_ops;510 511 /* skip the event, if uevent_suppress is set*/512 if (kobj->uevent_suppress) {513 pr_debug("kobject: '%s' (%p): %s: uevent_suppress "514 "caused the event to drop!\n",515 kobject_name(kobj), kobj, __func__);516 return 0;517 }518 /* skip the event, if the filter returns zero. */519 if (uevent_ops && uevent_ops->filter)520 if (!uevent_ops->filter(kobj)) {521 pr_debug("kobject: '%s' (%p): %s: filter function "522 "caused the event to drop!\n",523 kobject_name(kobj), kobj, __func__);524 return 0;525 }526 527 /* originating subsystem */528 if (uevent_ops && uevent_ops->name)529 subsystem = uevent_ops->name(kobj);530 else531 subsystem = kobject_name(&kset->kobj);532 if (!subsystem) {533 pr_debug("kobject: '%s' (%p): %s: unset subsystem caused the "534 "event to drop!\n", kobject_name(kobj), kobj,535 __func__);536 return 0;537 }538 539 /* environment buffer */540 env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);541 if (!env)542 return -ENOMEM;543 544 /* complete object path */545 devpath = kobject_get_path(kobj, GFP_KERNEL);546 if (!devpath) {547 retval = -ENOENT;548 goto exit;549 }550 551 /* default keys */552 retval = add_uevent_var(env, "ACTION=%s", action_string);553 if (retval)554 goto exit;555 retval = add_uevent_var(env, "DEVPATH=%s", devpath);556 if (retval)557 goto exit;558 retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);559 if (retval)560 goto exit;561 562 /* keys passed in from the caller */563 if (envp_ext) {564 for (i = 0; envp_ext[i]; i++) {565 retval = add_uevent_var(env, "%s", envp_ext[i]);566 if (retval)567 goto exit;568 }569 }570 571 /* let the kset specific function add its stuff */572 if (uevent_ops && uevent_ops->uevent) {573 retval = uevent_ops->uevent(kobj, env);574 if (retval) {575 pr_debug("kobject: '%s' (%p): %s: uevent() returned "576 "%d\n", kobject_name(kobj), kobj,577 __func__, retval);578 goto exit;579 }580 }581 582 switch (action) {583 case KOBJ_ADD:584 /*585 * Mark "add" event so we can make sure we deliver "remove"586 * event to userspace during automatic cleanup. If587 * the object did send an "add" event, "remove" will588 * automatically generated by the core, if not already done589 * by the caller.590 */591 kobj->state_add_uevent_sent = 1;592 break;593 594 case KOBJ_UNBIND:595 zap_modalias_env(env);596 break;597 598 default:599 break;600 }601 602 /* we will send an event, so request a new sequence number */603 retval = add_uevent_var(env, "SEQNUM=%llu",604 atomic64_inc_return(&uevent_seqnum));605 if (retval)606 goto exit;607 608 retval = kobject_uevent_net_broadcast(kobj, env, action_string,609 devpath);610 611#ifdef CONFIG_UEVENT_HELPER612 /* call uevent_helper, usually only enabled during early boot */613 if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {614 struct subprocess_info *info;615 616 retval = add_uevent_var(env, "HOME=/");617 if (retval)618 goto exit;619 retval = add_uevent_var(env,620 "PATH=/sbin:/bin:/usr/sbin:/usr/bin");621 if (retval)622 goto exit;623 retval = init_uevent_argv(env, subsystem);624 if (retval)625 goto exit;626 627 retval = -ENOMEM;628 info = call_usermodehelper_setup(env->argv[0], env->argv,629 env->envp, GFP_KERNEL,630 NULL, cleanup_uevent_env, env);631 if (info) {632 retval = call_usermodehelper_exec(info, UMH_NO_WAIT);633 env = NULL; /* freed by cleanup_uevent_env */634 }635 }636#endif637 638exit:639 kfree(devpath);640 kfree(env);641 return retval;642}643EXPORT_SYMBOL_GPL(kobject_uevent_env);644 645/**646 * kobject_uevent - notify userspace by sending an uevent647 *648 * @kobj: struct kobject that the action is happening to649 * @action: action that is happening650 *651 * Returns 0 if kobject_uevent() is completed with success or the652 * corresponding error when it fails.653 */654int kobject_uevent(struct kobject *kobj, enum kobject_action action)655{656 return kobject_uevent_env(kobj, action, NULL);657}658EXPORT_SYMBOL_GPL(kobject_uevent);659 660/**661 * add_uevent_var - add key value string to the environment buffer662 * @env: environment buffer structure663 * @format: printf format for the key=value pair664 *665 * Returns 0 if environment variable was added successfully or -ENOMEM666 * if no space was available.667 */668int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)669{670 va_list args;671 int len;672 673 if (env->envp_idx >= ARRAY_SIZE(env->envp)) {674 WARN(1, KERN_ERR "add_uevent_var: too many keys\n");675 return -ENOMEM;676 }677 678 va_start(args, format);679 len = vsnprintf(&env->buf[env->buflen],680 sizeof(env->buf) - env->buflen,681 format, args);682 va_end(args);683 684 if (len >= (sizeof(env->buf) - env->buflen)) {685 WARN(1, KERN_ERR "add_uevent_var: buffer size too small\n");686 return -ENOMEM;687 }688 689 env->envp[env->envp_idx++] = &env->buf[env->buflen];690 env->buflen += len + 1;691 return 0;692}693EXPORT_SYMBOL_GPL(add_uevent_var);694 695#if defined(CONFIG_NET)696static int uevent_net_broadcast(struct sock *usk, struct sk_buff *skb,697 struct netlink_ext_ack *extack)698{699 /* u64 to chars: 2^64 - 1 = 21 chars */700 char buf[sizeof("SEQNUM=") + 21];701 struct sk_buff *skbc;702 int ret;703 704 /* bump and prepare sequence number */705 ret = snprintf(buf, sizeof(buf), "SEQNUM=%llu",706 atomic64_inc_return(&uevent_seqnum));707 if (ret < 0 || (size_t)ret >= sizeof(buf))708 return -ENOMEM;709 ret++;710 711 /* verify message does not overflow */712 if ((skb->len + ret) > UEVENT_BUFFER_SIZE) {713 NL_SET_ERR_MSG(extack, "uevent message too big");714 return -EINVAL;715 }716 717 /* copy skb and extend to accommodate sequence number */718 skbc = skb_copy_expand(skb, 0, ret, GFP_KERNEL);719 if (!skbc)720 return -ENOMEM;721 722 /* append sequence number */723 skb_put_data(skbc, buf, ret);724 725 /* remove msg header */726 skb_pull(skbc, NLMSG_HDRLEN);727 728 /* set portid 0 to inform userspace message comes from kernel */729 NETLINK_CB(skbc).portid = 0;730 NETLINK_CB(skbc).dst_group = 1;731 732 ret = netlink_broadcast(usk, skbc, 0, 1, GFP_KERNEL);733 /* ENOBUFS should be handled in userspace */734 if (ret == -ENOBUFS || ret == -ESRCH)735 ret = 0;736 737 return ret;738}739 740static int uevent_net_rcv_skb(struct sk_buff *skb, struct nlmsghdr *nlh,741 struct netlink_ext_ack *extack)742{743 struct net *net;744 int ret;745 746 if (!nlmsg_data(nlh))747 return -EINVAL;748 749 /*750 * Verify that we are allowed to send messages to the target751 * network namespace. The caller must have CAP_SYS_ADMIN in the752 * owning user namespace of the target network namespace.753 */754 net = sock_net(NETLINK_CB(skb).sk);755 if (!netlink_ns_capable(skb, net->user_ns, CAP_SYS_ADMIN)) {756 NL_SET_ERR_MSG(extack, "missing CAP_SYS_ADMIN capability");757 return -EPERM;758 }759 760 ret = uevent_net_broadcast(net->uevent_sock->sk, skb, extack);761 762 return ret;763}764 765static void uevent_net_rcv(struct sk_buff *skb)766{767 netlink_rcv_skb(skb, &uevent_net_rcv_skb);768}769 770static int uevent_net_init(struct net *net)771{772 struct uevent_sock *ue_sk;773 struct netlink_kernel_cfg cfg = {774 .groups = 1,775 .input = uevent_net_rcv,776 .flags = NL_CFG_F_NONROOT_RECV777 };778 779 ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL);780 if (!ue_sk)781 return -ENOMEM;782 783 ue_sk->sk = netlink_kernel_create(net, NETLINK_KOBJECT_UEVENT, &cfg);784 if (!ue_sk->sk) {785 pr_err("kobject_uevent: unable to create netlink socket!\n");786 kfree(ue_sk);787 return -ENODEV;788 }789 790 net->uevent_sock = ue_sk;791 792 /* Restrict uevents to initial user namespace. */793 if (sock_net(ue_sk->sk)->user_ns == &init_user_ns) {794 mutex_lock(&uevent_sock_mutex);795 list_add_tail(&ue_sk->list, &uevent_sock_list);796 mutex_unlock(&uevent_sock_mutex);797 }798 799 return 0;800}801 802static void uevent_net_exit(struct net *net)803{804 struct uevent_sock *ue_sk = net->uevent_sock;805 806 if (sock_net(ue_sk->sk)->user_ns == &init_user_ns) {807 mutex_lock(&uevent_sock_mutex);808 list_del(&ue_sk->list);809 mutex_unlock(&uevent_sock_mutex);810 }811 812 netlink_kernel_release(ue_sk->sk);813 kfree(ue_sk);814}815 816static struct pernet_operations uevent_net_ops = {817 .init = uevent_net_init,818 .exit = uevent_net_exit,819};820 821static int __init kobject_uevent_init(void)822{823 return register_pernet_subsys(&uevent_net_ops);824}825 826 827postcore_initcall(kobject_uevent_init);828#endif829