// https://syzkaller.appspot.com/bug?id=136c70e33470358b114e91d488a9e8156ab03793 #define _GNU_SOURCE #include #include #include #include #include #include #include #include #define NUM_THREADS 16 #define MAX_FILES 256 char pci_files[MAX_FILES][256]; int num_pci_files = 0; char acpi_files[MAX_FILES][256]; int num_acpi_files = 0; void *pci_worker(void *arg) { int thread_id = (int)(long)arg; for (int loop = 0; loop < 100; loop++) { for (int i = 0; i < num_pci_files; i++) { int fd = open(pci_files[i], O_WRONLY); if (fd < 0) { printf("[-] Thread %d failed to open %s: %s\n", thread_id, pci_files[i], strerror(errno)); exit(1); } ssize_t res = write(fd, "auto\n", 5); if (res < 0) { printf("[-] Thread %d failed to write 'auto' to %s: %s\n", thread_id, pci_files[i], strerror(errno)); exit(1); } close(fd); fd = open(pci_files[i], O_WRONLY); if (fd < 0) { printf("[-] Thread %d failed to open %s: %s\n", thread_id, pci_files[i], strerror(errno)); exit(1); } res = write(fd, "on\n", 3); if (res < 0) { printf("[-] Thread %d failed to write 'on' to %s: %s\n", thread_id, pci_files[i], strerror(errno)); exit(1); } close(fd); } } printf("[+] Thread %d finished PCI loop successfully.\n", thread_id); return NULL; } void *acpi_worker(void *arg) { int thread_id = (int)(long)arg; char buf[32]; for (int loop = 0; loop < 100; loop++) { for (int i = 0; i < num_acpi_files; i++) { int fd = open(acpi_files[i], O_RDONLY); if (fd < 0) { printf("[-] Thread %d failed to open %s: %s\n", thread_id, acpi_files[i], strerror(errno)); exit(1); } ssize_t res = read(fd, buf, sizeof(buf)); if (res < 0) { printf("[-] Thread %d failed to read %s: %s\n", thread_id, acpi_files[i], strerror(errno)); exit(1); } close(fd); } } printf("[+] Thread %d finished ACPI loop successfully.\n", thread_id); return NULL; } int main(void) { setvbuf(stdout, NULL, _IONBF, 0); DIR *dir = opendir("/sys/bus/pci/devices"); if (!dir) { printf("[-] Failed to opendir /sys/bus/pci/devices: %s\n", strerror(errno)); exit(1); } printf("[+] opendir /sys/bus/pci/devices successful.\n"); struct dirent *ent; while ((ent = readdir(dir)) != NULL) { if (ent->d_name[0] == '.') continue; char path[256]; snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/power/control", ent->d_name); if (access(path, W_OK) == 0) { strncpy(pci_files[num_pci_files++], path, sizeof(pci_files[0]) - 1); if (num_pci_files >= MAX_FILES) { break; } } } closedir(dir); printf("[+] Found %d PCI power control files.\n", num_pci_files); dir = opendir("/sys/bus/acpi/devices"); if (!dir) { printf("[-] Failed to opendir /sys/bus/acpi/devices: %s\n", strerror(errno)); exit(1); } printf("[+] opendir /sys/bus/acpi/devices successful.\n"); while ((ent = readdir(dir)) != NULL) { if (ent->d_name[0] == '.') continue; char path[256]; snprintf(path, sizeof(path), "/sys/bus/acpi/devices/%s/status", ent->d_name); if (access(path, R_OK) == 0) { strncpy(acpi_files[num_acpi_files++], path, sizeof(acpi_files[0]) - 1); if (num_acpi_files >= MAX_FILES) { break; } } } closedir(dir); printf("[+] Found %d ACPI status files.\n", num_acpi_files); if (num_pci_files == 0 && num_acpi_files == 0) { printf("[-] No suitable PCI or ACPI files found.\n"); exit(1); } pthread_t threads[NUM_THREADS]; for (int i = 0; i < NUM_THREADS; i++) { void *(*worker)(void *) = NULL; if (i % 2 == 0 && num_acpi_files > 0) { worker = acpi_worker; } else if (num_pci_files > 0) { worker = pci_worker; } else if (num_acpi_files > 0) { worker = acpi_worker; } if (worker) { int res = pthread_create(&threads[i], NULL, worker, (void *)(long)i); if (res != 0) { printf("[-] Failed to create thread %d: %s\n", i, strerror(res)); exit(1); } } } printf("[+] Created %d threads.\n", NUM_THREADS); for (int i = 0; i < NUM_THREADS; i++) { int res = pthread_join(threads[i], NULL); if (res != 0) { printf("[-] Failed to join thread %d: %s\n", i, strerror(res)); exit(1); } } printf("[+] All threads finished.\n"); sleep(2); printf("[+] Exit successful.\n"); return 0; }