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.
This commit is contained in:
parent
a31d76b186
commit
fc1de713f5
|
@ -124,14 +124,20 @@ sharepkgconfig_DATA = udev/udev.pc
|
|||
|
||||
if WITH_SYSTEMD
|
||||
systemdsystemunit_DATA = \
|
||||
init/udev.socket \
|
||||
init/udev.service \
|
||||
init/udev-trigger.service \
|
||||
init/udev-settle.service
|
||||
|
||||
EXTRA_DIST += init/udev.socket
|
||||
|
||||
systemd-install-hook:
|
||||
mkdir -p $(DESTDIR)$(systemdsystemunitdir)/socket.target.wants
|
||||
ln -sf ../udev.socket $(DESTDIR)$(systemdsystemunitdir)/socket.target.wants/udev.socket
|
||||
mkdir -p $(DESTDIR)$(systemdsystemunitdir)/basic.target.wants
|
||||
ln -sf ../udev.service $(DESTDIR)$(systemdsystemunitdir)/basic.target.wants/udev.service
|
||||
ln -sf ../udev-trigger.service $(DESTDIR)$(systemdsystemunitdir)/basic.target.wants/udev-trigger.service
|
||||
ln -sf ../udev-settle.service $(DESTDIR)$(systemdsystemunitdir)/basic.target.wants/udev-settle.service
|
||||
ln -sf ../udev-retry.service $(DESTDIR)$(systemdsystemunitdir)/basic.target.wants/udev-retry.service
|
||||
|
||||
INSTALL_DATA_HOOKS += systemd-install-hook
|
||||
endif
|
||||
|
|
|
@ -137,6 +137,7 @@ AC_CONFIG_FILES([
|
|||
Makefile
|
||||
udev/udev.pc
|
||||
init/udev.service
|
||||
init/udev-trigger.service
|
||||
init/udev-settle.service
|
||||
libudev/libudev.pc
|
||||
libudev/docs/Makefile
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
[Unit]
|
||||
Description=udev Coldplug all Devices
|
||||
Requires=udev.service
|
||||
After=udev.service
|
||||
Before=basic.target
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=@sbindir@/udevadm trigger --type=subsystems --action=add ; @sbindir@/udevadm trigger --type=devices --action=add
|
|
@ -1,9 +1,10 @@
|
|||
[Unit]
|
||||
Description=udev Kernel Device Manager
|
||||
DefaultDependencies=no
|
||||
Requires=udev.socket
|
||||
After=udev.socket
|
||||
Before=basic.target
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
ExecStart=@sbindir@/udevd
|
||||
ExecStartPost=@sbindir@/udevadm trigger --type=subsystems --action=add ; @sbindir@/udevadm trigger --type=devices --action=add
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
[Unit]
|
||||
Description=udev Kernel Device Manager Socket
|
||||
|
||||
[Socket]
|
||||
ListenDatagram=@/org/kernel/udev/udevd
|
|
@ -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;
|
||||
const int on = 1;
|
||||
|
||||
err= bind(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen);
|
||||
if (err < 0) {
|
||||
err(uctrl->udev, "bind failed: %m\n");
|
||||
return err;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
14
udev/udevd.c
14
udev/udevd.c
|
@ -1228,16 +1228,20 @@ int main(int argc, char *argv[])
|
|||
if (write(STDERR_FILENO, 0, 0) < 0)
|
||||
dup2(fd, STDERR_FILENO);
|
||||
|
||||
udev_ctrl = udev_ctrl_new_from_socket(udev, UDEV_CTRL_SOCK_PATH);
|
||||
/* udevadm control socket */
|
||||
if (sd_listen_fds(true) == 1 && sd_is_socket(SD_LISTEN_FDS_START, AF_LOCAL, SOCK_DGRAM, -1))
|
||||
udev_ctrl = udev_ctrl_new_from_fd(udev, SD_LISTEN_FDS_START);
|
||||
else
|
||||
udev_ctrl = udev_ctrl_new_from_socket(udev, UDEV_CTRL_SOCK_PATH);
|
||||
if (udev_ctrl == NULL) {
|
||||
fprintf(stderr, "error initializing control socket");
|
||||
err(udev, "error initializing udevd socket");
|
||||
fprintf(stderr, "error initializing udev control socket");
|
||||
err(udev, "error initializing udev control socket");
|
||||
rc = 1;
|
||||
goto exit;
|
||||
}
|
||||
if (udev_ctrl_enable_receiving(udev_ctrl) < 0) {
|
||||
fprintf(stderr, "error binding control socket, seems udevd is already running\n");
|
||||
err(udev, "error binding control socket, seems udevd is already running\n");
|
||||
fprintf(stderr, "error binding udev control socket\n");
|
||||
err(udev, "error binding udev control socket\n");
|
||||
rc = 1;
|
||||
goto exit;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue