I have spent HOURS trying to figure out how to do this, but I have had no success.
Calling do_execve() seems to return without error, but as soon as the process is scheduled, a segmentation fault occurs.
My understanding is that I need to be initializing the stack appropriately for this to work properly, unfortunately, I cannot for the life of me find out how to do this.
I think that if I could see the code for the exec() family in the C library, I could work from there, unfortunately, I can't seem to find this anywhere, either.
Anybody have any suggestions? Should I abandon this plan and try something else?
strace
The following is an strace of a program that uses my system call that calls do_execve()
execve("./testprog", ["./testprog"], [/* 75 vars */]) = 0
uname({sys="Linux", node="linux", ...}) = 0
brk(0) = 0x804a000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=64313, ...}) = 0
old_mmap(NULL, 64313, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40017000
close(3) = 0
open("/lib/tls/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240O\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1417095, ...}) = 0
old_mmap(NULL, 1174524, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x40027000
madvise(0x40027000, 1174524, MADV_SEQUENTIAL|0x1) = 0
old_mmap(0x40140000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x119000) = 0x40140000
old_mmap(0x40144000, 7164, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40144000
close(3) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40146000
mprotect(0x40140000, 4096, PROT_READ) = 0
set_thread_area({entry_number:-1 -> 6, base_addr:0x40146aa0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
munmap(0x40017000, 64313) = 0
SYS_295(0x8048604, 0xbfebe044, 0xbfebe04c, 0, 0x804860d) = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
try something else
understand, what "@ 0 (0)" means by comparison with other strace outputs, or try something else. most likely you will want to try something else (execve() call in user space, i.e. put functionality inside a library function, not a system call) anyway.
call_usermodehelper
1. Use the function call_usermodehelper.
2. Else, use the kernel system call "execve". (Directly call execve from the kernel) You *might* have to do setfs(KERNEL_DS); before this call. (Note : #define __KERNEL_SYSCALLS__ at the top of your file.)
EUREKA
>Else, use the kernel system call "execve".
Great! This finally worked for me!
You do indeed have to make the setfs(KERNEL_DS) call for it to work.
Thanks a lot!
Now that I've execed it....
So, I can now exec a process from within the kernel, but I have a few other questions.
When calling execve(), does the process immediately run and take over as the currently running process, as it does when using the system call in user space?
I would like to make a few modifications to the memory of the now exec()ed process, after it is set running. Specifically, I am trying to load in saved data. Is there any way that I can do this immediately after execing?
Furthermore, using the execve call appears to give the process root privilages, which I would like to avoid. Is there any way I can keep the process' privilages as they were when my system call is called?
Thanks again.
Code Sample
sys_execrestore(...)
{
...
fs = get_fs();
set_fs(KERNEL_DS);
retval = execve(fname, argv, envp);
printk("This is never printed\n");
set_fs(fs);
if(retval < 0)
goto out_kfree;
...
}
Where is it scheduled?
I can't seem to find anything within sys_execve() or do_execve() that would cause the process to be immediately scheduled/executed. Is there something I'm missing?
I am trying to execing a
I am trying to execing a process from within the kernel. the problem is that i dont know where the envp come from?