diff options
Diffstat (limited to 'udev')
-rw-r--r-- | udev/udev-event.c | 4 | ||||
-rw-r--r-- | udev/udev-node.c | 5 | ||||
-rw-r--r-- | udev/udev-rules.c | 14 | ||||
-rw-r--r-- | udev/udev.h | 1 | ||||
-rw-r--r-- | udev/udevd.c | 5 |
5 files changed, 23 insertions, 6 deletions
diff --git a/udev/udev-event.c b/udev/udev-event.c index 823768a3e2..391fce81c3 100644 --- a/udev/udev-event.c +++ b/udev/udev-event.c @@ -1030,6 +1030,10 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, } } + /* set sticky bit, so we do not remove the node on module unload */ + if (event->static_node) + event->mode |= 01000; + err = udev_node_add(dev, event->mode, event->uid, event->gid); } diff --git a/udev/udev-node.c b/udev/udev-node.c index dc7d9c365a..6fbe250b85 100644 --- a/udev/udev-node.c +++ b/udev/udev-node.c @@ -425,6 +425,11 @@ int udev_node_remove(struct udev_device *dev) goto out; } + if (stats.st_mode & 01000) { + info(udev, "device node '%s' has sticky bit set, skip removal\n", devnode); + goto out; + } + dev_check = udev_device_new_from_syspath(udev, udev_device_get_syspath(dev)); if (dev_check != NULL) { /* do not remove device node if the same sys-device is re-created in the meantime */ diff --git a/udev/udev-rules.c b/udev/udev-rules.c index 742d88b3d5..6bf2726e1e 100644 --- a/udev/udev-rules.c +++ b/udev/udev-rules.c @@ -2572,6 +2572,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event rule->rule.filename_line); break; case TK_A_STATIC_NODE: + event->static_node = true; break; case TK_A_ENV: { const char *name = &rules->buf[cur->key.attr_off]; @@ -2793,10 +2794,15 @@ void udev_rules_apply_static_dev_perms(struct udev_rules *rules) goto next; if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode)) goto next; - - if (mode == 0 && gid > 0) - mode = 0660; - if (mode != (stats.st_mode & 0777)) { + if (mode == 0) { + if (gid > 0) + mode = 0660; + else + mode = 0600; + } + /* set sticky bit, so we do not remove the node on module unload */ + mode |= 01000; + if (mode != (stats.st_mode & 01777)) { chmod(filename, mode); info(rules->udev, "chmod '%s' %#o\n", filename, mode); } diff --git a/udev/udev.h b/udev/udev.h index 1f9650fc42..5aaf117a9c 100644 --- a/udev/udev.h +++ b/udev/udev.h @@ -53,6 +53,7 @@ struct udev_event { bool owner_final; bool mode_set; bool mode_final; + bool static_node; bool name_final; bool devlink_final; bool run_final; diff --git a/udev/udevd.c b/udev/udevd.c index 1220deaaa6..f1a31e7afb 100644 --- a/udev/udevd.c +++ b/udev/udevd.c @@ -889,10 +889,11 @@ static void static_dev_create_from_modules(struct udev *udev) if (sscanf(devno, "%c%u:%u", &type, &maj, &min) != 3) continue; + /* set sticky bit, so we do not remove the node on module unload */ if (type == 'c') - mode = 0600 | S_IFCHR; + mode = 01600|S_IFCHR; else if (type == 'b') - mode = 0600 | S_IFBLK; + mode = 01600|S_IFBLK; else continue; |