X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fudev%2Fudev-ctrl.c;h=61d3c5b5575a616a60e3ed82be921038cf1a433e;hb=62a30b2c490512fe22a4e5faacb1d55763ead1e0;hp=6fb5bb4a7a87d03dfb6ac34aae07fb65bb67c22f;hpb=9ec6e95b046de71c0198cb9d17acc5462dc76c74;p=elogind.git diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c index 6fb5bb4a7..61d3c5b55 100644 --- a/src/udev/udev-ctrl.c +++ b/src/udev/udev-ctrl.c @@ -10,16 +10,15 @@ */ #include -#include #include #include #include #include -#include -#include +#include #include #include +#include "socket-util.h" #include "udev.h" /* wire protocol magic must match */ @@ -57,7 +56,7 @@ struct udev_ctrl { int refcount; struct udev *udev; int sock; - struct sockaddr_un saddr; + union sockaddr_union saddr; socklen_t addrlen; bool bound; bool cleanup_socket; @@ -73,6 +72,7 @@ struct udev_ctrl_connection { struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) { struct udev_ctrl *uctrl; const int on = 1; + int r; uctrl = new0(struct udev_ctrl, 1); if (uctrl == NULL) @@ -83,7 +83,7 @@ struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) { if (fd < 0) { uctrl->sock = socket(AF_LOCAL, SOCK_SEQPACKET|SOCK_NONBLOCK|SOCK_CLOEXEC, 0); if (uctrl->sock < 0) { - log_error("error getting socket: %m"); + log_error_errno(errno, "error getting socket: %m"); udev_ctrl_unref(uctrl); return NULL; } @@ -91,11 +91,13 @@ struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) { uctrl->bound = true; uctrl->sock = fd; } - setsockopt(uctrl->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + r = setsockopt(uctrl->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + if (r < 0) + log_warning_errno(errno, "could not set SO_PASSCRED: %m"); - uctrl->saddr.sun_family = AF_LOCAL; - strscpy(uctrl->saddr.sun_path, sizeof(uctrl->saddr.sun_path), "/run/udev/control"); - uctrl->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(uctrl->saddr.sun_path); + uctrl->saddr.un.sun_family = AF_LOCAL; + strscpy(uctrl->saddr.un.sun_path, sizeof(uctrl->saddr.un.sun_path), "/run/udev/control"); + uctrl->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(uctrl->saddr.un.sun_path); return uctrl; } @@ -107,22 +109,22 @@ int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) { int err; if (!uctrl->bound) { - err = bind(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen); + err = bind(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen); if (err < 0 && errno == EADDRINUSE) { - unlink(uctrl->saddr.sun_path); - err = bind(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen); + unlink(uctrl->saddr.un.sun_path); + err = bind(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen); } if (err < 0) { err = -errno; - log_error("bind failed: %m"); + log_error_errno(errno, "bind failed: %m"); return err; } err = listen(uctrl->sock, 0); if (err < 0) { err = -errno; - log_error("listen failed: %m"); + log_error_errno(errno, "listen failed: %m"); return err; } @@ -159,7 +161,7 @@ int udev_ctrl_cleanup(struct udev_ctrl *uctrl) { if (uctrl == NULL) return 0; if (uctrl->cleanup_socket) - unlink(uctrl->saddr.sun_path); + unlink(uctrl->saddr.un.sun_path); return 0; } @@ -184,23 +186,26 @@ struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl) { conn->sock = accept4(uctrl->sock, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK); if (conn->sock < 0) { if (errno != EINTR) - log_error("unable to receive ctrl connection: %m"); + log_error_errno(errno, "unable to receive ctrl connection: %m"); goto err; } /* check peer credential of connection */ r = getpeercred(conn->sock, &ucred); if (r < 0) { - log_error("unable to receive credentials of ctrl connection: %s", strerror(-r)); + log_error_errno(r, "unable to receive credentials of ctrl connection: %m"); goto err; } if (ucred.uid > 0) { - log_error("sender uid=%i, message ignored", ucred.uid); + log_error("sender uid="UID_FMT", message ignored", ucred.uid); goto err; } /* enable receiving of the sender credentials in the messages */ - setsockopt(conn->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + r = setsockopt(conn->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + if (r < 0) + log_warning_errno(errno, "could not set SO_PASSCRED: %m"); + udev_ctrl_ref(uctrl); return conn; err: @@ -245,7 +250,7 @@ static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int ctrl_msg_wire.intval = intval; if (!uctrl->connected) { - if (connect(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen) < 0) { + if (connect(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen) < 0) { err = -errno; goto out; } @@ -355,7 +360,7 @@ struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) { goto err; } else { if (!(pfd[0].revents & POLLIN)) { - log_error("ctrl connection error: %m"); + log_error_errno(errno, "ctrl connection error: %m"); goto err; } } @@ -368,9 +373,12 @@ struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) { size = recvmsg(conn->sock, &smsg, 0); if (size < 0) { - log_error("unable to receive ctrl message: %m"); + log_error_errno(errno, "unable to receive ctrl message: %m"); goto err; } + + cmsg_close_all(&smsg); + cmsg = CMSG_FIRSTHDR(&smsg); cred = (struct ucred *) CMSG_DATA(cmsg); @@ -380,7 +388,7 @@ struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) { } if (cred->uid != 0) { - log_error("sender uid=%i, message ignored", cred->uid); + log_error("sender uid="UID_FMT", message ignored", cred->uid); goto err; }