0

I'm trying to replace "/usr/bin/echo" by "/usr/bin/ls" in sys_execve(), the modified code is the following.

SYSCALL_DEFINE3(execve,
        const char __user *, filename,
        const char __user *const __user *, argv,
        const char __user *const __user *, envp)
{
    const char *kernel_filename;
    kernel_filename = strndup_user(filename, PATH_MAX);
    if (IS_ERR(kernel_filename)) {
        return PTR_ERR(kernel_filename);
    }

    if (strcmp(kernel_filename, "/usr/bin/echo") == 0) {
        printk(KERN_INFO "Modifying from %s to /usr/bin/ls\n", kernel_filename);
        const char * const* k_argv;
        const char * const* k_envp;
        int argc = 0;
        int envc = 0;
        copy_exec_args(argv, envp, &k_argv, &k_envp, &argc, &envc);
        int res  = kernel_execve("/usr/bin/ls", k_argv, k_envp);
        kfree(kernel_filename);
        if (k_argv) {
            for (int i = 0; i < argc; i++)
                kfree(k_argv[i]);
            kfree(k_argv);
        }
        if (k_envp) {
            for (int i = 0; i < envc; i++)
                kfree(k_envp[i]);
            kfree(k_envp);
        }
        return res;
    }
    kfree(kernel_filename);

    return do_execve(getname(filename), argv, envp);
}

Run qemu:

qemu-system-x86_64 \
    -kernel ./linux/arch/x86_64/boot/bzImage \
    -initrd ./ram.img \
    -drive file=vm-disk.qcow2,format=qcow2 \
    -m 2G \
    -append "root=/dev/sda rw console=ttyS0" \
    -nographic

Test /usr/bin/echo command:

(initramfs) /usr/bin/echo hello
[  195.914196] Modifying from /usr/bin/echo to /usr/bin/ls
[  195.915116] kernel_execve: /usr/bin/ls
[  195.915931] /usr/bin/ls
[  195.916546] /usr/bin/ls
hello

But when I build the kernel and test it in qemu, it still run "/usr/bin/echo" instead of "/usr/bin/ls".

Why the replacement did not work, and how can I fix it?

2
  • Do you have a file named hello? Commented Mar 12 at 11:29
  • 2
    Just a shot in the dark: do you use busybox in your initramfs? Busybox symlinks /usr/bin/echo and /usr/bin/ls to /usr/bin/busybox, and detects which application (applet) to run by checking argv[0]. You don't change argv[0], that's why running /usr/bin/echo or /usr/bin/ls has the same effect: it just runs busybox. Commented Mar 12 at 11:35

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.