You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义myext2文件系统加密修改后cat等命令异常求助

Fixing Kernel Paging Fault When Adding Encryption to Custom ext2 Filesystem

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 modifying char __user *buf directly. The __user annotation 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 the unable to handle kernel paging request error you see.
  • In new_sync_write_crypt, casting the user-space buf to a regular char * 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 buffer
  • copy_to_user(): Copies data from a kernel buffer to user space
  • kmalloc()/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

  1. Kernel Buffer Allocation: We use kmalloc to get a buffer in kernel space, which the kernel can safely read and modify without triggering page faults.
  2. Safe Data Copy: copy_from_user and copy_to_user handle 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.
  3. Kernel-Safe File I/O: kernel_read and kernel_write work with kernel-space pointers, so we don't have to worry about passing user-space addresses to functions that expect them.
  4. 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> for kmalloc and kfree.
  • Always clean up allocated memory with kfree before returning from the function—leaking kernel memory will cause system instability over time.
  • The GFP_KERNEL flag is safe here because file operations are allowed to sleep while waiting for memory.

内容的提问来源于stack exchange,提问作者Candy Zhang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:57:41