summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-04-24 14:06:41 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-04-24 14:06:41 -0700
commit97adb49f052e70455c3529509885f8aa3b40c370 (patch)
treec646f53d8bad336e9a7b2e8bed527b2217334cab
parente2eff52ce512ec725f9f1daf975c45a499be1e1e (diff)
parent43b450632676fb60e9faeddff285d9fac94a4f58 (diff)
downloadlinux-stable-97adb49f052e70455c3529509885f8aa3b40c370.tar.gz
Merge tag 'v6.4/vfs.open' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs open fixlet from Christian Brauner: "EINVAL ist keinmal: This contains the changes to make O_DIRECTORY when specified together with O_CREAT an invalid request. The wider background is that a regression report about the behavior of O_DIRECTORY | O_CREAT was sent to fsdevel about a behavior that was changed multiple years and LTS releases earlier during v5.7 development. This has also been covered in https://lwn.net/Articles/926782/ which provides an excellent summary of the discussion" * tag 'v6.4/vfs.open' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: open: return EINVAL for O_DIRECTORY | O_CREAT
-rw-r--r--fs/open.c18
-rw-r--r--include/uapi/asm-generic/fcntl.h1
-rw-r--r--tools/include/uapi/asm-generic/fcntl.h1
3 files changed, 13 insertions, 7 deletions
diff --git a/fs/open.c b/fs/open.c
index 4401a73d4032..4478adcc4f3a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1196,13 +1196,21 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
}
/*
- * In order to ensure programs get explicit errors when trying to use
- * O_TMPFILE on old kernels, O_TMPFILE is implemented such that it
- * looks like (O_DIRECTORY|O_RDWR & ~O_CREAT) to old kernels. But we
- * have to require userspace to explicitly set it.
+ * Block bugs where O_DIRECTORY | O_CREAT created regular files.
+ * Note, that blocking O_DIRECTORY | O_CREAT here also protects
+ * O_TMPFILE below which requires O_DIRECTORY being raised.
*/
+ if ((flags & (O_DIRECTORY | O_CREAT)) == (O_DIRECTORY | O_CREAT))
+ return -EINVAL;
+
+ /* Now handle the creative implementation of O_TMPFILE. */
if (flags & __O_TMPFILE) {
- if ((flags & O_TMPFILE_MASK) != O_TMPFILE)
+ /*
+ * In order to ensure programs get explicit errors when trying
+ * to use O_TMPFILE on old kernels we enforce that O_DIRECTORY
+ * is raised alongside __O_TMPFILE.
+ */
+ if (!(flags & O_DIRECTORY))
return -EINVAL;
if (!(acc_mode & MAY_WRITE))
return -EINVAL;
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index 1ecdb911add8..80f37a0d40d7 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -91,7 +91,6 @@
/* a horrid kludge trying to make sure that this will fail on old kernels */
#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
-#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT)
#ifndef O_NDELAY
#define O_NDELAY O_NONBLOCK
diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h
index b02c8e0f4057..1c7a0f6632c0 100644
--- a/tools/include/uapi/asm-generic/fcntl.h
+++ b/tools/include/uapi/asm-generic/fcntl.h
@@ -91,7 +91,6 @@
/* a horrid kludge trying to make sure that this will fail on old kernels */
#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
-#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT)
#ifndef O_NDELAY
#define O_NDELAY O_NONBLOCK