summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--udevd.c30
-rw-r--r--udevsend.c37
2 files changed, 61 insertions, 6 deletions
diff --git a/udevd.c b/udevd.c
index 104cb2b987..366c227a3b 100644
--- a/udevd.c
+++ b/udevd.c
@@ -222,6 +222,11 @@ static void handle_msg(int sock)
{
struct hotplug_msg *msg;
int retval;
+ struct msghdr smsg;
+ struct cmsghdr *cmsg;
+ struct iovec iov;
+ struct ucred *cred;
+ char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
msg = msg_create();
if (msg == NULL) {
@@ -229,13 +234,30 @@ static void handle_msg(int sock)
return;
}
- retval = recv(sock, msg, sizeof(struct hotplug_msg), 0);
+ iov.iov_base = msg;
+ iov.iov_len = sizeof(struct hotplug_msg);
+
+ memset(&smsg, 0x00, sizeof(struct msghdr));
+ smsg.msg_iov = &iov;
+ smsg.msg_iovlen = 1;
+ smsg.msg_control = cred_msg;
+ smsg.msg_controllen = sizeof(cred_msg);
+
+ retval = recvmsg(sock, &smsg, 0);
if (retval < 0) {
if (errno != EINTR)
dbg("unable to receive message");
return;
}
-
+ cmsg = CMSG_FIRSTHDR(&smsg);
+ cred = (struct ucred *) CMSG_DATA(cmsg);
+
+ if (cred->uid != 0) {
+ dbg("sender uid=%i, message ignored", cred->uid);
+ free(msg);
+ return;
+ }
+
if (strncmp(msg->magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) {
dbg("message magic '%s' doesn't match, ignore it", msg->magic);
free(msg);
@@ -289,6 +311,7 @@ int main(int argc, char *argv[])
struct sockaddr_un saddr;
socklen_t addrlen;
int retval;
+ const int on = 1;
struct sigaction act;
init_logging("udevd");
@@ -324,6 +347,9 @@ int main(int argc, char *argv[])
goto exit;
}
+ /* enable receiving of the sender credentials */
+ setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
+
while (1) {
handle_msg(ssock);
diff --git a/udevsend.c b/udevsend.c
index a24e7d75ed..b26c744422 100644
--- a/udevsend.c
+++ b/udevsend.c
@@ -119,7 +119,7 @@ static int start_daemon(void)
int main(int argc, char* argv[])
{
- struct hotplug_msg message;
+ struct hotplug_msg msg;
char *action;
char *devpath;
char *subsystem;
@@ -133,6 +133,13 @@ int main(int argc, char* argv[])
struct sockaddr_un saddr;
socklen_t addrlen;
int started_daemon = 0;
+ struct iovec iov;
+ struct msghdr smsg;
+ char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
+ struct cmsghdr *cmsg;
+ struct ucred *cred;
+
+
#ifdef DEBUG
init_logging("udevsend");
@@ -174,12 +181,34 @@ int main(int argc, char* argv[])
strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH);
addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1;
- size = build_hotplugmsg(&message, action, devpath, subsystem, seq);
-
+ size = build_hotplugmsg(&msg, action, devpath, subsystem, seq);
+
+ /* prepare message with credentials to authenticate ourself */
+ iov.iov_base = &msg;
+ iov.iov_len = size;
+
+ smsg.msg_name = &saddr;
+ smsg.msg_namelen = addrlen;
+ smsg.msg_iov = &iov;
+ smsg.msg_iovlen = 1;
+ smsg.msg_control = cred_msg;
+ smsg.msg_controllen = CMSG_LEN(sizeof(struct ucred));;
+ smsg.msg_flags = 0;
+
+ cmsg = CMSG_FIRSTHDR(&smsg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_CREDENTIALS;
+ cmsg->cmsg_len = sizeof(cred_msg);
+ cred = (struct ucred *) CMSG_DATA(cmsg);
+ cred->uid = getuid();
+ cred->gid = getgid();
+ cred->pid = getpid();
+ cred->pid = getpid();
+
/* If we can't send, try to start daemon and resend message */
loop = UDEVSEND_CONNECT_RETRY;
while (loop--) {
- retval = sendto(sock, &message, size, 0, (struct sockaddr *)&saddr, addrlen);
+ retval = sendmsg(sock, &smsg, 0);
if (retval != -1) {
retval = 0;
goto close_and_exit;