Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+13 -7
+13 -5
fs/open.c
··· 1196 1196 } 1197 1197 1198 1198 /* 1199 - * In order to ensure programs get explicit errors when trying to use 1200 - * O_TMPFILE on old kernels, O_TMPFILE is implemented such that it 1201 - * looks like (O_DIRECTORY|O_RDWR & ~O_CREAT) to old kernels. But we 1202 - * have to require userspace to explicitly set it. 1199 + * Block bugs where O_DIRECTORY | O_CREAT created regular files. 1200 + * Note, that blocking O_DIRECTORY | O_CREAT here also protects 1201 + * O_TMPFILE below which requires O_DIRECTORY being raised. 1203 1202 */ 1203 + if ((flags & (O_DIRECTORY | O_CREAT)) == (O_DIRECTORY | O_CREAT)) 1204 + return -EINVAL; 1205 + 1206 + /* Now handle the creative implementation of O_TMPFILE. */ 1204 1207 if (flags & __O_TMPFILE) { 1205 - if ((flags & O_TMPFILE_MASK) != O_TMPFILE) 1208 + /* 1209 + * In order to ensure programs get explicit errors when trying 1210 + * to use O_TMPFILE on old kernels we enforce that O_DIRECTORY 1211 + * is raised alongside __O_TMPFILE. 1212 + */ 1213 + if (!(flags & O_DIRECTORY)) 1206 1214 return -EINVAL; 1207 1215 if (!(acc_mode & MAY_WRITE)) 1208 1216 return -EINVAL;
-1
include/uapi/asm-generic/fcntl.h
··· 91 91 92 92 /* a horrid kludge trying to make sure that this will fail on old kernels */ 93 93 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) 94 - #define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT) 95 94 96 95 #ifndef O_NDELAY 97 96 #define O_NDELAY O_NONBLOCK
-1
tools/include/uapi/asm-generic/fcntl.h
··· 91 91 92 92 /* a horrid kludge trying to make sure that this will fail on old kernels */ 93 93 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) 94 - #define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT) 95 94 96 95 #ifndef O_NDELAY 97 96 #define O_NDELAY O_NONBLOCK