自定义myext2文件系统加密修改后cat等命令异常求助
Alright, let's get straight to the issue here and how to fix it. The kernel paging fault you're seeing is not a random bug—it's happening because your code is trying to directly access user-space memory from the kernel, which is a strict no-no in Linux kernel development.
What's Causing the Crash?
Looking at your code:
- In
new_sync_read_crypt, you're modifyingchar __user *bufdirectly. The__userannotation tells the kernel this pointer points to user-space memory, which the kernel can't safely read or write directly. User-space pages might be swapped out to disk, or the kernel might lack permission to access them—this triggers theunable to handle kernel paging requesterror you see. - In
new_sync_write_crypt, casting the user-spacebufto a regularchar *and modifying it is equally unsafe, even if it didn't crash immediately.
The kernel enforces strict separation between user and kernel memory for stability and security. Directly accessing user-space pointers from kernel code will almost always trigger an Oops (kernel panic-like error).
The Correct Approach: Use Safe Data Copy Functions
The Linux kernel provides dedicated functions to safely transfer data between user and kernel space:
copy_from_user(): Copies data from user space to a kernel buffercopy_to_user(): Copies data from a kernel buffer to user spacekmalloc()/kfree(): Allocates/frees memory in kernel space (which the kernel can safely access)
Additionally, use kernel_read() and kernel_write() instead of the user-facing new_sync_read/new_sync_write—these functions accept kernel-space pointers, which is exactly what we need after encrypting/decrypting data.
Modified Working Code
Here's the fixed version of your functions:
#include <linux/slab.h> // For kmalloc/kfree #include <linux/uio.h> ssize_t new_sync_write_crypt(struct file *filp, const char __user *buf, size_t len, loff_t *ppos){ char *kernel_buf; ssize_t ret; if (len == 0) return 0; // Allocate kernel-space buffer (GFP_KERNEL allows sleep for memory allocation) kernel_buf = kmalloc(len, GFP_KERNEL); if (!kernel_buf) return -ENOMEM; // Safely copy data from user space to kernel buffer if (copy_from_user(kernel_buf, buf, len)) { kfree(kernel_buf); return -EFAULT; } // Execute encryption logic on kernel buffer int i; for(i = 0; i < len; i++){ kernel_buf[i] += 25; } printk("haha write encrypt %ld\n", len); // Write encrypted data to file using kernel-safe function ret = kernel_write(filp, kernel_buf, len, ppos); // Clean up kernel buffer kfree(kernel_buf); return ret; } ssize_t new_sync_read_crypt(struct file *filp, char __user *buf, size_t len, loff_t *ppos){ char *kernel_buf; ssize_t ret; if (len == 0) return 0; // Allocate kernel-space buffer kernel_buf = kmalloc(len, GFP_KERNEL); if (!kernel_buf) return -ENOMEM; // Read encrypted data from file into kernel buffer ret = kernel_read(filp, kernel_buf, len, ppos); if (ret <= 0) { kfree(kernel_buf); return ret; } // Execute decryption logic on kernel buffer int i; for(i = 0; i < ret; i++){ kernel_buf[i] -= 25; } printk("haha read encrypt %ld\n", ret); // Safely copy decrypted data to user space if (copy_to_user(buf, kernel_buf, ret)) { kfree(kernel_buf); return -EFAULT; } // Clean up kernel buffer kfree(kernel_buf); return ret; }
Key Fixes Explained
- Kernel Buffer Allocation: We use
kmallocto get a buffer in kernel space, which the kernel can safely read and modify without triggering page faults. - Safe Data Copy:
copy_from_userandcopy_to_userhandle all low-level safety checks—they automatically handle missing user pages (e.g., trigger a page fault to load them from disk) and return an error if the user-space memory is invalid. - Kernel-Safe File I/O:
kernel_readandkernel_writework with kernel-space pointers, so we don't have to worry about passing user-space addresses to functions that expect them. - Error Handling: We check for memory allocation failures, copy errors, and read/write errors to ensure the code is robust.
Additional Notes
- Make sure to include
<linux/slab.h>forkmallocandkfree. - Always clean up allocated memory with
kfreebefore returning from the function—leaking kernel memory will cause system instability over time. - The
GFP_KERNELflag is safe here because file operations are allowed to sleep while waiting for memory.
内容的提问来源于stack exchange,提问作者Candy Zhang

