[pacman-dev] [PATCH] Use O_CLOEXEC as much as possible when opening files
Allan McRae
allan at archlinux.org
Mon Jul 15 20:11:59 EDT 2013
On 16/07/13 04:32, Dan McGee wrote:
> When calling open(), use O_CLOEXEC as much as possible to ensure the
> file descriptor is closed when and if a process using libalpm forks.
>
> For most of these cases, and especially in utility functions, the file
> descriptor is opened and closed in the same function, so we don't have
> too much to worry about. However, for things like the log file and
> database lock file, we should ensure descriptors aren't left hanging
> around for children to touch.
>
> This patch is inspired by the problem in FS#36161, where an open file
> descriptor to the current working directory prevents chroot() from
> working on FreeBSD. We don't need this file descriptor in the child
> process, so open it (and now several others) with O_CLOEXEC.
>
> Signed-off-by: Dan McGee <dan at archlinux.org>
> ---
Compile error:
CC libalpm_la-log.lo
In file included from /usr/include/fcntl.h:296:0,
from util.h:41,
from <command-line>:27:
In function 'open',
inlined from 'alpm_logaction' at <command-line>:52:3:
/usr/include/bits/fcntl2.h:50:24: error: call to '__open_missing_mode'
declared with attribute error: open with O_CREAT in second argument
needs 3 arguments
__open_missing_mode ();
^
> lib/libalpm/add.c | 2 +-
> lib/libalpm/handle.c | 2 +-
> lib/libalpm/log.c | 8 ++++++--
> lib/libalpm/util.c | 14 +++++++-------
> 4 files changed, 15 insertions(+), 11 deletions(-)
>
> diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
> index 8ef9ef0..2d93077 100644
> --- a/lib/libalpm/add.c
> +++ b/lib/libalpm/add.c
> @@ -542,7 +542,7 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
> }
>
> /* save the cwd so we can restore it later */
> - OPEN(cwdfd, ".", O_RDONLY);
> + OPEN(cwdfd, ".", O_RDONLY | O_CLOEXEC);
> if(cwdfd < 0) {
> _alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n"));
> }
> diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
> index 53c86c5..274e3bc 100644
> --- a/lib/libalpm/handle.c
> +++ b/lib/libalpm/handle.c
> @@ -110,7 +110,7 @@ int _alpm_handle_lock(alpm_handle_t *handle)
> FREE(dir);
>
> do {
> - fd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL, 0000);
> + fd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, 0000);
> } while(fd == -1 && errno == EINTR);
> if(fd >= 0) {
> FILE *f = fdopen(fd, "w");
> diff --git a/lib/libalpm/log.c b/lib/libalpm/log.c
> index 271bd00..5f3b094 100644
> --- a/lib/libalpm/log.c
> +++ b/lib/libalpm/log.c
> @@ -49,9 +49,13 @@ int SYMEXPORT alpm_logaction(alpm_handle_t *handle, const char *prefix,
>
> /* check if the logstream is open already, opening it if needed */
> if(handle->logstream == NULL) {
> - handle->logstream = fopen(handle->logfile, "a");
> + int fd;
> + OPEN(fd, handle->logfile, O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC);
> + if(fd >= 0) {
> + handle->logstream = fdopen(fd, "a");
> + }
> /* if we couldn't open it, we have an issue */
> - if(handle->logstream == NULL) {
> + if(fd < 0 || handle->logstream == NULL) {
> if(errno == EACCES) {
> handle->pm_errno = ALPM_ERR_BADPERMS;
> } else if(errno == ENOENT) {
> diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
> index 1e21362..863614e 100644
> --- a/lib/libalpm/util.c
> +++ b/lib/libalpm/util.c
> @@ -154,9 +154,9 @@ int _alpm_copyfile(const char *src, const char *dest)
>
> MALLOC(buf, (size_t)ALPM_BUFFER_SIZE, return 1);
>
> - OPEN(in, src, O_RDONLY);
> + OPEN(in, src, O_RDONLY | O_CLOEXEC);
> do {
> - out = open(dest, O_WRONLY | O_CREAT, 0000);
> + out = open(dest, O_WRONLY | O_CREAT | O_BINARY | O_CLOEXEC, 0000);
> } while(out == -1 && errno == EINTR);
> if(in < 0 || out < 0) {
> goto cleanup;
> @@ -245,7 +245,7 @@ int _alpm_open_archive(alpm_handle_t *handle, const char *path,
> archive_read_support_format_all(*archive);
>
> _alpm_log(handle, ALPM_LOG_DEBUG, "opening archive %s\n", path);
> - OPEN(fd, path, O_RDONLY);
> + OPEN(fd, path, O_RDONLY | O_CLOEXEC);
> if(fd < 0) {
> _alpm_log(handle, ALPM_LOG_ERROR,
> _("could not open file %s: %s\n"), path, strerror(errno));
> @@ -327,7 +327,7 @@ int _alpm_unpack(alpm_handle_t *handle, const char *path, const char *prefix,
> oldmask = umask(0022);
>
> /* save the cwd so we can restore it later */
> - OPEN(cwdfd, ".", O_RDONLY);
> + OPEN(cwdfd, ".", O_RDONLY | O_CLOEXEC);
> if(cwdfd < 0) {
> _alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n"));
> }
> @@ -503,7 +503,7 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[])
> int retval = 0;
>
> /* save the cwd so we can restore it later */
> - OPEN(cwdfd, ".", O_RDONLY);
> + OPEN(cwdfd, ".", O_RDONLY | O_CLOEXEC);
> if(cwdfd < 0) {
> _alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n"));
> }
> @@ -769,7 +769,7 @@ static int md5_file(const char *path, unsigned char output[16])
>
> MALLOC(buf, (size_t)ALPM_BUFFER_SIZE, return 1);
>
> - OPEN(fd, path, O_RDONLY);
> + OPEN(fd, path, O_RDONLY | O_CLOEXEC);
> if(fd < 0) {
> free(buf);
> return 1;
> @@ -811,7 +811,7 @@ static int sha2_file(const char *path, unsigned char output[32], int is224)
>
> MALLOC(buf, (size_t)ALPM_BUFFER_SIZE, return 1);
>
> - OPEN(fd, path, O_RDONLY);
> + OPEN(fd, path, O_RDONLY | O_CLOEXEC);
> if(fd < 0) {
> free(buf);
> return 1;
>
More information about the pacman-dev
mailing list