Understanding the Linux Kernel says about the implementation of execve()
:
do_execve( )
performs the following operations:
Dynamically allocates a
linux_binprm
data structure, which will be filled with data concerning the new executable file.Invokes
path_lookup(), dentry_open()
, andpath_release()
to get the dentry object, the file object, and the inode object associated with the executable file. On failure, it returns the proper error code.Verifies that the file is executable by the current process; also, checks that the file is not being written by looking at the
i_writecount
field of theinode
; stores –1 in that field to forbid further write accesses.In multiprocessor systems, it invokes the
sched_exec()
function to determine the least loaded CPU that can execute the new program and to migrate the current process to it (see Chapter 7).Invokes
init_new_context()
to check whether the current process was using a custom Local Descriptor Table (see the section “The Linux LDTs” in Chapter 2); in this case, the function allocates and fills a new LDT to be used by the new program.Invokes the
prepare_binprm( )
function to fill thelinux_binprm
data structure. This function, in turn, performs the following operations:a. Checks again whether the file is executable (at least one execute access right is set); if not, returns an error code. (The previous check in step 3 is not sufficient because a process with the
CAP_DAC_OVERRIDE
capability set always satisfies the check; see the section “Process Credentials and Capabilities” earlier in this chapter)....
Do step 3 and step 6a both perform verification check that the execution permission bit of the executable file is set for the process?
What are their differences and relations?
Does step 3 not take into account the CAP_DAC_OVERRIDE
capacity of the process, while step 6a does? Is this the only difference between the two steps?
Why do we need the two-step check, instead of one-step check by lumping all the check into step 3 or step 6a?
Thanks.