{
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) {
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);
struct sockaddr_un saddr;
socklen_t addrlen;
int retval;
+ const int on = 1;
struct sigaction act;
init_logging("udevd");
goto exit;
}
+ /* enable receiving of the sender credentials */
+ setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
+
while (1) {
handle_msg(ssock);
int main(int argc, char* argv[])
{
- struct hotplug_msg message;
+ struct hotplug_msg msg;
char *action;
char *devpath;
char *subsystem;
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");
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;