Here is a small improvement. We check for the type of message we receive
and udevsend seems not to need all the credential setup stuff, the
kernel will fill it for us.
udevd now refuses to start as non root, cause it doesn't make any sense.
cmsg = CMSG_FIRSTHDR(&smsg);
cred = (struct ucred *) CMSG_DATA(cmsg);
cmsg = CMSG_FIRSTHDR(&smsg);
cred = (struct ucred *) CMSG_DATA(cmsg);
+ if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
+ dbg("no sender credentials received, message ignored");
+ goto skip;
+ }
+
if (cred->uid != 0) {
dbg("sender uid=%i, message ignored", cred->uid);
if (cred->uid != 0) {
dbg("sender uid=%i, message ignored", cred->uid);
}
if (strncmp(msg->magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) {
dbg("message magic '%s' doesn't match, ignore it", msg->magic);
}
if (strncmp(msg->magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) {
dbg("message magic '%s' doesn't match, ignore it", msg->magic);
}
/* if no seqnum is given, we move straight to exec queue */
}
/* if no seqnum is given, we move straight to exec queue */
} else {
msg_queue_insert(msg);
}
} else {
msg_queue_insert(msg);
}
+ return;
+
+skip:
+ free(msg);
+ return;
}
static void sig_handler(int signum)
}
static void sig_handler(int signum)
+ if (getuid() != 0) {
+ dbg("need to be root, exit");
+ exit(1);
+ }
+
/* set signal handler */
act.sa_handler = sig_handler;
sigemptyset (&act.sa_mask);
/* set signal handler */
act.sa_handler = sig_handler;
sigemptyset (&act.sa_mask);
ssock = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (ssock == -1) {
ssock = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (ssock == -1) {
- dbg("error getting socket");
+ dbg("error getting socket, exit");
exit(1);
}
/* the bind takes care of ensuring only one copy running */
retval = bind(ssock, (struct sockaddr *) &saddr, addrlen);
if (retval < 0) {
exit(1);
}
/* the bind takes care of ensuring only one copy running */
retval = bind(ssock, (struct sockaddr *) &saddr, addrlen);
if (retval < 0) {
+ dbg("bind failed, exit");
struct sockaddr_un saddr;
socklen_t addrlen;
int started_daemon = 0;
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");
#ifdef DEBUG
init_logging("udevsend");
size = build_hotplugmsg(&msg, 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--) {
/* If we can't send, try to start daemon and resend message */
loop = UDEVSEND_CONNECT_RETRY;
while (loop--) {
- retval = sendmsg(sock, &smsg, 0);
+ retval = sendto(sock, &msg, size, 0, (struct sockaddr *)&saddr, addrlen);
if (retval != -1) {
retval = 0;
goto close_and_exit;
if (retval != -1) {
retval = 0;
goto close_and_exit;