3 ms·
I experimented recently with writing a user-space ELF loader. Why should ELF loading need to happen in the kernel? Ok, there are some good reasons (the kernel
by haberman 8y ago
I experimented recently with writing a user-space ELF loader. Why should ELF loading need to happen in the kernel? Ok, there are some good reasons (the kernel has an easier time of single-handedly cleaning up all file descriptors, memory mappings, etc. in one fell swoop inside execve(). Are there others?). But I think it's an interesting proof-of-concept to show that ELF loading from user-space is totally possible.
When I started down this path, I learned some interesting details of the kernel/userspace interface that I wasn't aware of before, like the ELF Auxiliary Vector, which is how the kernel communicates some basic information to the process, like its arguments and uid/gid.
https://lwn.net/Articles/519085/ https://lwn.net/Articles/519085/
- gizmo686 8y agoNot nearly an ELF loader, but during my security class, I wanted to test my payloads, so I wrote a load_bin program which read a file into a buffer, then jmp`ed to the start of the buffer.
- deleted 8y ago[deleted]
- xenadu02 8y ago> the kernel has an easier time of single-handedly cleaning up all file descriptors, memory mappings, etc. in one fell swoop inside execve() fork() / execve() isn't a good mechanism for launching new processes; it's one of the worst aspects of early Unix design. A properly designed syscall should require the caller to specify the desired behavior explicitly: 1. Do I want to inherit file descriptors, etc or do I want a clean slate? 2. Do I want a separate address space or to share address space? 3. What happens to threads, mutexes, locks, etc in the new child process? 4. If a separate address space should I inherit my parent's VM mappings or should I just load and execute a new binary image? That gives flexibility to the caller and maximum information to the kernel to optimize. Instead we have a bunch of ad-hoc patches like vfork(), clone(), and posix_spawn() (+ non-standard attributes like POSIX_SPAWN_CLOEXEC_DEFAULT, POSIX_SPAWN_SETEXEC, and POSIX_SPAWN_USEVFORK).