Yes, it is possible to execute a file by its inode:
find / -inum 242 -exec {} \; -quit
Performance motivated the question, though, and the above is not performant. Not only is the directory structure walked to find a file having that inode (and there may be multiple), but under the hood, the inode number is resolved to a path, and the path is given to the kernel to execute. But why?
The kernel exposes the exec family of functions (execl
, execvp
, etc), which all wrap the kernel function execve
. That function replaces the current process image with a new process image, one that's been bootstrapped by reading the contents from a given file path. So every way the kernel gives to execute a program requires it be given by path. By using the file path as the entry point, we get all the access control benefits associated with file paths and, for this reason, the "by path" API is the only one in Linux for executing a program.
However, there exists a fiddly and not guaranteed to work in all environments mechanism that allows you to invoke a program from within memory. Since anything in memory is necessarily faster than anything on disk, this drives to the heart of the question: how to run a program as fast as possible.
In early 2002 a (famous) hacker known as grugq introduced the concept of userland exec. This is not a shell's exec
function: it's an emulation of every step the kernel's execve
function performs, just written in userland. This is ideal for hackers who want to hide their activity because it allows the execution of a program outside the usual access control mechanism of execve
.
The implementation for this method requires numerous helpers that can clean the address space, load the dynamic linker if needed, initialize the stack and so on. The mechanism also requires the desired code be loaded in certain kinds of memory.
There are also counter-measures in place to make this kind of thing difficult but, note, not impossible. All that's required is that the target system has page-aligned memory, the ability to mark memory as executable, and the ability to jump to arbitrary points in memory. Those requirements usually translate to: you must write it in C and use it on a system without SELinux or without SELinux being completely enabled. I won't go into the implementation details here, but will provide links that allow you to explore on your own.
So, if your Linux system meets the requirements above, then you can execute code from within memory by:
- Loading the code into memory somewhere. Malicious actors will have already side-loaded the desired code into memory as part of the initial drop, but if you wanted to do it along the lines of inode, you could do
find / -inum 242 -exec cat {} \;
- Invoking the userland exec mechanism, setting its entry point to the address of memory where you stored your program from step 1
- Profit
The kernel, filesystem, and shell have all been tuned to make the lookup and execution of programs a negligible fraction of the total overhead necessary to do work. Loading a program in memory and executing it from there is not really in the domain of the average use case, so unless doing this for fun I'd say you'd want to benchmark the performance before investing time in trying.
References:
ls
in a script, that’s a sign you’re doing something wrong, and you’d probably benefit more by avoiding thels
invocation altogether than by optimising it.ls
andgrep
you're thinking, you might get better results by switching to a programming language with better tooling for data processingls
to do operation on files in scripts, Why not parsels
(and what to do instead)?fork()
+execve()
part of running a new executable is much, much slower.