switch do_filp_open() to struct open_flags
take calculation of open_flags by open(2) arguments into new helper in fs/open.c, move filp_open() over there, have it and do_sys_open() use that helper, switch exec.c callers of do_filp_open() to explicit (and constant) struct open_flags. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
73
fs/open.c
73
fs/open.c
@@ -890,15 +890,86 @@ void fd_install(unsigned int fd, struct file *file)
|
||||
|
||||
EXPORT_SYMBOL(fd_install);
|
||||
|
||||
static inline int build_open_flags(int flags, int mode, struct open_flags *op)
|
||||
{
|
||||
int lookup_flags = 0;
|
||||
int acc_mode;
|
||||
|
||||
if (!(flags & O_CREAT))
|
||||
mode = 0;
|
||||
op->mode = mode;
|
||||
|
||||
/* Must never be set by userspace */
|
||||
flags &= ~FMODE_NONOTIFY;
|
||||
|
||||
/*
|
||||
* O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only
|
||||
* check for O_DSYNC if the need any syncing at all we enforce it's
|
||||
* always set instead of having to deal with possibly weird behaviour
|
||||
* for malicious applications setting only __O_SYNC.
|
||||
*/
|
||||
if (flags & __O_SYNC)
|
||||
flags |= O_DSYNC;
|
||||
|
||||
op->open_flag = flags;
|
||||
|
||||
acc_mode = MAY_OPEN | ACC_MODE(flags);
|
||||
|
||||
/* O_TRUNC implies we need access checks for write permissions */
|
||||
if (flags & O_TRUNC)
|
||||
acc_mode |= MAY_WRITE;
|
||||
|
||||
/* Allow the LSM permission hook to distinguish append
|
||||
access from general write access. */
|
||||
if (flags & O_APPEND)
|
||||
acc_mode |= MAY_APPEND;
|
||||
|
||||
op->acc_mode = acc_mode;
|
||||
|
||||
op->intent = LOOKUP_OPEN;
|
||||
if (flags & O_CREAT) {
|
||||
op->intent |= LOOKUP_CREATE;
|
||||
if (flags & O_EXCL)
|
||||
op->intent |= LOOKUP_EXCL;
|
||||
}
|
||||
|
||||
if (flags & O_DIRECTORY)
|
||||
lookup_flags |= LOOKUP_DIRECTORY;
|
||||
if (!(flags & O_NOFOLLOW))
|
||||
lookup_flags |= LOOKUP_FOLLOW;
|
||||
return lookup_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* filp_open - open file and return file pointer
|
||||
*
|
||||
* @filename: path to open
|
||||
* @flags: open flags as per the open(2) second argument
|
||||
* @mode: mode for the new file if O_CREAT is set, else ignored
|
||||
*
|
||||
* This is the helper to open a file from kernelspace if you really
|
||||
* have to. But in generally you should not do this, so please move
|
||||
* along, nothing to see here..
|
||||
*/
|
||||
struct file *filp_open(const char *filename, int flags, int mode)
|
||||
{
|
||||
struct open_flags op;
|
||||
int lookup = build_open_flags(flags, mode, &op);
|
||||
return do_filp_open(AT_FDCWD, filename, &op, lookup);
|
||||
}
|
||||
EXPORT_SYMBOL(filp_open);
|
||||
|
||||
long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
|
||||
{
|
||||
struct open_flags op;
|
||||
int lookup = build_open_flags(flags, mode, &op);
|
||||
char *tmp = getname(filename);
|
||||
int fd = PTR_ERR(tmp);
|
||||
|
||||
if (!IS_ERR(tmp)) {
|
||||
fd = get_unused_fd_flags(flags);
|
||||
if (fd >= 0) {
|
||||
struct file *f = do_filp_open(dfd, tmp, flags, mode, 0);
|
||||
struct file *f = do_filp_open(dfd, tmp, &op, lookup);
|
||||
if (IS_ERR(f)) {
|
||||
put_unused_fd(fd);
|
||||
fd = PTR_ERR(f);
|
||||
|
Reference in New Issue
Block a user