#include <unistd.h>
#include <stdio.h>
+#include <errno.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
}
while (1) {
- static char buff[HOTPLUG_BUFFER_SIZE + OBJECT_SIZE];
int i;
char *pos;
size_t bufpos;
ssize_t buflen;
struct uevent *uev;
char *buffer;
+ struct msghdr smsg;
+ struct iovec iov;
+ char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
+ struct cmsghdr *cmsg;
+ struct ucred *cred;
+ static char buf[HOTPLUG_BUFFER_SIZE + OBJECT_SIZE];
+
+ memset(buf, 0x00, sizeof(buf));
+ iov.iov_base = &buf;
+ iov.iov_len = sizeof(buf);
+ 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);
+
+ if (recvmsg(sock, &smsg, 0) < 0) {
+ if (errno != EINTR)
+ condlog(0, "error receiving message");
+ continue;
+ }
- buflen = recv(sock, &buff, sizeof(buff), 0);
- if (buflen < 0) {
- condlog(0, "error receiving message");
+ cmsg = CMSG_FIRSTHDR(&smsg);
+ if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
+ condlog(3, "no sender credentials received, message ignored");
continue;
}
- if ((size_t)buflen > sizeof(buff)-1)
- buflen = sizeof(buff)-1;
+ cred = (struct ucred *)CMSG_DATA(cmsg);
+ if (cred->uid != 0) {
+ condlog(3, "sender uid=%d, message ignored", cred->uid);
+ continue;
+ }
+
+ /* skip header */
+ bufpos = strlen(buf) + 1;
+ if (bufpos < sizeof("a@/d") || bufpos >= sizeof(buf)) {
+ condlog(3, "invalid message length");
+ continue;
+ }
+
+ /* check message header */
+ if (strstr(buf, "@/") == NULL) {
+ condlog(3, "unrecognized message header");
+ continue;
+ }
uev = alloc_uevent();
continue;
}
+ if ((size_t)buflen > sizeof(buf)-1)
+ buflen = sizeof(buf)-1;
+
/*
* Copy the shared receive buffer contents to buffer private
* to this uevent so we can immediately reuse the shared buffer.
*/
- memcpy(uev->buffer, buff, HOTPLUG_BUFFER_SIZE + OBJECT_SIZE);
+ memcpy(uev->buffer, buf, HOTPLUG_BUFFER_SIZE + OBJECT_SIZE);
buffer = uev->buffer;
buffer[buflen] = '\0';