Q Stack
Q Stack

Reputation: 11

How to deal with execve function?

I am writing this function:

int main(int argc, char const *argv[]) {
  char* hack[];
  hack[0] = "/bin/sh";
  hack[1] = NULL;

  execve(hack[0], &hack, &hack[1]);
  return 0;
}

my question is, what is the difference between writing the line:

execve(hack[0], &hack, &hack[1]);

instead of:

execve(hack[0], hack, NULL);

if there is any difference which is the best way? Writing the first type of expression I get a warning saying:

warning: passing argument 2 of ‘execve’ from incompatible pointer type [-Wincompatible-pointer-types]
note: expected ‘char * const*’ but argument is of type ‘char * (*)[3]’

what does this mean?

Upvotes: 1

Views: 633

Answers (1)

Adalcar
Adalcar

Reputation: 1458

EDIT: I will start with an explanation about execve to make it a bit clearer.

execve will run the program pathname, replacing the current process, stack frame and heap. For this it takes three arguments:

  • The path of the program pathname. This is a basic char* with the path to your program.
  • The arguments passed to your program argv. This has the same use as the argv passed to your own main: get command line arguments, with the first such argument being the pathname to the program.
  • The environment variables envp. This lists the environment variables present in your program's execution context (for example $PATH which lists all the paths where your OS can reasonably find executable files).

Both argv and envp are char **, meaning they are lists of char * (null-terminated strings), with the last element being NULL. A program can then expect to iterate them until they find a NULL pointer to gather its arguments and environment.

--

There are two differences between your two statements:

  1. The second argument (argv):

    • In the first case, a pointer to the hack array, meaning you have a char***, not compatible with the declaration which expects a char**
    • In the second case, the hack array itself, which is a char ** (AKA a string array)
  2. The third argument (envp):

    • In the first case, a pointer to the second element of the hack array, which translates to "A string array whose first element is NULL".
    • In the second case, NULL, which on LINUX systems is interpreted like the above, but will cause an error in most other UNIX system.

To quote the execve(2) man page:

On Linux, argv and envp can be specified as NULL. In both cases, this has the same effect as specifying the argument as a pointer to a list containing a single null pointer. Do not take advantage of this nonstandard and nonportable misfeature! On many other UNIX systems, specifying argv as NULL will result in an error (EFAULT). Some other UNIX systems treat the envp==NULL case the same as Linux.

In conclusion, in your case, the proper call is

execve(hack[0], hack, &hack[1]);

Upvotes: 1

Related Questions