Bug 74481 - It should be documented that using fexecve on a file opened in O_CLOEXEC that is a script cannot possibly work.
Summary: It should be documented that using fexecve on a file opened in O_CLOEXEC that...
Status: RESOLVED CODE_FIX
Alias: None
Product: Documentation
Classification: Unclassified
Component: man-pages (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: documentation_man-pages@kernel-bugs.osdl.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-04-20 02:36 UTC by Steven Stewart-Gallus
Modified: 2014-04-20 08:26 UTC (History)
1 user (show)

See Also:
Kernel Version:
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Steven Stewart-Gallus 2014-04-20 02:36:23 UTC
Consider the following program:

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
    int test = open("./test.sh", O_RDONLY | O_CLOEXEC);
    if (-1 == test) {
        perror("open");
    }

    char * const argv[] = {
        (char *) "./test.sh",
        NULL
    };
    char * const env[] = { NULL };
    fexecve(test, argv, env);
    perror("fexecve");

    return 0;
}

and the following script:

#! /usr/bin/env dash

echo 'hello world!'

When the C program is run, it cannot work because by the time the interpreter has the passed in file name "/proc/self/fd/${FD}" it has already been closed. This is a strange corner case that should be documented.
Comment 1 Michael Kerrisk 2014-04-20 05:55:25 UTC
On 04/20/2014 04:36 AM, bugzilla-daemon@bugzilla.kernel.org wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=74481
> 
>             Bug ID: 74481
>            Summary: It should be documented that using fexecve on a file
>                     opened in O_CLOEXEC that is a script cannot possibly
>                     work.
>            Product: Documentation
>            Version: unspecified
>           Hardware: All
>                 OS: Linux
>             Status: NEW
>           Severity: normal
>           Priority: P1
>          Component: man-pages
>           Assignee: documentation_man-pages@kernel-bugs.osdl.org
>           Reporter: sstewartgallus00@mylangara.bc.ca
>         Regression: No
> 
> Consider the following program:
> 
> #include <errno.h>
> #include <fcntl.h>
> #include <unistd.h>
> 
> int main()
> {
>     int test = open("./test.sh", O_RDONLY | O_CLOEXEC);
>     if (-1 == test) {
>         perror("open");
>     }
> 
>     char * const argv[] = {
>         (char *) "./test.sh",
>         NULL
>     };
>     char * const env[] = { NULL };
>     fexecve(test, argv, env);
>     perror("fexecve");
> 
>     return 0;
> }
> 
> and the following script:
> 
> #! /usr/bin/env dash
> 
> echo 'hello world!'
> 
> When the C program is run, it cannot work because by the time the interpreter
> has the passed in file name "/proc/self/fd/${FD}" it has already been closed.
> This is a strange corner case that should be documented.

Agreed. I added the text below, under NOTES.

Thanks for the report, Steven.

Cheers,

Michael

If
.I fd
is a file descriptor that refers to an interpreter script
and has been marked as close-on-exec (see the discussion of the
.BR FD_CLOEXEC
in
.BR fcntl (2)),
.BR fexecve ()
will fail to execute the script, since,
by the time the script interpreter tries to access the script file,
.I fd
has already been closed.

Note You need to log in before you can comment on or make changes to this bug.