int prepare_binprm(struct linux_binprm *bprm) {

bprm->e_uid = current->euid; bprm->e_gid = current->egid;

if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) { /* Set-uid? */ if (mode & S_ISUID) {

* If setgid is set but no group execute bit then this

* is a candidate for mandatory locking, not a setgid

* executable.

if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { bprm->e_gid = inode->i_gid;

After making sure that mnt_nosuid is not set for the mount from which the file originates, the kernel checks if the SUID or SGID bit is set. The first case is simple to handle: If s_isuid is set, then the effective UID gets the same value as the inode (otherwise, the process's effective UID is used). The SGID case is similar, but the kernel must additionally make sure that the execute bit is also set for the group.

Linux supports various organization formats for executable files. The standard format is ELF (Executable and Linkable Format), which I discuss at length in Appendix E. Other alternatives are the variants shown in Table 2-2 (which lists the names of the corresponding linux_binfmt instances in the kernel).

Even though many binary formats can be used on different architectures (ELF was designed explicitly to be as system-independent as possible), this does not mean that programs in a specific binary format are able to run on multiple architectures. The assembler statements used still differ greatly from processor to processor and the binary format only indicates how the different parts of a program — data, code, and so on — are organized in the executable file and in memory.

search_binary_handler is used at the end of do_execve to find a suitable binary format for the particular file. Searching is possible because each format can be recognized by reference to special characteristics (usually a ''magic number'' at the beginning of the file). The binary format handler is responsible for loading the data of the new program into the old address space. Appendix E describes the steps needed to do this when the ELF format is used. Generally, a binary format handler performs the following actions:

□ It releases all resources used by the old process.

□ It maps the application into virtual address space. The following segments must be taken into account (the variables specified are elements of the task structure and are set to the correct values by the binary format handler):

□ The text segment contains the executable code of the program. start_code and end_code specify the area in address space where the segment resides.

□ The pre-initialized data (variables supplied with a specific value at compilation time) are located between start_data and end_data and are mapped from the corresponding segment of the executable file.

□ The heap used for dynamic memory allocation is placed in virtual address space; start_brk and brk specify its boundaries.

□ The position of the stack is defined by start_stack; the stack grows downward automatically on nearly all machines. The only exception is currently PA-Risc. The inverse direction of stack growth must be noted by the architecture by setting the configuration symbol STACK_GROWSUP.

□ The program arguments and the environment are mapped into the virtual address space and are located between arg_start and arg_end and env_start and env_end, respectively.

□ The instruction pointer of the process and some other architecture-specific registers are set so that the main function of the program is executed when the scheduler selects the process.

How the ELF format populates the virtual address space will be discussed in more detail in Section 4.2.1.

Table 2-2: Binary Formats Supported by Linux.




The flat format is used on embedded CPUs without a memory management unit (MMU). To save space, the data in the executable can also be compressed (if zlib support is available in the kernel).


This is a dummy format used to run scripts using the she-bang mechanism. By looking at the first line of the file, the kernel knows which interpreter to use and starts the appropriate application (e.g., Perl for # ! /usr/bin/perl).


This is also a dummy format used to start applications requiring an external interpreter. In contrast to the # ! mechanism, the interpreter need not be specified explicitly but is determined by reference to special file identifiers (suffix, header, etc.). This format is used, for example, to execute Java byte code or to run Windows programs with wine.


This is a machine- and architecture-independent format for 32 and 64 bits. It is the standard format under Linux.


ELF format with special features for systems without an MMU.


ELF format with Irix-specific features.


HP-UX-specific format used on PA-Risc machines.


a.out is the former standard format for Linux used before ELF was introduced. It is rarely used today because it is too inflexible.

Continue reading here: Info

Was this article helpful?

0 0