[PATCH] fanotify: add a flag to allow setting O_CLOEXEC on event fd

From: Yann Droneaud
Date: Thu Oct 02 2014 - 04:41:48 EST


In order to not potentially break applications which were
requesting O_CLOEXEC on event file descriptors but which
actually need it to be not effective as the kernel currently
ignore the flag, so the file descriptor is inherited accross
exec regardless of O_CLOEXEC (please forgive me for the
wording), this patch introduces FAN_FD_CLOEXEC flag to
fanotify_init() so that application can request O_CLOEXEC
to be effective.
Newer application would use FAN_FD_CLOEXEC flag along
O_CLOEXEC to enable close on exec on newly created
file descriptor:

fd = fanotify_init(FAN_CLOEXEC|FAN_NONBLOCK|FAN_FD_CLOEXEC,
O_RDONLY|O_LARGEFILE|O_CLOEXEC|O_NOATIME);

Signed-off-by: Yann Droneaud <ydroneaud@xxxxxxxxxx>
---

Hi Andrew,

While I believe fanotify_init() must enable close-on-exec
when requested by userspace to prevent unwelcomed security
issue, I understand your concerns regarding the possible
breakage on userspace application requesting O_CLOEXEC
but relying on it not being enable on file descriptor
created for the events.

So with a new flag to fanotify_init(), we could allow
newer applications to really enable O_CLOEXEC.

But I feel bad to have to force application to specify
twice they want close on exec:
- are you sure ?
- are you really sure ?
- is this your final answer ?
...

Regards.

Yann Droneaud
OPTEYA


fs/notify/fanotify/fanotify_user.c | 6 +++++-
include/uapi/linux/fanotify.h | 5 ++++-
2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index c991616acca9..3c1fb1412f37 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -78,7 +78,7 @@ static int create_fd(struct fsnotify_group *group,

pr_debug("%s: group=%p event=%p\n", __func__, group, event);

- client_fd = get_unused_fd_flags(group->fanotify_data.f_flags);
+ client_fd = get_unused_fd_flags(group->fanotify_data.f_flags & O_CLOEXEC);
if (client_fd < 0)
return client_fd;

@@ -706,6 +706,10 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
return -EINVAL;
}

+ if ((event_f_flags & O_CLOEXEC) &&
+ !(flags & FAN_FD_CLOEXEC))
+ event_f_flags ^= O_CLOEXEC;
+
user = get_current_user();
if (atomic_read(&user->fanotify_listeners) > FANOTIFY_DEFAULT_MAX_LISTENERS) {
free_uid(user);
diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h
index 030508d195d3..f2d517be3152 100644
--- a/include/uapi/linux/fanotify.h
+++ b/include/uapi/linux/fanotify.h
@@ -36,7 +36,10 @@
#define FAN_UNLIMITED_QUEUE 0x00000010
#define FAN_UNLIMITED_MARKS 0x00000020

-#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | \
+/* flags used for fanotify_init() too */
+#define FAN_FD_CLOEXEC 0x00000100
+
+#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | FAN_FD_CLOEXEC | \
FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE |\
FAN_UNLIMITED_MARKS)

--
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/