Monday, January 5, 2015

Linux exec()

A family of exec calls build upon a single system call - execl().  The call accepts a string containing the path of the executable and 1 or more optional arguments to be passed to the program.  There is at least 1 argument which is the name of the program.  The execl() is varidic which means it accepts a variable number of arguments, to be terminated by a NULL char.

e.g. ret = execl("/bin/vi", "vi", "abc.txt", NULL);

In general, execl does not return as the program image will be replaced by a new one specified in the call.  A successful execl call also have the following effects:

- pending signals are lost (s original program is not there to handle it)
- the signal handler setting is reverted back to default
- memory locks are all freed, mapped file is freed
- thread attribute are returned to default
- process stat is reset
- atexit is reset

Some attributes will be retained across exec
- pid
- process priority
- owning user and group
- opened files which means the new program can access all files of its parent if it know the fd number.  More commonly, files are closed before the exec call.

Other exec calls are built upon execl():
- execlp - only specifies the file name and uses the PATH to resolve the full path name
- execle - also passes over the environment variables
- execv - uses vector (array) for argument passing
- execvp - uses file name and vector for argument passing
- execve - uses file name, vector and environment variables

e.g. const char *args[] = {"vi", "/abc.txt", NULL};
ret = execvp("vi",args);

Use of path has security risk: if the attacker manipulates the PATH variable, it could trick the application to execute a rogue replacement of a program resided in the head of the PATH chain.

No comments: