mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs changes from Al Viro.
"A lot of misc stuff. The obvious groups:
* Miklos' atomic_open series; kills the damn abuse of
->d_revalidate() by NFS, which was the major stumbling block for
all work in that area.
* ripping security_file_mmap() and dealing with deadlocks in the
area; sanitizing the neighborhood of vm_mmap()/vm_munmap() in
general.
* ->encode_fh() switched to saner API; insane fake dentry in
mm/cleancache.c gone.
* assorted annotations in fs (endianness, __user)
* parts of Artem's ->s_dirty work (jff2 and reiserfs parts)
* ->update_time() work from Josef.
* other bits and pieces all over the place.
Normally it would've been in two or three pull requests, but
signal.git stuff had eaten a lot of time during this cycle ;-/"
Fix up trivial conflicts in Documentation/filesystems/vfs.txt (the
'truncate_range' inode method was removed by the VM changes, the VFS
update adds an 'update_time()' method), and in fs/btrfs/ulist.[ch] (due
to sparse fix added twice, with other changes nearby).
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (95 commits)
nfs: don't open in ->d_revalidate
vfs: retry last component if opening stale dentry
vfs: nameidata_to_filp(): don't throw away file on error
vfs: nameidata_to_filp(): inline __dentry_open()
vfs: do_dentry_open(): don't put filp
vfs: split __dentry_open()
vfs: do_last() common post lookup
vfs: do_last(): add audit_inode before open
vfs: do_last(): only return EISDIR for O_CREAT
vfs: do_last(): check LOOKUP_DIRECTORY
vfs: do_last(): make ENOENT exit RCU safe
vfs: make follow_link check RCU safe
vfs: do_last(): use inode variable
vfs: do_last(): inline walk_component()
vfs: do_last(): make exit RCU safe
vfs: split do_lookup()
Btrfs: move over to use ->update_time
fs: introduce inode operation ->update_time
reiserfs: get rid of resierfs_sync_super
reiserfs: mark the superblock as dirty a bit later
...
This commit is contained in:
commit
1193755ac6
148 changed files with 1495 additions and 1618 deletions
|
|
@ -80,7 +80,7 @@ EXPORT_SYMBOL(__cleancache_init_shared_fs);
|
|||
static int cleancache_get_key(struct inode *inode,
|
||||
struct cleancache_filekey *key)
|
||||
{
|
||||
int (*fhfn)(struct dentry *, __u32 *fh, int *, int);
|
||||
int (*fhfn)(struct inode *, __u32 *fh, int *, struct inode *);
|
||||
int len = 0, maxlen = CLEANCACHE_KEY_MAX;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
|
||||
|
|
@ -88,9 +88,7 @@ static int cleancache_get_key(struct inode *inode,
|
|||
if (sb->s_export_op != NULL) {
|
||||
fhfn = sb->s_export_op->encode_fh;
|
||||
if (fhfn) {
|
||||
struct dentry d;
|
||||
d.d_inode = inode;
|
||||
len = (*fhfn)(&d, &key->u.fh[0], &maxlen, 0);
|
||||
len = (*fhfn)(inode, &key->u.fh[0], &maxlen, NULL);
|
||||
if (len <= 0 || len == 255)
|
||||
return -1;
|
||||
if (maxlen > CLEANCACHE_KEY_MAX)
|
||||
|
|
|
|||
69
mm/filemap.c
69
mm/filemap.c
|
|
@ -1899,71 +1899,6 @@ struct page *read_cache_page(struct address_space *mapping,
|
|||
}
|
||||
EXPORT_SYMBOL(read_cache_page);
|
||||
|
||||
/*
|
||||
* The logic we want is
|
||||
*
|
||||
* if suid or (sgid and xgrp)
|
||||
* remove privs
|
||||
*/
|
||||
int should_remove_suid(struct dentry *dentry)
|
||||
{
|
||||
umode_t mode = dentry->d_inode->i_mode;
|
||||
int kill = 0;
|
||||
|
||||
/* suid always must be killed */
|
||||
if (unlikely(mode & S_ISUID))
|
||||
kill = ATTR_KILL_SUID;
|
||||
|
||||
/*
|
||||
* sgid without any exec bits is just a mandatory locking mark; leave
|
||||
* it alone. If some exec bits are set, it's a real sgid; kill it.
|
||||
*/
|
||||
if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
|
||||
kill |= ATTR_KILL_SGID;
|
||||
|
||||
if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
|
||||
return kill;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(should_remove_suid);
|
||||
|
||||
static int __remove_suid(struct dentry *dentry, int kill)
|
||||
{
|
||||
struct iattr newattrs;
|
||||
|
||||
newattrs.ia_valid = ATTR_FORCE | kill;
|
||||
return notify_change(dentry, &newattrs);
|
||||
}
|
||||
|
||||
int file_remove_suid(struct file *file)
|
||||
{
|
||||
struct dentry *dentry = file->f_path.dentry;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int killsuid;
|
||||
int killpriv;
|
||||
int error = 0;
|
||||
|
||||
/* Fast path for nothing security related */
|
||||
if (IS_NOSEC(inode))
|
||||
return 0;
|
||||
|
||||
killsuid = should_remove_suid(dentry);
|
||||
killpriv = security_inode_need_killpriv(dentry);
|
||||
|
||||
if (killpriv < 0)
|
||||
return killpriv;
|
||||
if (killpriv)
|
||||
error = security_inode_killpriv(dentry);
|
||||
if (!error && killsuid)
|
||||
error = __remove_suid(dentry, killsuid);
|
||||
if (!error && (inode->i_sb->s_flags & MS_NOSEC))
|
||||
inode->i_flags |= S_NOSEC;
|
||||
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL(file_remove_suid);
|
||||
|
||||
static size_t __iovec_copy_from_user_inatomic(char *vaddr,
|
||||
const struct iovec *iov, size_t base, size_t bytes)
|
||||
{
|
||||
|
|
@ -2489,7 +2424,9 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
|||
if (err)
|
||||
goto out;
|
||||
|
||||
file_update_time(file);
|
||||
err = file_update_time(file);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
/* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
|
||||
if (unlikely(file->f_flags & O_DIRECT)) {
|
||||
|
|
|
|||
|
|
@ -426,7 +426,9 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len,
|
|||
if (ret)
|
||||
goto out_backing;
|
||||
|
||||
file_update_time(filp);
|
||||
ret = file_update_time(filp);
|
||||
if (ret)
|
||||
goto out_backing;
|
||||
|
||||
ret = __xip_file_write (filp, buf, count, pos, ppos);
|
||||
|
||||
|
|
|
|||
|
|
@ -350,3 +350,7 @@ extern u64 hwpoison_filter_flags_mask;
|
|||
extern u64 hwpoison_filter_flags_value;
|
||||
extern u64 hwpoison_filter_memcg;
|
||||
extern u32 hwpoison_filter_enable;
|
||||
|
||||
extern unsigned long vm_mmap_pgoff(struct file *, unsigned long,
|
||||
unsigned long, unsigned long,
|
||||
unsigned long, unsigned long);
|
||||
|
|
|
|||
54
mm/mmap.c
54
mm/mmap.c
|
|
@ -971,15 +971,13 @@ static inline unsigned long round_hint_to_min(unsigned long hint)
|
|||
* The caller must hold down_write(¤t->mm->mmap_sem).
|
||||
*/
|
||||
|
||||
static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
|
||||
unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
|
||||
unsigned long len, unsigned long prot,
|
||||
unsigned long flags, unsigned long pgoff)
|
||||
{
|
||||
struct mm_struct * mm = current->mm;
|
||||
struct inode *inode;
|
||||
vm_flags_t vm_flags;
|
||||
int error;
|
||||
unsigned long reqprot = prot;
|
||||
|
||||
/*
|
||||
* Does the application expect PROT_READ to imply PROT_EXEC?
|
||||
|
|
@ -1101,39 +1099,9 @@ static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
|
|||
}
|
||||
}
|
||||
|
||||
error = security_file_mmap(file, reqprot, prot, flags, addr, 0);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return mmap_region(file, addr, len, flags, vm_flags, pgoff);
|
||||
}
|
||||
|
||||
unsigned long do_mmap(struct file *file, unsigned long addr,
|
||||
unsigned long len, unsigned long prot,
|
||||
unsigned long flag, unsigned long offset)
|
||||
{
|
||||
if (unlikely(offset + PAGE_ALIGN(len) < offset))
|
||||
return -EINVAL;
|
||||
if (unlikely(offset & ~PAGE_MASK))
|
||||
return -EINVAL;
|
||||
return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
|
||||
}
|
||||
EXPORT_SYMBOL(do_mmap);
|
||||
|
||||
unsigned long vm_mmap(struct file *file, unsigned long addr,
|
||||
unsigned long len, unsigned long prot,
|
||||
unsigned long flag, unsigned long offset)
|
||||
{
|
||||
unsigned long ret;
|
||||
struct mm_struct *mm = current->mm;
|
||||
|
||||
down_write(&mm->mmap_sem);
|
||||
ret = do_mmap(file, addr, len, prot, flag, offset);
|
||||
up_write(&mm->mmap_sem);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(vm_mmap);
|
||||
|
||||
SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
|
||||
unsigned long, prot, unsigned long, flags,
|
||||
unsigned long, fd, unsigned long, pgoff)
|
||||
|
|
@ -1165,10 +1133,7 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
|
|||
|
||||
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
|
||||
retval = vm_mmap_pgoff(file, addr, len, prot, flags, pgoff);
|
||||
if (file)
|
||||
fput(file);
|
||||
out:
|
||||
|
|
@ -1629,7 +1594,9 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
|
|||
if (addr & ~PAGE_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
return arch_rebalance_pgtables(addr, len);
|
||||
addr = arch_rebalance_pgtables(addr, len);
|
||||
error = security_mmap_addr(addr);
|
||||
return error ? error : addr;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(get_unmapped_area);
|
||||
|
|
@ -1819,7 +1786,7 @@ int expand_downwards(struct vm_area_struct *vma,
|
|||
return -ENOMEM;
|
||||
|
||||
address &= PAGE_MASK;
|
||||
error = security_file_mmap(NULL, 0, 0, 0, address, 1);
|
||||
error = security_mmap_addr(address);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
@ -2159,7 +2126,6 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(do_munmap);
|
||||
|
||||
int vm_munmap(unsigned long start, size_t len)
|
||||
{
|
||||
|
|
@ -2207,10 +2173,6 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
|
|||
if (!len)
|
||||
return addr;
|
||||
|
||||
error = security_file_mmap(NULL, 0, 0, 0, addr, 1);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
|
||||
|
||||
error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED);
|
||||
|
|
@ -2563,10 +2525,6 @@ int install_special_mapping(struct mm_struct *mm,
|
|||
vma->vm_ops = &special_mapping_vmops;
|
||||
vma->vm_private_data = pages;
|
||||
|
||||
ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = insert_vm_struct(mm, vma);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
|
|
|||
26
mm/mremap.c
26
mm/mremap.c
|
|
@ -371,10 +371,6 @@ static unsigned long mremap_to(unsigned long addr,
|
|||
if ((addr <= new_addr) && (addr+old_len) > new_addr)
|
||||
goto out;
|
||||
|
||||
ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = do_munmap(mm, new_addr, new_len);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
|
@ -432,15 +428,17 @@ static int vma_expandable(struct vm_area_struct *vma, unsigned long delta)
|
|||
* MREMAP_FIXED option added 5-Dec-1999 by Benjamin LaHaise
|
||||
* This option implies MREMAP_MAYMOVE.
|
||||
*/
|
||||
unsigned long do_mremap(unsigned long addr,
|
||||
unsigned long old_len, unsigned long new_len,
|
||||
unsigned long flags, unsigned long new_addr)
|
||||
SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
|
||||
unsigned long, new_len, unsigned long, flags,
|
||||
unsigned long, new_addr)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
struct vm_area_struct *vma;
|
||||
unsigned long ret = -EINVAL;
|
||||
unsigned long charged = 0;
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
|
||||
if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
|
||||
goto out;
|
||||
|
||||
|
|
@ -530,25 +528,11 @@ unsigned long do_mremap(unsigned long addr,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = move_vma(vma, addr, old_len, new_len, new_addr);
|
||||
}
|
||||
out:
|
||||
if (ret & ~PAGE_MASK)
|
||||
vm_unacct_memory(charged);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
|
||||
unsigned long, new_len, unsigned long, flags,
|
||||
unsigned long, new_addr)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
ret = do_mremap(addr, old_len, new_len, flags, new_addr);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
35
mm/nommu.c
35
mm/nommu.c
|
|
@ -889,7 +889,6 @@ static int validate_mmap_request(struct file *file,
|
|||
unsigned long *_capabilities)
|
||||
{
|
||||
unsigned long capabilities, rlen;
|
||||
unsigned long reqprot = prot;
|
||||
int ret;
|
||||
|
||||
/* do the simple checks first */
|
||||
|
|
@ -1047,7 +1046,7 @@ static int validate_mmap_request(struct file *file,
|
|||
}
|
||||
|
||||
/* allow the security API to have its say */
|
||||
ret = security_file_mmap(file, reqprot, prot, flags, addr, 0);
|
||||
ret = security_mmap_addr(addr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1233,7 +1232,7 @@ enomem:
|
|||
/*
|
||||
* handle mapping creation for uClinux
|
||||
*/
|
||||
static unsigned long do_mmap_pgoff(struct file *file,
|
||||
unsigned long do_mmap_pgoff(struct file *file,
|
||||
unsigned long addr,
|
||||
unsigned long len,
|
||||
unsigned long prot,
|
||||
|
|
@ -1471,32 +1470,6 @@ error_getting_region:
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
unsigned long do_mmap(struct file *file, unsigned long addr,
|
||||
unsigned long len, unsigned long prot,
|
||||
unsigned long flag, unsigned long offset)
|
||||
{
|
||||
if (unlikely(offset + PAGE_ALIGN(len) < offset))
|
||||
return -EINVAL;
|
||||
if (unlikely(offset & ~PAGE_MASK))
|
||||
return -EINVAL;
|
||||
return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
|
||||
}
|
||||
EXPORT_SYMBOL(do_mmap);
|
||||
|
||||
unsigned long vm_mmap(struct file *file, unsigned long addr,
|
||||
unsigned long len, unsigned long prot,
|
||||
unsigned long flag, unsigned long offset)
|
||||
{
|
||||
unsigned long ret;
|
||||
struct mm_struct *mm = current->mm;
|
||||
|
||||
down_write(&mm->mmap_sem);
|
||||
ret = do_mmap(file, addr, len, prot, flag, offset);
|
||||
up_write(&mm->mmap_sem);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(vm_mmap);
|
||||
|
||||
SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
|
||||
unsigned long, prot, unsigned long, flags,
|
||||
unsigned long, fd, unsigned long, pgoff)
|
||||
|
|
@ -1513,9 +1486,7 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
|
|||
|
||||
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
ret = vm_mmap_pgoff(file, addr, len, prot, flags, pgoff);
|
||||
|
||||
if (file)
|
||||
fput(file);
|
||||
|
|
|
|||
|
|
@ -2439,11 +2439,9 @@ static struct dentry *shmem_fh_to_dentry(struct super_block *sb,
|
|||
return dentry;
|
||||
}
|
||||
|
||||
static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
|
||||
int connectable)
|
||||
static int shmem_encode_fh(struct inode *inode, __u32 *fh, int *len,
|
||||
struct inode *parent)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
|
||||
if (*len < 3) {
|
||||
*len = 3;
|
||||
return 255;
|
||||
|
|
|
|||
30
mm/util.c
30
mm/util.c
|
|
@ -4,6 +4,7 @@
|
|||
#include <linux/export.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/security.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
|
@ -341,6 +342,35 @@ int __attribute__((weak)) get_user_pages_fast(unsigned long start,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(get_user_pages_fast);
|
||||
|
||||
unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr,
|
||||
unsigned long len, unsigned long prot,
|
||||
unsigned long flag, unsigned long pgoff)
|
||||
{
|
||||
unsigned long ret;
|
||||
struct mm_struct *mm = current->mm;
|
||||
|
||||
ret = security_mmap_file(file, prot, flag);
|
||||
if (!ret) {
|
||||
down_write(&mm->mmap_sem);
|
||||
ret = do_mmap_pgoff(file, addr, len, prot, flag, pgoff);
|
||||
up_write(&mm->mmap_sem);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned long vm_mmap(struct file *file, unsigned long addr,
|
||||
unsigned long len, unsigned long prot,
|
||||
unsigned long flag, unsigned long offset)
|
||||
{
|
||||
if (unlikely(offset + PAGE_ALIGN(len) < offset))
|
||||
return -EINVAL;
|
||||
if (unlikely(offset & ~PAGE_MASK))
|
||||
return -EINVAL;
|
||||
|
||||
return vm_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
|
||||
}
|
||||
EXPORT_SYMBOL(vm_mmap);
|
||||
|
||||
/* Tracepoints definitions. */
|
||||
EXPORT_TRACEPOINT_SYMBOL(kmalloc);
|
||||
EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc);
|
||||
|
|
|
|||
Loading…
Reference in a new issue