From: yumkam@gmail.com (Yuriy M. Kaminskiy)
To: util-linux@vger.kernel.org
Subject: [PATCH] Proper fallback for systems that lacks O_CLOEXEC (was: [PATCH 12/14] lib: provide mkostemp fallback function)
Date: Fri, 26 Feb 2016 17:51:28 +0300 [thread overview]
Message-ID: <m3y4a7msnj.fsf_-_@gmail.com> (raw)
In-Reply-To: m337sfocs8.fsf@gmail.com
[-- Attachment #1: Type: text/plain, Size: 555 bytes --]
yumkam@gmail.com (Yuriy M. Kaminskiy)
writes:
> Ruediger Meier <sweet_f_a@gmx.de> writes:
>
>> From: Ruediger Meier <ruediger.meier@ga-group.nl>
>>
[...]
> `O_CREAT`, etc; most notable, `O_CLOEXEC`; however, if `O_CLOEXEC` is missing
> on system, "c.h" defines it as 0, so it is silently ignored on those
> systems, instead of being emulated; so, whenever it matters, callers
> must call **both** `open(O_CLOEXEC)` and `fcntl(F_SETFD,FD_CLOEXEC)`]).
... something like attached below. In some cases it is maybe
unnecessary, but better safe than sorry.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Proper-fallback-for-systems-that-lacks-O_CLOEXEC.patch --]
[-- Type: text/x-diff, Size: 13815 bytes --]
>From 510a63401fbc251600648c803d9867bb27a9ce64 Mon Sep 17 00:00:00 2001
From: "Yuriy M. Kaminskiy" <yumkam@gmail.com>
Date: Fri, 26 Feb 2016 17:34:16 +0300
Subject: [PATCH] Proper fallback for systems that lacks O_CLOEXEC
... and fixes one missing O_CLOEXEC in open() and two missing fcntl(F_SETFD)
after dup().
Signed-off-by: "Yuriy M. Kaminskiy" <yumkam@gmail.com>
---
Note: I intentionally ommited few cases when fd closed right away after open.
disk-utils/fsck.c | 1 +
lib/blkdev.c | 1 +
lib/fileutils.c | 1 +
lib/loopdev.c | 5 ++++-
libblkid/src/evaluate.c | 1 +
libblkid/src/probe.c | 2 ++
libblkid/src/read.c | 1 +
libblkid/src/save.c | 1 +
libblkid/src/topology/md.c | 1 +
libblkid/src/verify.c | 1 +
libfdisk/src/context.c | 1 +
libmount/src/lock.c | 2 ++
libmount/src/monitor.c | 1 +
libmount/src/tab_parse.c | 3 +++
libmount/src/utils.c | 1 +
libsmartcols/samples/tree.c | 1 +
libuuid/src/gen_uuid.c | 1 +
login-utils/sulogin-consoles.c | 5 +++++
misc-utils/blkid.c | 1 +
sys-utils/rtcwake.c | 1 +
sys-utils/wdctl.c | 2 ++
term-utils/agetty.c | 3 +++
22 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/disk-utils/fsck.c b/disk-utils/fsck.c
index b8a47a1..f10b08e 100644
--- a/disk-utils/fsck.c
+++ b/disk-utils/fsck.c
@@ -375,6 +375,7 @@ static void lock_disk(struct fsck_instance *inst)
if (inst->lock >= 0) {
int rc = -1;
+ if (O_CLOEXEC == 0) fcntl(inst->lock, F_SETFD, FD_CLOEXEC);
/* inform users that we're waiting on the lock */
if (verbose &&
(rc = flock(inst->lock, LOCK_EX | LOCK_NB)) != 0 &&
diff --git a/lib/blkdev.c b/lib/blkdev.c
index a57b367..66a472e 100644
--- a/lib/blkdev.c
+++ b/lib/blkdev.c
@@ -378,6 +378,7 @@ main(int argc, char **argv)
if ((fd = open(argv[1], O_RDONLY|O_CLOEXEC)) < 0)
err(EXIT_FAILURE, "open %s failed", argv[1]);
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
if (blkdev_get_size(fd, &bytes) < 0)
err(EXIT_FAILURE, "blkdev_get_size() failed");
diff --git a/lib/fileutils.c b/lib/fileutils.c
index bf8e60a..897e3ce 100644
--- a/lib/fileutils.c
+++ b/lib/fileutils.c
@@ -35,6 +35,7 @@ int xmkstemp(char **tmpname, const char *dir, const char *prefix)
old_mode = umask(077);
fd = mkostemp(localtmp, O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC);
umask(old_mode);
+ if (O_CLOEXEC == 0 && fd != -1) fcntl(fd, F_SETFD, FD_CLOEXEC);
if (fd == -1) {
free(localtmp);
localtmp = NULL;
diff --git a/lib/loopdev.c b/lib/loopdev.c
index 54c6200..dcee458 100644
--- a/lib/loopdev.c
+++ b/lib/loopdev.c
@@ -280,6 +280,8 @@ int loopcxt_get_fd(struct loopdev_cxt *lc)
lc->fd = open(lc->device, lc->mode | O_CLOEXEC);
DBG(CXT, ul_debugobj(lc, "open %s [%s]: %m", lc->device,
lc->flags & LOOPDEV_FL_RDWR ? "rw" : "ro"));
+ if (O_CLOEXEC == 0 && lc->fd != -1)
+ fcntl(lc->fd, F_SETFD, FD_CLOEXEC);
}
return lc->fd;
}
@@ -1230,7 +1232,7 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
if ((file_fd = open(lc->filename, mode | O_CLOEXEC)) < 0) {
if (mode != O_RDONLY && (errno == EROFS || errno == EACCES))
- file_fd = open(lc->filename, mode = O_RDONLY);
+ file_fd = open(lc->filename, (mode = O_RDONLY) | O_CLOEXEC);
if (file_fd < 0) {
DBG(SETUP, ul_debugobj(lc, "open backing file failed: %m"));
@@ -1238,6 +1240,7 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
}
}
DBG(SETUP, ul_debugobj(lc, "backing file open: OK"));
+ if (O_CLOEXEC == 0 && file_fd >= 0) fcntl(file_fd, F_SETFD, FD_CLOEXEC);
if (lc->fd != -1 && lc->mode != mode) {
DBG(SETUP, ul_debugobj(lc, "closing already open device (mode mismatch)"));
diff --git a/libblkid/src/evaluate.c b/libblkid/src/evaluate.c
index ffbe097..e3c2424 100644
--- a/libblkid/src/evaluate.c
+++ b/libblkid/src/evaluate.c
@@ -75,6 +75,7 @@ static int verify_tag(const char *devname, const char *name, const char *value)
errsv = errno;
goto done;
}
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
if (blkid_probe_set_device(pr, fd, 0, 0))
goto done;
rc = blkid_do_safeprobe(pr);
diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c
index 4efa2ba..e4c1102 100644
--- a/libblkid/src/probe.c
+++ b/libblkid/src/probe.c
@@ -221,6 +221,7 @@ blkid_probe blkid_new_probe_from_filename(const char *filename)
fd = open(filename, O_RDONLY|O_CLOEXEC);
if (fd < 0)
return NULL;
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
pr = blkid_new_probe();
if (!pr)
@@ -1156,6 +1157,7 @@ int blkid_do_probe(blkid_probe pr)
* <title>wipe all filesystems or raids from the device</title>
* <programlisting>
* fd = open(devname, O_RDWR|O_CLOEXEC);
+ * if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
* blkid_probe_set_device(pr, fd, 0, 0);
*
* blkid_probe_enable_superblocks(pr, 1);
diff --git a/libblkid/src/read.c b/libblkid/src/read.c
index 41e564f..c5403fd 100644
--- a/libblkid/src/read.c
+++ b/libblkid/src/read.c
@@ -404,6 +404,7 @@ void blkid_read_cache(blkid_cache cache)
*/
if ((fd = open(cache->bic_filename, O_RDONLY|O_CLOEXEC)) < 0)
return;
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
if (fstat(fd, &st) < 0)
goto errout;
if ((st.st_mtime == cache->bic_ftime) ||
diff --git a/libblkid/src/save.c b/libblkid/src/save.c
index 5e8bbee..d7955f3 100644
--- a/libblkid/src/save.c
+++ b/libblkid/src/save.c
@@ -135,6 +135,7 @@ int blkid_flush_cache(blkid_cache cache)
sprintf(tmp, "%s-XXXXXX", filename);
fd = mkostemp(tmp, O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC);
if (fd >= 0) {
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
if (fchmod(fd, 0644) != 0)
DBG(SAVE, ul_debug("%s: fchmod failed", filename));
else if ((file = fdopen(fd, "w" UL_CLOEXECSTR)))
diff --git a/libblkid/src/topology/md.c b/libblkid/src/topology/md.c
index 5eba947..39b104a 100644
--- a/libblkid/src/topology/md.c
+++ b/libblkid/src/topology/md.c
@@ -102,6 +102,7 @@ static int probe_md_tp(blkid_probe pr,
if (fd == -1)
goto nothing;
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
}
memset(&md, 0, sizeof(md));
diff --git a/libblkid/src/verify.c b/libblkid/src/verify.c
index 06f6d53..bdb6551 100644
--- a/libblkid/src/verify.c
+++ b/libblkid/src/verify.c
@@ -133,6 +133,7 @@ blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
dev->bid_name));
goto open_err;
}
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
if (blkid_probe_set_device(cache->probe, fd, 0, 0)) {
/* failed to read the device */
diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c
index 1f6118c..b4c796e 100644
--- a/libfdisk/src/context.c
+++ b/libfdisk/src/context.c
@@ -541,6 +541,7 @@ int fdisk_assign_device(struct fdisk_context *cxt,
fd = open(fname, (readonly ? O_RDONLY : O_RDWR ) | O_CLOEXEC);
if (fd < 0)
return -errno;
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
cxt->readonly = readonly;
cxt->dev_fd = fd;
diff --git a/libmount/src/lock.c b/libmount/src/lock.c
index 0d94329..ca218eb 100644
--- a/libmount/src/lock.c
+++ b/libmount/src/lock.c
@@ -220,6 +220,7 @@ static int lock_simplelock(struct libmnt_lock *ml)
rc = -errno;
goto err;
}
+ if (O_CLOEXEC == 0) fcntl(ml->lockfile_fd, F_SETFD, FD_CLOEXEC);
while (flock(ml->lockfile_fd, LOCK_EX) < 0) {
int errsv;
@@ -449,6 +450,7 @@ static int lock_mtab(struct libmnt_lock *ml)
rc = -errsv;
goto failed;
}
+ if (O_CLOEXEC == 0) fcntl(ml->lockfile_fd, F_SETFD, FD_CLOEXEC);
flock.l_type = F_WRLCK;
flock.l_whence = SEEK_SET;
diff --git a/libmount/src/monitor.c b/libmount/src/monitor.c
index 9bc7ea3..b274c6c 100644
--- a/libmount/src/monitor.c
+++ b/libmount/src/monitor.c
@@ -458,6 +458,7 @@ static int kernel_monitor_get_fd(struct libmnt_monitor *mn,
me->fd = open(me->path, O_RDONLY|O_CLOEXEC);
if (me->fd < 0)
goto err;
+ if (O_CLOEXEC == 0) fcntl(me->fd, F_SETFD, FD_CLOEXEC);
return me->fd;
err:
diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c
index 4c47390..b3219cb 100644
--- a/libmount/src/tab_parse.c
+++ b/libmount/src/tab_parse.c
@@ -741,6 +741,7 @@ static int __mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname)
dd = open(dirname, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
if (dd < 0)
return -errno;
+ if (O_CLOEXEC == 0) fcntl(dd, F_SETFD, FD_CLOEXEC);
n = scandirat(dd, ".", &namelist, mnt_table_parse_dir_filter, versionsort);
if (n <= 0) {
@@ -759,6 +760,7 @@ static int __mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname)
f = fopen_at(dd, ".", d->d_name, O_RDONLY|O_CLOEXEC, "r" UL_CLOEXECSTR);
if (f) {
+ if (O_CLOEXEC == 0) fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
mnt_table_parse_stream(tb, f, d->d_name);
fclose(f);
}
@@ -800,6 +802,7 @@ static int __mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname)
f = fopen_at(dirfd(dir), _PATH_MNTTAB_DIR, d->d_name,
O_RDONLY|O_CLOEXEC, "r" UL_CLOEXECSTR);
if (f) {
+ if (O_CLOEXEC == 0) fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
mnt_table_parse_stream(tb, f, d->d_name);
fclose(f);
}
diff --git a/libmount/src/utils.c b/libmount/src/utils.c
index 39f6c85..98820fd 100644
--- a/libmount/src/utils.c
+++ b/libmount/src/utils.c
@@ -943,6 +943,7 @@ int mnt_open_uniq_filename(const char *filename, char **name)
fd = -errno;
umask(oldmode);
+ if (O_CLOEXEC == 0 && fd >= 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
if (fd >= 0 && name)
*name = n;
else
diff --git a/libsmartcols/samples/tree.c b/libsmartcols/samples/tree.c
index 7f41f9e..1e262c6 100644
--- a/libsmartcols/samples/tree.c
+++ b/libsmartcols/samples/tree.c
@@ -94,6 +94,7 @@ static int add_line_from_stat(struct libscols_table *tb,
else
fd = open(name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC);
if (fd >= 0) {
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
rc = add_children(tb, ln, fd);
close(fd);
}
diff --git a/libuuid/src/gen_uuid.c b/libuuid/src/gen_uuid.c
index 4d60997..c8c1e18 100644
--- a/libuuid/src/gen_uuid.c
+++ b/libuuid/src/gen_uuid.c
@@ -236,6 +236,7 @@ static int get_clock(uint32_t *clock_high, uint32_t *clock_low,
state_fd = open(LIBUUID_CLOCK_FILE, O_RDWR|O_CREAT|O_CLOEXEC, 0660);
(void) umask(save_umask);
if (state_fd != -1) {
+ if (O_CLOEXEC == 0) fcntl(state_fd, F_SETFD, FD_CLOEXEC);
state_f = fdopen(state_fd, "r+" UL_CLOEXECSTR);
if (!state_f) {
close(state_fd);
diff --git a/login-utils/sulogin-consoles.c b/login-utils/sulogin-consoles.c
index 1b05b38..36c2f58 100644
--- a/login-utils/sulogin-consoles.c
+++ b/login-utils/sulogin-consoles.c
@@ -476,6 +476,7 @@ static int detect_consoles_from_cmdline(struct list_head *consoles)
continue;
}
free(name);
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
#ifdef TIOCGDEV
if (ioctl (fd, TIOCGDEV, &devnum) < 0) {
close(fd);
@@ -537,6 +538,8 @@ static int detect_consoles_from_tiocgdev(struct list_head *consoles,
if (fd < 0)
goto done;
+ /* XXX dup() clears close-on-exec */
+ /*if (O_CLOEXEC == 0) */fcntl(fd, F_SETFD, FD_CLOEXEC);
if (ioctl (fd, TIOCGDEV, &devnum) < 0)
goto done;
@@ -620,6 +623,8 @@ int detect_consoles(const char *device, int fallback, struct list_head *consoles
close(fd);
goto fallback;
#endif
+ /* XXX dup() clears close-on-exec */
+ /*if (O_CLOEXEC == 0) */fcntl(fd, F_SETFD, FD_CLOEXEC);
DBG(dbgprint("trying device/fallback file descriptor"));
if (fstat(fd, &st) < 0) {
diff --git a/misc-utils/blkid.c b/misc-utils/blkid.c
index 4ecbb5d..a4f05df 100644
--- a/misc-utils/blkid.c
+++ b/misc-utils/blkid.c
@@ -489,6 +489,7 @@ static int lowprobe_device(blkid_probe pr, const char *devname,
fprintf(stderr, "error: %s: %m\n", devname);
return BLKID_EXIT_NOTFOUND;
}
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
if (blkid_probe_set_device(pr, fd, offset, size))
goto done;
diff --git a/sys-utils/rtcwake.c b/sys-utils/rtcwake.c
index 842ea50..a89220c 100644
--- a/sys-utils/rtcwake.c
+++ b/sys-utils/rtcwake.c
@@ -374,6 +374,7 @@ static int open_dev_rtc(const char *devname)
fd = open(devpath, O_RDONLY | O_CLOEXEC);
if (fd < 0)
err(EXIT_FAILURE, _("%s: unable to find device"), devpath);
+ if (O_CLOEXEC == 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
free(devpath);
return fd;
}
diff --git a/sys-utils/wdctl.c b/sys-utils/wdctl.c
index 095d8ed..e09f031 100644
--- a/sys-utils/wdctl.c
+++ b/sys-utils/wdctl.c
@@ -313,6 +313,7 @@ static int set_watchdog(struct wdinfo *wd, int timeout)
sigprocmask(SIG_BLOCK, &sigs, &oldsigs);
fd = open(wd->device, O_WRONLY|O_CLOEXEC);
+ /* Static_assert(O_CLOEXEC != 0); */
if (fd < 0) {
if (errno == EBUSY)
@@ -369,6 +370,7 @@ static int read_watchdog(struct wdinfo *wd)
sigprocmask(SIG_BLOCK, &sigs, &oldsigs);
fd = open(wd->device, O_WRONLY|O_CLOEXEC);
+ /* Static_assert(O_CLOEXEC != 0); */
if (fd < 0) {
if (errno == EBUSY)
diff --git a/term-utils/agetty.c b/term-utils/agetty.c
index cd57c67..812875a 100644
--- a/term-utils/agetty.c
+++ b/term-utils/agetty.c
@@ -1623,6 +1623,8 @@ static int wait_for_term_input(int fd)
O_CREAT|O_CLOEXEC|O_RDONLY,
S_IRUSR|S_IWUSR);
+ /* Static_assert(O_CLOEXEC != 0); */
+
/* initialize reload trigger inotify stuff */
if (reload_fd >= 0) {
inotify_fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
@@ -2623,6 +2625,7 @@ static void reload_agettys(void)
#ifdef AGETTY_RELOAD
int fd = open(AGETTY_RELOAD_FILENAME, O_CREAT|O_CLOEXEC|O_WRONLY,
S_IRUSR|S_IWUSR);
+ /* Static_assert(O_CLOEXEC != 0); */
if (fd < 0)
err(EXIT_FAILURE, _("cannot open %s"), AGETTY_RELOAD_FILENAME);
--
2.1.4
next prev parent reply other threads:[~2016-02-26 14:51 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-26 3:03 [PATCH 00/14] some fixes, cleanup and portability issues Ruediger Meier
2016-02-26 3:03 ` [PATCH 01/14] logger: use SCM_CREDENTIALS on LINUX only Ruediger Meier
2016-02-26 3:03 ` [PATCH 02/14] build-sys: add openat build conditional Ruediger Meier
2016-02-26 3:03 ` [PATCH 03/14] fdisk: fix warning, incompatible pointer types passing 'uint64_t *' Ruediger Meier
2016-02-26 3:03 ` [PATCH 04/14] libsmartcols: fix uninitialized variable Ruediger Meier
2016-02-26 3:03 ` [PATCH 05/14] misc: fix some includes Ruediger Meier
2016-02-26 11:37 ` Ruediger Meier
2016-02-26 3:03 ` [PATCH 06/14] newgrp: rename memset_s() Ruediger Meier
2016-02-26 12:29 ` Yuriy M. Kaminskiy
2016-02-26 12:47 ` Ruediger Meier
2016-02-26 3:03 ` [PATCH 07/14] build-sys: build_init should check for flock Ruediger Meier
2016-02-26 3:03 ` [PATCH 08/14] login-utils: minor utmp cleanup Ruediger Meier
2016-02-26 3:03 ` [PATCH 09/14] build-sys: disable login-utils if shadow.h or utmp.h is missing Ruediger Meier
2016-02-26 3:08 ` [PATCH 10/14] build-sys: add --disable-ipcrm --disable-ipcs Ruediger Meier
2016-02-26 3:08 ` [PATCH 11/14] build-sys: chrt requires a sched_set* function Ruediger Meier
2016-02-26 3:08 ` [PATCH 12/14] lib: provide mkostemp fallback function Ruediger Meier
2016-02-26 12:51 ` Yuriy M. Kaminskiy
2016-02-26 13:50 ` Ruediger Meier
2016-02-26 14:51 ` Yuriy M. Kaminskiy [this message]
2016-02-27 19:40 ` [PATCH] Proper fallback for systems that lacks O_CLOEXEC (was: [PATCH 12/14] lib: provide mkostemp fallback function) Rüdiger Meier
2016-03-07 13:50 ` Karel Zak
2016-02-27 20:02 ` [PATCH v2 12/14] lib: provide fallback if mkostemp(3) missing Ruediger Meier
2016-02-26 3:08 ` [PATCH 13/14] build-sys: remove duplicate cal sources Ruediger Meier
2016-02-26 3:08 ` [PATCH 14/14] lib: include strutils.h for mempcpy() Ruediger Meier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3y4a7msnj.fsf_-_@gmail.com \
--to=yumkam@gmail.com \
--cc=util-linux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.