mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-15 13:22:55 +00:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "These four commits are obvious fixes (a couple of fdget_pos()-related ones from Eric Biggers, prepend_name() fix, missing checks for false negatives from __lookup_mnt() in fs/namei.c)" For now I'm pulling just the four obvious fixes, there's another four pending in Al's 'for-linus' branch wrt the mnt_hash list that were more involved. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: rcuwalk: recheck mount_lock after mountpoint crossing attempts make prepend_name() work correctly when called with negative *buflen vfs: Don't let __fdget_pos() get FMODE_PATH files vfs: atomic f_pos access in llseek()
This commit is contained in:
commit
3e79d97828
@ -2833,9 +2833,9 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name)
|
||||
u32 dlen = ACCESS_ONCE(name->len);
|
||||
char *p;
|
||||
|
||||
if (*buflen < dlen + 1)
|
||||
return -ENAMETOOLONG;
|
||||
*buflen -= dlen + 1;
|
||||
if (*buflen < 0)
|
||||
return -ENAMETOOLONG;
|
||||
p = *buffer -= dlen + 1;
|
||||
*p++ = '/';
|
||||
while (dlen--) {
|
||||
|
19
fs/file.c
19
fs/file.c
@ -713,27 +713,16 @@ unsigned long __fdget_raw(unsigned int fd)
|
||||
|
||||
unsigned long __fdget_pos(unsigned int fd)
|
||||
{
|
||||
struct files_struct *files = current->files;
|
||||
struct file *file;
|
||||
unsigned long v;
|
||||
unsigned long v = __fdget(fd);
|
||||
struct file *file = (struct file *)(v & ~3);
|
||||
|
||||
if (atomic_read(&files->count) == 1) {
|
||||
file = __fcheck_files(files, fd);
|
||||
v = 0;
|
||||
} else {
|
||||
file = __fget(fd, 0);
|
||||
v = FDPUT_FPUT;
|
||||
}
|
||||
if (!file)
|
||||
return 0;
|
||||
|
||||
if (file->f_mode & FMODE_ATOMIC_POS) {
|
||||
if (file && (file->f_mode & FMODE_ATOMIC_POS)) {
|
||||
if (file_count(file) > 1) {
|
||||
v |= FDPUT_POS_UNLOCK;
|
||||
mutex_lock(&file->f_pos_lock);
|
||||
}
|
||||
}
|
||||
return v | (unsigned long)file;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
|
29
fs/namei.c
29
fs/namei.c
@ -1109,7 +1109,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
|
||||
return false;
|
||||
|
||||
if (!d_mountpoint(path->dentry))
|
||||
break;
|
||||
return true;
|
||||
|
||||
mounted = __lookup_mnt(path->mnt, path->dentry);
|
||||
if (!mounted)
|
||||
@ -1125,20 +1125,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
|
||||
*/
|
||||
*inode = path->dentry->d_inode;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void follow_mount_rcu(struct nameidata *nd)
|
||||
{
|
||||
while (d_mountpoint(nd->path.dentry)) {
|
||||
struct mount *mounted;
|
||||
mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry);
|
||||
if (!mounted)
|
||||
break;
|
||||
nd->path.mnt = &mounted->mnt;
|
||||
nd->path.dentry = mounted->mnt.mnt_root;
|
||||
nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
|
||||
}
|
||||
return read_seqretry(&mount_lock, nd->m_seq);
|
||||
}
|
||||
|
||||
static int follow_dotdot_rcu(struct nameidata *nd)
|
||||
@ -1166,7 +1153,17 @@ static int follow_dotdot_rcu(struct nameidata *nd)
|
||||
break;
|
||||
nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
|
||||
}
|
||||
follow_mount_rcu(nd);
|
||||
while (d_mountpoint(nd->path.dentry)) {
|
||||
struct mount *mounted;
|
||||
mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry);
|
||||
if (!mounted)
|
||||
break;
|
||||
nd->path.mnt = &mounted->mnt;
|
||||
nd->path.dentry = mounted->mnt.mnt_root;
|
||||
nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
|
||||
if (!read_seqretry(&mount_lock, nd->m_seq))
|
||||
goto failed;
|
||||
}
|
||||
nd->inode = nd->path.dentry->d_inode;
|
||||
return 0;
|
||||
|
||||
|
@ -307,7 +307,7 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
|
||||
unsigned int, whence)
|
||||
{
|
||||
int retval;
|
||||
struct fd f = fdget(fd);
|
||||
struct fd f = fdget_pos(fd);
|
||||
loff_t offset;
|
||||
|
||||
if (!f.file)
|
||||
@ -327,7 +327,7 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
|
||||
retval = 0;
|
||||
}
|
||||
out_putf:
|
||||
fdput(f);
|
||||
fdput_pos(f);
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user