Loading include/cutils/uevent.h +1 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ extern "C" { int uevent_open_socket(int buf_sz, bool passcred); ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length); ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid); #ifdef __cplusplus } Loading libcutils/uevent.c +25 −6 Original line number Diff line number Diff line Loading @@ -29,7 +29,24 @@ /** * Like recv(), but checks that messages actually originate from the kernel. */ ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length) { ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length) { uid_t user = -1; return uevent_kernel_multicast_uid_recv(socket, buffer, length, &user); } /** * Like the above, but passes a uid_t in by reference. In the event that this * fails due to a bad uid check, the uid_t will be set to the uid of the * socket's peer. * * If this method rejects a netlink message from outside the kernel, it * returns -1, sets errno to EIO, and sets "user" to the UID associated with the * message. If the peer UID cannot be determined, "user" is set to -1." */ ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *user) { struct iovec iov = { buffer, length }; struct sockaddr_nl addr; char control[CMSG_SPACE(sizeof(struct ucred))]; Loading @@ -43,16 +60,12 @@ ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length) { 0, }; *user = -1; ssize_t n = recvmsg(socket, &hdr, 0); if (n <= 0) { return n; } if (addr.nl_groups == 0 || addr.nl_pid != 0) { /* ignoring non-kernel or unicast netlink message */ goto out; } struct cmsghdr *cmsg = CMSG_FIRSTHDR(&hdr); if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { /* ignoring netlink message with no sender credentials */ Loading @@ -60,11 +73,17 @@ ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length) { } struct ucred *cred = (struct ucred *)CMSG_DATA(cmsg); *user = cred->uid; if (cred->uid != 0) { /* ignoring netlink message from non-root user */ goto out; } if (addr.nl_groups == 0 || addr.nl_pid != 0) { /* ignoring non-kernel or unicast netlink message */ goto out; } return n; out: Loading Loading
include/cutils/uevent.h +1 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ extern "C" { int uevent_open_socket(int buf_sz, bool passcred); ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length); ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid); #ifdef __cplusplus } Loading
libcutils/uevent.c +25 −6 Original line number Diff line number Diff line Loading @@ -29,7 +29,24 @@ /** * Like recv(), but checks that messages actually originate from the kernel. */ ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length) { ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length) { uid_t user = -1; return uevent_kernel_multicast_uid_recv(socket, buffer, length, &user); } /** * Like the above, but passes a uid_t in by reference. In the event that this * fails due to a bad uid check, the uid_t will be set to the uid of the * socket's peer. * * If this method rejects a netlink message from outside the kernel, it * returns -1, sets errno to EIO, and sets "user" to the UID associated with the * message. If the peer UID cannot be determined, "user" is set to -1." */ ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *user) { struct iovec iov = { buffer, length }; struct sockaddr_nl addr; char control[CMSG_SPACE(sizeof(struct ucred))]; Loading @@ -43,16 +60,12 @@ ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length) { 0, }; *user = -1; ssize_t n = recvmsg(socket, &hdr, 0); if (n <= 0) { return n; } if (addr.nl_groups == 0 || addr.nl_pid != 0) { /* ignoring non-kernel or unicast netlink message */ goto out; } struct cmsghdr *cmsg = CMSG_FIRSTHDR(&hdr); if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { /* ignoring netlink message with no sender credentials */ Loading @@ -60,11 +73,17 @@ ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length) { } struct ucred *cred = (struct ucred *)CMSG_DATA(cmsg); *user = cred->uid; if (cred->uid != 0) { /* ignoring netlink message from non-root user */ goto out; } if (addr.nl_groups == 0 || addr.nl_pid != 0) { /* ignoring non-kernel or unicast netlink message */ goto out; } return n; out: Loading