...
If the command returned by get_validated_editor() will always be a simple path (such as /usr/bin/vim), and runs on a POSIX system, this program could be strengthened by using a call to execve() rather than system(), in accordance with ENV04ENV33-C. Do not call system() if you do not need a command processor.
On UNIX-based systems, child processes are typically spawned using a form of fork() and exec(), and the child process always inherits from its parent any file descriptors that do not have the close-on-exec flag set. Under Microsoft Windows, file-handle inheritance is determined on a per-file and per-spawned process basis. See WIN03-C. Understand HANDLE inheritance for more information.
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
extern const char *get_validated_editor(void);
void func(const char *file_name) {
int flags;
char *editor;
int fd = open(file_name, O_RDONLY);
if (fd == -1) {
/* Handle error */
}
flags = fcntl(fd, F_GETFD);
if (flags == -1) {
/* Handle error */
}
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
/* Handle error */
}
editor = get_validated_editor();
if (editor == NULL) {
/* Handle getenv() error */
}
if (system(editor) == -1) {
/* Handle error */
}
} |
Compliant Solution (Linux)
Some systems (such as those with Linux kernel versions 2.6.23 and later) have an O_CLOEXEC flag that provides the close-on-exec function directly in open(). This flag is required by IEEE Std 1003.1 [IEEE Std 1003.1:2013]. In multithreaded programs, this flag should be used, if possible, because it prevents a timing hole between open() and fcntl() when using FD_CLOEXEC, during which another thread can create a child process while the file descriptor does not have close-on-exec set.
...