summaryrefslogtreecommitdiff
path: root/libudev
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2011-03-23 16:40:23 +0100
committerKay Sievers <kay.sievers@vrfy.org>2011-03-23 16:40:23 +0100
commitfc1de713f5b754fb38876b5b797e18f812727f0a (patch)
treed9b9a7159f9a5a058f1918dbe4bce61c03bb6b28 /libudev
parenta31d76b18675a0bf213fdd16242b4268c9ff48e0 (diff)
systemd: bind udev control socket in systemd and split udev.service
We should bind the udev socket from systemd, so we are sure that the abstract namespace socket is always bound by a root process and there is never a window during an update where an untrusted process can steal our socket. Also split the udev.service file, so that the daemon can be updated/restarted without triggering any coldplug events.
Diffstat (limited to 'libudev')
-rw-r--r--libudev/libudev-ctrl.c39
-rw-r--r--libudev/libudev-private.h1
2 files changed, 32 insertions, 8 deletions
diff --git a/libudev/libudev-ctrl.c b/libudev/libudev-ctrl.c
index af59c36826..63bf539197 100644
--- a/libudev/libudev-ctrl.c
+++ b/libudev/libudev-ctrl.c
@@ -61,7 +61,7 @@ struct udev_ctrl {
socklen_t addrlen;
};
-struct udev_ctrl *udev_ctrl_new_from_socket(struct udev *udev, const char *socket_path)
+static struct udev_ctrl *udev_ctrl_new(struct udev *udev)
{
struct udev_ctrl *uctrl;
@@ -70,6 +70,16 @@ struct udev_ctrl *udev_ctrl_new_from_socket(struct udev *udev, const char *socke
return NULL;
uctrl->refcount = 1;
uctrl->udev = udev;
+ return uctrl;
+}
+
+struct udev_ctrl *udev_ctrl_new_from_socket(struct udev *udev, const char *socket_path)
+{
+ struct udev_ctrl *uctrl;
+
+ uctrl = udev_ctrl_new(udev);
+ if (uctrl == NULL)
+ return NULL;
uctrl->sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (uctrl->sock < 0) {
@@ -84,6 +94,17 @@ struct udev_ctrl *udev_ctrl_new_from_socket(struct udev *udev, const char *socke
/* translate leading '@' to abstract namespace */
if (uctrl->saddr.sun_path[0] == '@')
uctrl->saddr.sun_path[0] = '\0';
+ return uctrl;
+}
+
+struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd)
+{
+ struct udev_ctrl *uctrl;
+
+ uctrl = udev_ctrl_new(udev);
+ if (uctrl == NULL)
+ return NULL;
+ uctrl->sock = fd;
return uctrl;
}
@@ -91,16 +112,18 @@ struct udev_ctrl *udev_ctrl_new_from_socket(struct udev *udev, const char *socke
int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl)
{
int err;
- const int feature_on = 1;
-
- err= bind(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen);
- if (err < 0) {
- err(uctrl->udev, "bind failed: %m\n");
- return err;
+ const int on = 1;
+
+ if (uctrl->addrlen > 0) {
+ err = bind(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen);
+ if (err < 0) {
+ err(uctrl->udev, "bind failed: %m\n");
+ return err;
+ }
}
/* enable receiving of the sender credentials */
- setsockopt(uctrl->sock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on));
+ setsockopt(uctrl->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
return 0;
}
diff --git a/libudev/libudev-private.h b/libudev/libudev-private.h
index bd317933ba..10612560f9 100644
--- a/libudev/libudev-private.h
+++ b/libudev/libudev-private.h
@@ -125,6 +125,7 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor,
/* libudev-ctrl.c - daemon runtime setup */
struct udev_ctrl;
struct udev_ctrl *udev_ctrl_new_from_socket(struct udev *udev, const char *socket_path);
+struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd);
int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl);
struct udev_ctrl *udev_ctrl_ref(struct udev_ctrl *uctrl);
void udev_ctrl_unref(struct udev_ctrl *uctrl);