mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
Merge tag 'vfs-7.1-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull misc vfs updates from Christian Brauner:
"Features:
- coredump: add tracepoint for coredump events
- fs: hide file and bfile caches behind runtime const machinery
Fixes:
- fix architecture-specific compat_ftruncate64 implementations
- dcache: Limit the minimal number of bucket to two
- fs/omfs: reject s_sys_blocksize smaller than OMFS_DIR_START
- fs/mbcache: cancel shrink work before destroying the cache
- dcache: permit dynamic_dname()s up to NAME_MAX
Cleanups:
- remove or unexport unused fs_context infrastructure
- trivial ->setattr cleanups
- selftests/filesystems: Assume that TIOCGPTPEER is defined
- writeback: fix kernel-doc function name mismatch for wb_put_many()
- autofs: replace manual symlink buffer allocation in autofs_dir_symlink
- init/initramfs.c: trivial fix: FSM -> Finite-state machine
- fs: remove stale and duplicate forward declarations
- readdir: Introduce dirent_size()
- fs: Replace user_access_{begin/end} by scoped user access
- kernel: acct: fix duplicate word in comment
- fs: write a better comment in step_into() concerning .mnt assignment
- fs: attr: fix comment formatting and spelling issues"
* tag 'vfs-7.1-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (28 commits)
dcache: permit dynamic_dname()s up to NAME_MAX
fs: attr: fix comment formatting and spelling issues
fs: hide file and bfile caches behind runtime const machinery
fs: write a better comment in step_into() concerning .mnt assignment
proc: rename proc_notify_change to proc_setattr
proc: rename proc_setattr to proc_nochmod_setattr
affs: rename affs_notify_change to affs_setattr
adfs: rename adfs_notify_change to adfs_setattr
hfs: update comments on hfs_inode_setattr
kernel: acct: fix duplicate word in comment
fs: Replace user_access_{begin/end} by scoped user access
readdir: Introduce dirent_size()
coredump: add tracepoint for coredump events
fs: remove do_sys_truncate
fs: pass on FTRUNCATE_* flags to do_truncate
fs: fix archiecture-specific compat_ftruncate64
fs: remove stale and duplicate forward declarations
init/initramfs.c: trivial fix: FSM -> Finite-state machine
autofs: replace manual symlink buffer allocation in autofs_dir_symlink
fs/mbcache: cancel shrink work before destroying the cache
...
This commit is contained in:
@@ -647,9 +647,7 @@ The members are as follows:
|
||||
fs_param_is_u64 64-bit unsigned int result->uint_64
|
||||
fs_param_is_enum Enum value name result->uint_32
|
||||
fs_param_is_string Arbitrary string param->string
|
||||
fs_param_is_blob Binary blob param->blob
|
||||
fs_param_is_blockdev Blockdev path * Needs lookup
|
||||
fs_param_is_path Path * Needs lookup
|
||||
fs_param_is_fd File descriptor result->int_32
|
||||
fs_param_is_uid User ID (u32) result->uid
|
||||
fs_param_is_gid Group ID (u32) result->gid
|
||||
@@ -681,9 +679,7 @@ The members are as follows:
|
||||
fsparam_u64() fs_param_is_u64
|
||||
fsparam_enum() fs_param_is_enum
|
||||
fsparam_string() fs_param_is_string
|
||||
fsparam_blob() fs_param_is_blob
|
||||
fsparam_bdev() fs_param_is_blockdev
|
||||
fsparam_path() fs_param_is_path
|
||||
fsparam_fd() fs_param_is_fd
|
||||
fsparam_uid() fs_param_is_uid
|
||||
fsparam_gid() fs_param_is_gid
|
||||
|
||||
@@ -89,7 +89,7 @@ COMPAT_SYSCALL_DEFINE4(aarch32_truncate64, const char __user *, pathname,
|
||||
COMPAT_SYSCALL_DEFINE4(aarch32_ftruncate64, unsigned int, fd, u32, __pad,
|
||||
arg_u32p(length))
|
||||
{
|
||||
return ksys_ftruncate(fd, arg_u64(length));
|
||||
return ksys_ftruncate(fd, arg_u64(length), FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE5(aarch32_readahead, int, fd, u32, __pad,
|
||||
|
||||
@@ -60,7 +60,7 @@ SYSCALL_DEFINE4(32_truncate64, const char __user *, path,
|
||||
SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy,
|
||||
unsigned long, a2, unsigned long, a3)
|
||||
{
|
||||
return ksys_ftruncate(fd, merge_64(a2, a3));
|
||||
return ksys_ftruncate(fd, merge_64(a2, a3), FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE5(32_llseek, unsigned int, fd, unsigned int, offset_high,
|
||||
|
||||
@@ -216,7 +216,7 @@ asmlinkage long parisc_truncate64(const char __user * path,
|
||||
asmlinkage long parisc_ftruncate64(unsigned int fd,
|
||||
unsigned int high, unsigned int low)
|
||||
{
|
||||
return ksys_ftruncate(fd, (long)high << 32 | low);
|
||||
return ksys_ftruncate(fd, (long)high << 32 | low, FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
/* stubs for the benefit of the syscall_table since truncate64 and truncate
|
||||
@@ -227,7 +227,7 @@ asmlinkage long sys_truncate64(const char __user * path, unsigned long length)
|
||||
}
|
||||
asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length)
|
||||
{
|
||||
return ksys_ftruncate(fd, length);
|
||||
return ksys_ftruncate(fd, length, FTRUNCATE_LFS);
|
||||
}
|
||||
asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
|
||||
@@ -101,7 +101,7 @@ PPC32_SYSCALL_DEFINE4(ppc_ftruncate64,
|
||||
unsigned int, fd, u32, reg4,
|
||||
unsigned long, len1, unsigned long, len2)
|
||||
{
|
||||
return ksys_ftruncate(fd, merge_64(len1, len2));
|
||||
return ksys_ftruncate(fd, merge_64(len1, len2), FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
PPC32_SYSCALL_DEFINE6(ppc32_fadvise64,
|
||||
|
||||
@@ -58,7 +58,7 @@ COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, path, u32, high, u32, lo
|
||||
|
||||
COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd, u32, high, u32, low)
|
||||
{
|
||||
return ksys_ftruncate(fd, ((u64)high << 32) | low);
|
||||
return ksys_ftruncate(fd, ((u64)high << 32) | low, FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
static int cp_compat_stat64(struct kstat *stat,
|
||||
|
||||
@@ -61,7 +61,8 @@ SYSCALL_DEFINE3(ia32_truncate64, const char __user *, filename,
|
||||
SYSCALL_DEFINE3(ia32_ftruncate64, unsigned int, fd,
|
||||
unsigned long, offset_low, unsigned long, offset_high)
|
||||
{
|
||||
return ksys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low);
|
||||
return ksys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low,
|
||||
FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
/* warning: next two assume little endian */
|
||||
|
||||
@@ -144,8 +144,8 @@ struct adfs_discmap {
|
||||
/* Inode stuff */
|
||||
struct inode *adfs_iget(struct super_block *sb, struct object_info *obj);
|
||||
int adfs_write_inode(struct inode *inode, struct writeback_control *wbc);
|
||||
int adfs_notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *attr);
|
||||
int adfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *attr);
|
||||
|
||||
/* map.c */
|
||||
int adfs_map_lookup(struct super_block *sb, u32 frag_id, unsigned int offset);
|
||||
|
||||
@@ -454,5 +454,5 @@ adfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||
*/
|
||||
const struct inode_operations adfs_dir_inode_operations = {
|
||||
.lookup = adfs_lookup,
|
||||
.setattr = adfs_notify_change,
|
||||
.setattr = adfs_setattr,
|
||||
};
|
||||
|
||||
@@ -32,5 +32,5 @@ const struct file_operations adfs_file_operations = {
|
||||
};
|
||||
|
||||
const struct inode_operations adfs_file_inode_operations = {
|
||||
.setattr = adfs_notify_change,
|
||||
.setattr = adfs_setattr,
|
||||
};
|
||||
|
||||
@@ -299,8 +299,7 @@ out:
|
||||
* later.
|
||||
*/
|
||||
int
|
||||
adfs_notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *attr)
|
||||
adfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr)
|
||||
{
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct super_block *sb = inode->i_sb;
|
||||
@@ -355,8 +354,7 @@ out:
|
||||
|
||||
/*
|
||||
* write an existing inode back to the directory, and therefore the disk.
|
||||
* The adfs-specific inode data has already been updated by
|
||||
* adfs_notify_change()
|
||||
* The adfs-specific inode data has already been updated by * adfs_setattr().
|
||||
*/
|
||||
int adfs_write_inode(struct inode *inode, struct writeback_control *wbc)
|
||||
{
|
||||
|
||||
@@ -186,7 +186,7 @@ extern int affs_rename2(struct mnt_idmap *idmap,
|
||||
/* inode.c */
|
||||
|
||||
extern struct inode *affs_new_inode(struct inode *dir);
|
||||
extern int affs_notify_change(struct mnt_idmap *idmap,
|
||||
extern int affs_setattr(struct mnt_idmap *idmap,
|
||||
struct dentry *dentry, struct iattr *attr);
|
||||
extern void affs_evict_inode(struct inode *inode);
|
||||
extern struct inode *affs_iget(struct super_block *sb,
|
||||
|
||||
@@ -71,7 +71,7 @@ const struct inode_operations affs_dir_inode_operations = {
|
||||
.mkdir = affs_mkdir,
|
||||
.rmdir = affs_rmdir,
|
||||
.rename = affs_rename2,
|
||||
.setattr = affs_notify_change,
|
||||
.setattr = affs_setattr,
|
||||
};
|
||||
|
||||
static int
|
||||
|
||||
@@ -1016,5 +1016,5 @@ const struct file_operations affs_file_operations = {
|
||||
};
|
||||
|
||||
const struct inode_operations affs_file_inode_operations = {
|
||||
.setattr = affs_notify_change,
|
||||
.setattr = affs_setattr,
|
||||
};
|
||||
|
||||
@@ -213,13 +213,12 @@ affs_write_inode(struct inode *inode, struct writeback_control *wbc)
|
||||
}
|
||||
|
||||
int
|
||||
affs_notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *attr)
|
||||
affs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr)
|
||||
{
|
||||
struct inode *inode = d_inode(dentry);
|
||||
int error;
|
||||
|
||||
pr_debug("notify_change(%llu,0x%x)\n", inode->i_ino, attr->ia_valid);
|
||||
pr_debug("setattr(%llu,0x%x)\n", inode->i_ino, attr->ia_valid);
|
||||
|
||||
error = setattr_prepare(&nop_mnt_idmap, dentry, attr);
|
||||
if (error)
|
||||
|
||||
@@ -71,5 +71,5 @@ const struct address_space_operations affs_symlink_aops = {
|
||||
|
||||
const struct inode_operations affs_symlink_inode_operations = {
|
||||
.get_link = page_get_link,
|
||||
.setattr = affs_notify_change,
|
||||
.setattr = affs_setattr,
|
||||
};
|
||||
|
||||
@@ -46,8 +46,8 @@ int setattr_should_drop_sgid(struct mnt_idmap *idmap,
|
||||
EXPORT_SYMBOL(setattr_should_drop_sgid);
|
||||
|
||||
/**
|
||||
* setattr_should_drop_suidgid - determine whether the set{g,u}id bit needs to
|
||||
* be dropped
|
||||
* setattr_should_drop_suidgid - determine whether the set{g,u}id bit
|
||||
* needs to be dropped
|
||||
* @idmap: idmap of the mount @inode was found from
|
||||
* @inode: inode to check
|
||||
*
|
||||
@@ -165,7 +165,7 @@ int setattr_prepare(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
unsigned int ia_valid = attr->ia_valid;
|
||||
|
||||
/*
|
||||
* First check size constraints. These can't be overriden using
|
||||
* First check size constraints. These can't be overridden using
|
||||
* ATTR_FORCE.
|
||||
*/
|
||||
if (ia_valid & ATTR_SIZE) {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/capability.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include "autofs_i.h"
|
||||
|
||||
@@ -578,7 +579,6 @@ static int autofs_dir_symlink(struct mnt_idmap *idmap,
|
||||
struct autofs_info *ino = autofs_dentry_ino(dentry);
|
||||
struct autofs_info *p_ino;
|
||||
struct inode *inode;
|
||||
size_t size = strlen(symname);
|
||||
char *cp;
|
||||
|
||||
pr_debug("%s <- %pd\n", symname, dentry);
|
||||
@@ -589,19 +589,17 @@ static int autofs_dir_symlink(struct mnt_idmap *idmap,
|
||||
|
||||
autofs_del_active(dentry);
|
||||
|
||||
cp = kmalloc(size + 1, GFP_KERNEL);
|
||||
cp = kstrdup(symname, GFP_KERNEL);
|
||||
if (!cp)
|
||||
return -ENOMEM;
|
||||
|
||||
strcpy(cp, symname);
|
||||
|
||||
inode = autofs_get_inode(dir->i_sb, S_IFLNK | 0555);
|
||||
if (!inode) {
|
||||
kfree(cp);
|
||||
return -ENOMEM;
|
||||
}
|
||||
inode->i_private = cp;
|
||||
inode->i_size = size;
|
||||
inode->i_size = strlen(cp);
|
||||
|
||||
d_make_persistent(dentry, inode);
|
||||
p_ino = autofs_dentry_ino(dentry->d_parent);
|
||||
|
||||
@@ -63,6 +63,9 @@
|
||||
|
||||
#include <trace/events/sched.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/coredump.h>
|
||||
|
||||
static bool dump_vma_snapshot(struct coredump_params *cprm);
|
||||
static void free_vma_snapshot(struct coredump_params *cprm);
|
||||
|
||||
@@ -1090,6 +1093,8 @@ static inline bool coredump_skip(const struct coredump_params *cprm,
|
||||
static void do_coredump(struct core_name *cn, struct coredump_params *cprm,
|
||||
size_t **argv, int *argc, const struct linux_binfmt *binfmt)
|
||||
{
|
||||
trace_coredump(cprm->siginfo->si_signo);
|
||||
|
||||
if (!coredump_parse(cn, cprm, argv, argc)) {
|
||||
coredump_report_failure("format_corename failed, aborting core");
|
||||
return;
|
||||
|
||||
11
fs/d_path.c
11
fs/d_path.c
@@ -301,18 +301,19 @@ EXPORT_SYMBOL(d_path);
|
||||
char *dynamic_dname(char *buffer, int buflen, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char temp[64];
|
||||
char *start;
|
||||
int sz;
|
||||
|
||||
va_start(args, fmt);
|
||||
sz = vsnprintf(temp, sizeof(temp), fmt, args) + 1;
|
||||
sz = vsnprintf(buffer, buflen, fmt, args) + 1;
|
||||
va_end(args);
|
||||
|
||||
if (sz > sizeof(temp) || sz > buflen)
|
||||
if (sz > NAME_MAX || sz > buflen)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
|
||||
buffer += buflen - sz;
|
||||
return memcpy(buffer, temp, sz);
|
||||
/* Move the formatted d_name to the end of the buffer. */
|
||||
start = buffer + (buflen - sz);
|
||||
return memmove(start, buffer, sz);
|
||||
}
|
||||
|
||||
char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
|
||||
|
||||
@@ -3257,7 +3257,7 @@ static void __init dcache_init_early(void)
|
||||
HASH_EARLY | HASH_ZERO,
|
||||
&d_hash_shift,
|
||||
NULL,
|
||||
0,
|
||||
2,
|
||||
0);
|
||||
d_hash_shift = 32 - d_hash_shift;
|
||||
|
||||
@@ -3289,7 +3289,7 @@ static void __init dcache_init(void)
|
||||
HASH_ZERO,
|
||||
&d_hash_shift,
|
||||
NULL,
|
||||
0,
|
||||
2,
|
||||
0);
|
||||
d_hash_shift = 32 - d_hash_shift;
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ static struct fdtable *alloc_fdtable(unsigned int slots_wanted)
|
||||
/*
|
||||
* Check if the allocation size would exceed INT_MAX. kvmalloc_array()
|
||||
* and kvmalloc() will warn if the allocation size is greater than
|
||||
* INT_MAX, as filp_cachep objects are not __GFP_NOWARN.
|
||||
* INT_MAX, as filp_cache objects are not __GFP_NOWARN.
|
||||
*
|
||||
* This can happen when sysctl_nr_open is set to a very high value and
|
||||
* a process tries to use a file descriptor near that limit. For example,
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
#include <linux/atomic.h>
|
||||
|
||||
#include <asm/runtime-const.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/* sysctl tunables... */
|
||||
@@ -38,8 +40,10 @@ static struct files_stat_struct files_stat = {
|
||||
};
|
||||
|
||||
/* SLAB cache for file structures */
|
||||
static struct kmem_cache *filp_cachep __ro_after_init;
|
||||
static struct kmem_cache *bfilp_cachep __ro_after_init;
|
||||
static struct kmem_cache *__filp_cache __ro_after_init;
|
||||
#define filp_cache runtime_const_ptr(__filp_cache)
|
||||
static struct kmem_cache *__bfilp_cache __ro_after_init;
|
||||
#define bfilp_cache runtime_const_ptr(__bfilp_cache)
|
||||
|
||||
static struct percpu_counter nr_files __cacheline_aligned_in_smp;
|
||||
|
||||
@@ -74,9 +78,9 @@ static inline void file_free(struct file *f)
|
||||
put_cred(f->f_cred);
|
||||
if (unlikely(f->f_mode & FMODE_BACKING)) {
|
||||
path_put(backing_file_user_path(f));
|
||||
kmem_cache_free(bfilp_cachep, backing_file(f));
|
||||
kmem_cache_free(bfilp_cache, backing_file(f));
|
||||
} else {
|
||||
kmem_cache_free(filp_cachep, f);
|
||||
kmem_cache_free(filp_cache, f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,13 +238,13 @@ struct file *alloc_empty_file(int flags, const struct cred *cred)
|
||||
goto over;
|
||||
}
|
||||
|
||||
f = kmem_cache_alloc(filp_cachep, GFP_KERNEL);
|
||||
f = kmem_cache_alloc(filp_cache, GFP_KERNEL);
|
||||
if (unlikely(!f))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
error = init_file(f, flags, cred);
|
||||
if (unlikely(error)) {
|
||||
kmem_cache_free(filp_cachep, f);
|
||||
kmem_cache_free(filp_cache, f);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
@@ -268,13 +272,13 @@ struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred)
|
||||
struct file *f;
|
||||
int error;
|
||||
|
||||
f = kmem_cache_alloc(filp_cachep, GFP_KERNEL);
|
||||
f = kmem_cache_alloc(filp_cache, GFP_KERNEL);
|
||||
if (unlikely(!f))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
error = init_file(f, flags, cred);
|
||||
if (unlikely(error)) {
|
||||
kmem_cache_free(filp_cachep, f);
|
||||
kmem_cache_free(filp_cache, f);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
@@ -295,13 +299,13 @@ struct file *alloc_empty_backing_file(int flags, const struct cred *cred)
|
||||
struct backing_file *ff;
|
||||
int error;
|
||||
|
||||
ff = kmem_cache_alloc(bfilp_cachep, GFP_KERNEL);
|
||||
ff = kmem_cache_alloc(bfilp_cache, GFP_KERNEL);
|
||||
if (unlikely(!ff))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
error = init_file(&ff->file, flags, cred);
|
||||
if (unlikely(error)) {
|
||||
kmem_cache_free(bfilp_cachep, ff);
|
||||
kmem_cache_free(bfilp_cache, ff);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
@@ -593,14 +597,17 @@ void __init files_init(void)
|
||||
.freeptr_offset = offsetof(struct file, f_freeptr),
|
||||
};
|
||||
|
||||
filp_cachep = kmem_cache_create("filp", sizeof(struct file), &args,
|
||||
__filp_cache = kmem_cache_create("filp", sizeof(struct file), &args,
|
||||
SLAB_HWCACHE_ALIGN | SLAB_PANIC |
|
||||
SLAB_ACCOUNT | SLAB_TYPESAFE_BY_RCU);
|
||||
runtime_const_init(ptr, __filp_cache);
|
||||
|
||||
args.freeptr_offset = offsetof(struct backing_file, bf_freeptr);
|
||||
bfilp_cachep = kmem_cache_create("bfilp", sizeof(struct backing_file),
|
||||
__bfilp_cache = kmem_cache_create("bfilp", sizeof(struct backing_file),
|
||||
&args, SLAB_HWCACHE_ALIGN | SLAB_PANIC |
|
||||
SLAB_ACCOUNT | SLAB_TYPESAFE_BY_RCU);
|
||||
runtime_const_init(ptr, __bfilp_cache);
|
||||
|
||||
percpu_counter_init(&nr_files, 0, GFP_KERNEL);
|
||||
}
|
||||
|
||||
|
||||
@@ -318,7 +318,6 @@ struct fs_context *fs_context_for_reconfigure(struct dentry *dentry,
|
||||
return alloc_fs_context(dentry->d_sb->s_type, dentry, sb_flags,
|
||||
sb_flags_mask, FS_CONTEXT_FOR_RECONFIGURE);
|
||||
}
|
||||
EXPORT_SYMBOL(fs_context_for_reconfigure);
|
||||
|
||||
/**
|
||||
* fs_context_for_submount: allocate a new fs_context for a submount
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <linux/namei.h>
|
||||
#include "internal.h"
|
||||
|
||||
const struct constant_table bool_names[] = {
|
||||
static const struct constant_table bool_names[] = {
|
||||
{ "0", false },
|
||||
{ "1", true },
|
||||
{ "false", false },
|
||||
@@ -22,7 +22,6 @@ const struct constant_table bool_names[] = {
|
||||
{ "yes", true },
|
||||
{ },
|
||||
};
|
||||
EXPORT_SYMBOL(bool_names);
|
||||
|
||||
static const struct constant_table *
|
||||
__lookup_constant(const struct constant_table *tbl, const char *name)
|
||||
@@ -278,15 +277,6 @@ int fs_param_is_string(struct p_log *log, const struct fs_parameter_spec *p,
|
||||
}
|
||||
EXPORT_SYMBOL(fs_param_is_string);
|
||||
|
||||
int fs_param_is_blob(struct p_log *log, const struct fs_parameter_spec *p,
|
||||
struct fs_parameter *param, struct fs_parse_result *result)
|
||||
{
|
||||
if (param->type != fs_value_is_blob)
|
||||
return fs_param_bad_value(log, param);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(fs_param_is_blob);
|
||||
|
||||
int fs_param_is_fd(struct p_log *log, const struct fs_parameter_spec *p,
|
||||
struct fs_parameter *param, struct fs_parse_result *result)
|
||||
{
|
||||
@@ -371,13 +361,6 @@ int fs_param_is_blockdev(struct p_log *log, const struct fs_parameter_spec *p,
|
||||
}
|
||||
EXPORT_SYMBOL(fs_param_is_blockdev);
|
||||
|
||||
int fs_param_is_path(struct p_log *log, const struct fs_parameter_spec *p,
|
||||
struct fs_parameter *param, struct fs_parse_result *result)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(fs_param_is_path);
|
||||
|
||||
#ifdef CONFIG_VALIDATE_FS_PARSER
|
||||
/**
|
||||
* fs_validate_description - Validate a parameter specification array
|
||||
|
||||
@@ -622,23 +622,6 @@ static int hfs_file_release(struct inode *inode, struct file *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* hfs_notify_change()
|
||||
*
|
||||
* Based very closely on fs/msdos/inode.c by Werner Almesberger
|
||||
*
|
||||
* This is the notify_change() field in the super_operations structure
|
||||
* for HFS file systems. The purpose is to take that changes made to
|
||||
* an inode and apply then in a filesystem-dependent manner. In this
|
||||
* case the process has a few of tasks to do:
|
||||
* 1) prevent changes to the i_uid and i_gid fields.
|
||||
* 2) map file permissions to the closest allowable permissions
|
||||
* 3) Since multiple Linux files can share the same on-disk inode under
|
||||
* HFS (for instance the data and resource forks of a file) a change
|
||||
* to permissions must be applied to all other in-core inodes which
|
||||
* correspond to the same HFS file.
|
||||
*/
|
||||
|
||||
int hfs_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *attr)
|
||||
{
|
||||
@@ -646,8 +629,7 @@ int hfs_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
|
||||
int error;
|
||||
|
||||
error = setattr_prepare(&nop_mnt_idmap, dentry,
|
||||
attr); /* basic permission checks */
|
||||
error = setattr_prepare(&nop_mnt_idmap, dentry, attr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -663,6 +645,7 @@ int hfs_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
return hsb->s_quiet ? 0 : error;
|
||||
}
|
||||
|
||||
/* map file permissions to the closest allowable permissions in HFS */
|
||||
if (attr->ia_valid & ATTR_MODE) {
|
||||
/* Only the 'w' bits can ever change and only all together. */
|
||||
if (attr->ia_mode & S_IWUSR)
|
||||
|
||||
@@ -198,8 +198,7 @@ extern struct open_how build_open_how(int flags, umode_t mode);
|
||||
extern int build_open_flags(const struct open_how *how, struct open_flags *op);
|
||||
struct file *file_close_fd_locked(struct files_struct *files, unsigned fd);
|
||||
|
||||
int do_ftruncate(struct file *file, loff_t length, int small);
|
||||
int do_sys_ftruncate(unsigned int fd, loff_t length, int small);
|
||||
int do_ftruncate(struct file *file, loff_t length, unsigned int flags);
|
||||
int chmod_common(const struct path *path, umode_t mode);
|
||||
int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
|
||||
int flag);
|
||||
|
||||
@@ -406,6 +406,7 @@ void mb_cache_destroy(struct mb_cache *cache)
|
||||
{
|
||||
struct mb_cache_entry *entry, *next;
|
||||
|
||||
cancel_work_sync(&cache->c_shrink_work);
|
||||
shrinker_free(cache->c_shrink);
|
||||
|
||||
/*
|
||||
|
||||
@@ -2140,7 +2140,7 @@ static __always_inline const char *step_into(struct nameidata *nd, int flags,
|
||||
if (unlikely(!inode))
|
||||
return ERR_PTR(-ENOENT);
|
||||
nd->path.dentry = dentry;
|
||||
/* nd->path.mnt is retained on purpose */
|
||||
/* nd->path.mnt remains unchanged as no mount point was crossed */
|
||||
nd->inode = inode;
|
||||
nd->seq = nd->next_seq;
|
||||
return NULL;
|
||||
|
||||
@@ -513,6 +513,12 @@ static int omfs_fill_super(struct super_block *sb, struct fs_context *fc)
|
||||
goto out_brelse_bh;
|
||||
}
|
||||
|
||||
if (sbi->s_sys_blocksize < OMFS_DIR_START) {
|
||||
printk(KERN_ERR "omfs: sysblock size (%d) is too small\n",
|
||||
sbi->s_sys_blocksize);
|
||||
goto out_brelse_bh;
|
||||
}
|
||||
|
||||
if (sbi->s_blocksize < sbi->s_sys_blocksize ||
|
||||
sbi->s_blocksize > OMFS_MAX_BLOCK_SIZE) {
|
||||
printk(KERN_ERR "omfs: block size (%d) is out of range\n",
|
||||
|
||||
40
fs/open.c
40
fs/open.c
@@ -126,7 +126,7 @@ mnt_drop_write_and_out:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfs_truncate);
|
||||
|
||||
int do_sys_truncate(const char __user *pathname, loff_t length)
|
||||
int ksys_truncate(const char __user *pathname, loff_t length)
|
||||
{
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
struct path path;
|
||||
@@ -151,33 +151,31 @@ retry:
|
||||
|
||||
SYSCALL_DEFINE2(truncate, const char __user *, path, long, length)
|
||||
{
|
||||
return do_sys_truncate(path, length);
|
||||
return ksys_truncate(path, length);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
COMPAT_SYSCALL_DEFINE2(truncate, const char __user *, path, compat_off_t, length)
|
||||
{
|
||||
return do_sys_truncate(path, length);
|
||||
return ksys_truncate(path, length);
|
||||
}
|
||||
#endif
|
||||
|
||||
int do_ftruncate(struct file *file, loff_t length, int small)
|
||||
int do_ftruncate(struct file *file, loff_t length, unsigned int flags)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct dentry *dentry;
|
||||
struct dentry *dentry = file->f_path.dentry;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
|
||||
/* explicitly opened as large or we are on 64-bit box */
|
||||
if (file->f_flags & O_LARGEFILE)
|
||||
small = 0;
|
||||
|
||||
dentry = file->f_path.dentry;
|
||||
inode = dentry->d_inode;
|
||||
if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
|
||||
return -EINVAL;
|
||||
|
||||
/* Cannot ftruncate over 2^31 bytes without large file support */
|
||||
if (small && length > MAX_NON_LFS)
|
||||
/*
|
||||
* Cannot ftruncate over 2^31 bytes without large file support, either
|
||||
* through opening with O_LARGEFILE or by using ftruncate64().
|
||||
*/
|
||||
if (length > MAX_NON_LFS &&
|
||||
!(file->f_flags & O_LARGEFILE) && !(flags & FTRUNCATE_LFS))
|
||||
return -EINVAL;
|
||||
|
||||
/* Check IS_APPEND on real upper inode */
|
||||
@@ -197,7 +195,7 @@ int do_ftruncate(struct file *file, loff_t length, int small)
|
||||
ATTR_MTIME | ATTR_CTIME, file);
|
||||
}
|
||||
|
||||
int do_sys_ftruncate(unsigned int fd, loff_t length, int small)
|
||||
int ksys_ftruncate(unsigned int fd, loff_t length, unsigned int flags)
|
||||
{
|
||||
if (length < 0)
|
||||
return -EINVAL;
|
||||
@@ -205,18 +203,18 @@ int do_sys_ftruncate(unsigned int fd, loff_t length, int small)
|
||||
if (fd_empty(f))
|
||||
return -EBADF;
|
||||
|
||||
return do_ftruncate(fd_file(f), length, small);
|
||||
return do_ftruncate(fd_file(f), length, flags);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE2(ftruncate, unsigned int, fd, off_t, length)
|
||||
{
|
||||
return do_sys_ftruncate(fd, length, 1);
|
||||
return ksys_ftruncate(fd, length, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_off_t, length)
|
||||
{
|
||||
return do_sys_ftruncate(fd, length, 1);
|
||||
return ksys_ftruncate(fd, length, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -224,12 +222,12 @@ COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_off_t, length)
|
||||
#if BITS_PER_LONG == 32
|
||||
SYSCALL_DEFINE2(truncate64, const char __user *, path, loff_t, length)
|
||||
{
|
||||
return do_sys_truncate(path, length);
|
||||
return ksys_truncate(path, length);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length)
|
||||
{
|
||||
return do_sys_ftruncate(fd, length, 0);
|
||||
return ksys_ftruncate(fd, length, FTRUNCATE_LFS);
|
||||
}
|
||||
#endif /* BITS_PER_LONG == 32 */
|
||||
|
||||
@@ -245,7 +243,7 @@ COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, pathname,
|
||||
COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd,
|
||||
compat_arg_u64_dual(length))
|
||||
{
|
||||
return ksys_ftruncate(fd, compat_arg_u64_glue(length));
|
||||
return ksys_ftruncate(fd, compat_arg_u64_glue(length), FTRUNCATE_LFS);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -721,7 +721,7 @@ static bool proc_fd_access_allowed(struct inode *inode)
|
||||
return allowed;
|
||||
}
|
||||
|
||||
int proc_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
int proc_nochmod_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *attr)
|
||||
{
|
||||
int error;
|
||||
@@ -794,7 +794,7 @@ static int proc_pid_permission(struct mnt_idmap *idmap,
|
||||
|
||||
|
||||
static const struct inode_operations proc_def_inode_operations = {
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
static int proc_single_show(struct seq_file *m, void *v)
|
||||
@@ -1866,7 +1866,7 @@ out:
|
||||
const struct inode_operations proc_pid_link_inode_operations = {
|
||||
.readlink = proc_pid_readlink,
|
||||
.get_link = proc_pid_get_link,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
|
||||
@@ -2319,7 +2319,7 @@ proc_map_files_get_link(struct dentry *dentry,
|
||||
static const struct inode_operations proc_map_files_link_inode_operations = {
|
||||
.readlink = proc_pid_readlink,
|
||||
.get_link = proc_map_files_get_link,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
static struct dentry *
|
||||
@@ -2398,7 +2398,7 @@ out:
|
||||
static const struct inode_operations proc_map_files_inode_operations = {
|
||||
.lookup = proc_map_files_lookup,
|
||||
.permission = proc_fd_permission,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -2885,7 +2885,7 @@ static struct dentry *proc_##LSM##_attr_dir_lookup(struct inode *dir, \
|
||||
static const struct inode_operations proc_##LSM##_attr_dir_inode_ops = { \
|
||||
.lookup = proc_##LSM##_attr_dir_lookup, \
|
||||
.getattr = pid_getattr, \
|
||||
.setattr = proc_setattr, \
|
||||
.setattr = proc_nochmod_setattr, \
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURITY_SMACK
|
||||
@@ -2944,7 +2944,7 @@ static struct dentry *proc_attr_dir_lookup(struct inode *dir,
|
||||
static const struct inode_operations proc_attr_dir_inode_operations = {
|
||||
.lookup = proc_attr_dir_lookup,
|
||||
.getattr = pid_getattr,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -3453,7 +3453,7 @@ static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *de
|
||||
static const struct inode_operations proc_tgid_base_inode_operations = {
|
||||
.lookup = proc_tgid_base_lookup,
|
||||
.getattr = pid_getattr,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
.permission = proc_pid_permission,
|
||||
};
|
||||
|
||||
@@ -3650,7 +3650,7 @@ static int proc_tid_comm_permission(struct mnt_idmap *idmap,
|
||||
}
|
||||
|
||||
static const struct inode_operations proc_tid_comm_inode_operations = {
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
.permission = proc_tid_comm_permission,
|
||||
};
|
||||
|
||||
@@ -3779,7 +3779,7 @@ static const struct file_operations proc_tid_base_operations = {
|
||||
static const struct inode_operations proc_tid_base_inode_operations = {
|
||||
.lookup = proc_tid_base_lookup,
|
||||
.getattr = pid_getattr,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
static struct dentry *proc_task_instantiate(struct dentry *dentry,
|
||||
@@ -3992,7 +3992,7 @@ static loff_t proc_dir_llseek(struct file *file, loff_t offset, int whence)
|
||||
static const struct inode_operations proc_task_inode_operations = {
|
||||
.lookup = proc_task_lookup,
|
||||
.getattr = proc_task_getattr,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
.permission = proc_pid_permission,
|
||||
};
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ static int proc_fdinfo_permission(struct mnt_idmap *idmap, struct inode *inode,
|
||||
|
||||
static const struct inode_operations proc_fdinfo_file_inode_operations = {
|
||||
.permission = proc_fdinfo_permission,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
static const struct file_operations proc_fdinfo_file_operations = {
|
||||
@@ -361,7 +361,7 @@ const struct inode_operations proc_fd_inode_operations = {
|
||||
.lookup = proc_lookupfd,
|
||||
.permission = proc_fd_permission,
|
||||
.getattr = proc_fd_getattr,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
static struct dentry *proc_fdinfo_instantiate(struct dentry *dentry,
|
||||
@@ -402,7 +402,7 @@ static int proc_fdinfo_iterate(struct file *file, struct dir_context *ctx)
|
||||
const struct inode_operations proc_fdinfo_inode_operations = {
|
||||
.lookup = proc_lookupfdinfo,
|
||||
.permission = proc_fdinfo_permission,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
const struct file_operations proc_fdinfo_operations = {
|
||||
|
||||
@@ -115,8 +115,8 @@ static bool pde_subdir_insert(struct proc_dir_entry *dir,
|
||||
return true;
|
||||
}
|
||||
|
||||
static int proc_notify_change(struct mnt_idmap *idmap,
|
||||
struct dentry *dentry, struct iattr *iattr)
|
||||
static int proc_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *iattr)
|
||||
{
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct proc_dir_entry *de = PDE(inode);
|
||||
@@ -151,7 +151,7 @@ static int proc_getattr(struct mnt_idmap *idmap,
|
||||
}
|
||||
|
||||
static const struct inode_operations proc_file_inode_operations = {
|
||||
.setattr = proc_notify_change,
|
||||
.setattr = proc_setattr,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -364,7 +364,7 @@ const struct dentry_operations proc_net_dentry_ops = {
|
||||
static const struct inode_operations proc_dir_inode_operations = {
|
||||
.lookup = proc_lookup,
|
||||
.getattr = proc_getattr,
|
||||
.setattr = proc_notify_change,
|
||||
.setattr = proc_setattr,
|
||||
};
|
||||
|
||||
static void pde_set_flags(struct proc_dir_entry *pde)
|
||||
|
||||
@@ -257,8 +257,8 @@ extern int proc_pid_statm(struct seq_file *, struct pid_namespace *,
|
||||
extern const struct dentry_operations pid_dentry_operations;
|
||||
extern int pid_getattr(struct mnt_idmap *, const struct path *,
|
||||
struct kstat *, u32, unsigned int);
|
||||
extern int proc_setattr(struct mnt_idmap *, struct dentry *,
|
||||
struct iattr *);
|
||||
int proc_nochmod_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *attr);
|
||||
extern void proc_pid_evict_inode(struct proc_inode *);
|
||||
extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *, umode_t);
|
||||
extern void pid_update_inode(struct task_struct *, struct inode *);
|
||||
|
||||
@@ -92,7 +92,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl
|
||||
static const struct inode_operations proc_ns_link_inode_operations = {
|
||||
.readlink = proc_ns_readlink,
|
||||
.get_link = proc_ns_get_link,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
static struct dentry *proc_ns_instantiate(struct dentry *dentry,
|
||||
@@ -178,5 +178,5 @@ out_no_task:
|
||||
const struct inode_operations proc_ns_dir_inode_operations = {
|
||||
.lookup = proc_ns_dir_lookup,
|
||||
.getattr = pid_getattr,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
@@ -322,7 +322,7 @@ static int proc_tgid_net_getattr(struct mnt_idmap *idmap,
|
||||
const struct inode_operations proc_net_inode_operations = {
|
||||
.lookup = proc_tgid_net_lookup,
|
||||
.getattr = proc_tgid_net_getattr,
|
||||
.setattr = proc_setattr,
|
||||
.setattr = proc_nochmod_setattr,
|
||||
};
|
||||
|
||||
static int proc_tgid_net_readdir(struct file *file, struct dir_context *ctx)
|
||||
|
||||
103
fs/readdir.c
103
fs/readdir.c
@@ -22,6 +22,8 @@
|
||||
#include <linux/compat.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define dirent_size(dirent, len) offsetof(typeof(*(dirent)), d_name[len])
|
||||
|
||||
/*
|
||||
* Some filesystems were never converted to '->iterate_shared()'
|
||||
* and their directory iterators want the inode lock held for
|
||||
@@ -198,18 +200,13 @@ static bool fillonedir(struct dir_context *ctx, const char *name, int namlen,
|
||||
}
|
||||
buf->result++;
|
||||
dirent = buf->dirent;
|
||||
if (!user_write_access_begin(dirent,
|
||||
(unsigned long)(dirent->d_name + namlen + 1) -
|
||||
(unsigned long)dirent))
|
||||
goto efault;
|
||||
unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
|
||||
unsafe_put_user(offset, &dirent->d_offset, efault_end);
|
||||
unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
|
||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
|
||||
user_write_access_end();
|
||||
scoped_user_write_access_size(dirent, dirent_size(dirent, namlen + 1), efault) {
|
||||
unsafe_put_user(d_ino, &dirent->d_ino, efault);
|
||||
unsafe_put_user(offset, &dirent->d_offset, efault);
|
||||
unsafe_put_user(namlen, &dirent->d_namlen, efault);
|
||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault);
|
||||
}
|
||||
return true;
|
||||
efault_end:
|
||||
user_write_access_end();
|
||||
efault:
|
||||
buf->result = -EFAULT;
|
||||
return false;
|
||||
@@ -263,8 +260,7 @@ static bool filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||
struct getdents_callback *buf =
|
||||
container_of(ctx, struct getdents_callback, ctx);
|
||||
unsigned long d_ino;
|
||||
int reclen = ALIGN(offsetof(struct linux_dirent, d_name) + namlen + 2,
|
||||
sizeof(long));
|
||||
int reclen = ALIGN(dirent_size(dirent, namlen + 2), sizeof(long));
|
||||
int prev_reclen;
|
||||
unsigned int flags = d_type;
|
||||
|
||||
@@ -287,23 +283,19 @@ static bool filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||
return false;
|
||||
dirent = buf->current_dir;
|
||||
prev = (void __user *) dirent - prev_reclen;
|
||||
if (!user_write_access_begin(prev, reclen + prev_reclen))
|
||||
goto efault;
|
||||
|
||||
/* This might be 'dirent->d_off', but if so it will get overwritten */
|
||||
unsafe_put_user(offset, &prev->d_off, efault_end);
|
||||
unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
|
||||
unsafe_put_user(reclen, &dirent->d_reclen, efault_end);
|
||||
unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end);
|
||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
|
||||
user_write_access_end();
|
||||
scoped_user_write_access_size(prev, reclen + prev_reclen, efault) {
|
||||
/* This might be 'dirent->d_off', but if so it will get overwritten */
|
||||
unsafe_put_user(offset, &prev->d_off, efault);
|
||||
unsafe_put_user(d_ino, &dirent->d_ino, efault);
|
||||
unsafe_put_user(reclen, &dirent->d_reclen, efault);
|
||||
unsafe_put_user(d_type, (char __user *)dirent + reclen - 1, efault);
|
||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault);
|
||||
}
|
||||
|
||||
buf->current_dir = (void __user *)dirent + reclen;
|
||||
buf->prev_reclen = reclen;
|
||||
ctx->count -= reclen;
|
||||
return true;
|
||||
efault_end:
|
||||
user_write_access_end();
|
||||
efault:
|
||||
buf->error = -EFAULT;
|
||||
return false;
|
||||
@@ -352,8 +344,7 @@ static bool filldir64(struct dir_context *ctx, const char *name, int namlen,
|
||||
struct linux_dirent64 __user *dirent, *prev;
|
||||
struct getdents_callback64 *buf =
|
||||
container_of(ctx, struct getdents_callback64, ctx);
|
||||
int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1,
|
||||
sizeof(u64));
|
||||
int reclen = ALIGN(dirent_size(dirent, namlen + 1), sizeof(u64));
|
||||
int prev_reclen;
|
||||
unsigned int flags = d_type;
|
||||
|
||||
@@ -371,24 +362,20 @@ static bool filldir64(struct dir_context *ctx, const char *name, int namlen,
|
||||
return false;
|
||||
dirent = buf->current_dir;
|
||||
prev = (void __user *)dirent - prev_reclen;
|
||||
if (!user_write_access_begin(prev, reclen + prev_reclen))
|
||||
goto efault;
|
||||
|
||||
/* This might be 'dirent->d_off', but if so it will get overwritten */
|
||||
unsafe_put_user(offset, &prev->d_off, efault_end);
|
||||
unsafe_put_user(ino, &dirent->d_ino, efault_end);
|
||||
unsafe_put_user(reclen, &dirent->d_reclen, efault_end);
|
||||
unsafe_put_user(d_type, &dirent->d_type, efault_end);
|
||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
|
||||
user_write_access_end();
|
||||
scoped_user_write_access_size(prev, reclen + prev_reclen, efault) {
|
||||
/* This might be 'dirent->d_off', but if so it will get overwritten */
|
||||
unsafe_put_user(offset, &prev->d_off, efault);
|
||||
unsafe_put_user(ino, &dirent->d_ino, efault);
|
||||
unsafe_put_user(reclen, &dirent->d_reclen, efault);
|
||||
unsafe_put_user(d_type, &dirent->d_type, efault);
|
||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault);
|
||||
}
|
||||
|
||||
buf->prev_reclen = reclen;
|
||||
buf->current_dir = (void __user *)dirent + reclen;
|
||||
ctx->count -= reclen;
|
||||
return true;
|
||||
|
||||
efault_end:
|
||||
user_write_access_end();
|
||||
efault:
|
||||
buf->error = -EFAULT;
|
||||
return false;
|
||||
@@ -460,18 +447,13 @@ static bool compat_fillonedir(struct dir_context *ctx, const char *name,
|
||||
}
|
||||
buf->result++;
|
||||
dirent = buf->dirent;
|
||||
if (!user_write_access_begin(dirent,
|
||||
(unsigned long)(dirent->d_name + namlen + 1) -
|
||||
(unsigned long)dirent))
|
||||
goto efault;
|
||||
unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
|
||||
unsafe_put_user(offset, &dirent->d_offset, efault_end);
|
||||
unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
|
||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
|
||||
user_write_access_end();
|
||||
scoped_user_write_access_size(dirent, dirent_size(dirent, namlen + 1), efault) {
|
||||
unsafe_put_user(d_ino, &dirent->d_ino, efault);
|
||||
unsafe_put_user(offset, &dirent->d_offset, efault);
|
||||
unsafe_put_user(namlen, &dirent->d_namlen, efault);
|
||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault);
|
||||
}
|
||||
return true;
|
||||
efault_end:
|
||||
user_write_access_end();
|
||||
efault:
|
||||
buf->result = -EFAULT;
|
||||
return false;
|
||||
@@ -519,8 +501,7 @@ static bool compat_filldir(struct dir_context *ctx, const char *name, int namlen
|
||||
struct compat_getdents_callback *buf =
|
||||
container_of(ctx, struct compat_getdents_callback, ctx);
|
||||
compat_ulong_t d_ino;
|
||||
int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) +
|
||||
namlen + 2, sizeof(compat_long_t));
|
||||
int reclen = ALIGN(dirent_size(dirent, namlen + 2), sizeof(compat_long_t));
|
||||
int prev_reclen;
|
||||
unsigned int flags = d_type;
|
||||
|
||||
@@ -543,22 +524,18 @@ static bool compat_filldir(struct dir_context *ctx, const char *name, int namlen
|
||||
return false;
|
||||
dirent = buf->current_dir;
|
||||
prev = (void __user *) dirent - prev_reclen;
|
||||
if (!user_write_access_begin(prev, reclen + prev_reclen))
|
||||
goto efault;
|
||||
|
||||
unsafe_put_user(offset, &prev->d_off, efault_end);
|
||||
unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
|
||||
unsafe_put_user(reclen, &dirent->d_reclen, efault_end);
|
||||
unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end);
|
||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
|
||||
user_write_access_end();
|
||||
scoped_user_write_access_size(prev, reclen + prev_reclen, efault) {
|
||||
unsafe_put_user(offset, &prev->d_off, efault);
|
||||
unsafe_put_user(d_ino, &dirent->d_ino, efault);
|
||||
unsafe_put_user(reclen, &dirent->d_reclen, efault);
|
||||
unsafe_put_user(d_type, (char __user *)dirent + reclen - 1, efault);
|
||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault);
|
||||
}
|
||||
|
||||
buf->prev_reclen = reclen;
|
||||
buf->current_dir = (void __user *)dirent + reclen;
|
||||
ctx->count -= reclen;
|
||||
return true;
|
||||
efault_end:
|
||||
user_write_access_end();
|
||||
efault:
|
||||
buf->error = -EFAULT;
|
||||
return false;
|
||||
|
||||
35
fs/select.c
35
fs/select.c
@@ -1004,17 +1004,17 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
|
||||
fdcount = do_poll(head, &table, end_time);
|
||||
poll_freewait(&table);
|
||||
|
||||
if (!user_write_access_begin(ufds, nfds * sizeof(*ufds)))
|
||||
goto out_fds;
|
||||
scoped_user_write_access_size(ufds, nfds * sizeof(*ufds), out_fds) {
|
||||
struct pollfd __user *_ufds = ufds;
|
||||
|
||||
for (walk = head; walk; walk = walk->next) {
|
||||
struct pollfd *fds = walk->entries;
|
||||
unsigned int j;
|
||||
for (walk = head; walk; walk = walk->next) {
|
||||
struct pollfd *fds = walk->entries;
|
||||
unsigned int j;
|
||||
|
||||
for (j = walk->len; j; fds++, ufds++, j--)
|
||||
unsafe_put_user(fds->revents, &ufds->revents, Efault);
|
||||
}
|
||||
user_write_access_end();
|
||||
for (j = walk->len; j; fds++, _ufds++, j--)
|
||||
unsafe_put_user(fds->revents, &_ufds->revents, out_fds);
|
||||
}
|
||||
}
|
||||
|
||||
err = fdcount;
|
||||
out_fds:
|
||||
@@ -1026,11 +1026,6 @@ out_fds:
|
||||
}
|
||||
|
||||
return err;
|
||||
|
||||
Efault:
|
||||
user_write_access_end();
|
||||
err = -EFAULT;
|
||||
goto out_fds;
|
||||
}
|
||||
|
||||
static long do_restart_poll(struct restart_block *restart_block)
|
||||
@@ -1338,15 +1333,13 @@ static inline int get_compat_sigset_argpack(struct compat_sigset_argpack *to,
|
||||
struct compat_sigset_argpack __user *from)
|
||||
{
|
||||
if (from) {
|
||||
if (!user_read_access_begin(from, sizeof(*from)))
|
||||
return -EFAULT;
|
||||
unsafe_get_user(to->p, &from->p, Efault);
|
||||
unsafe_get_user(to->size, &from->size, Efault);
|
||||
user_read_access_end();
|
||||
scoped_user_read_access(from, efault) {
|
||||
unsafe_get_user(to->p, &from->p, efault);
|
||||
unsafe_get_user(to->size, &from->size, efault);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
Efault:
|
||||
user_read_access_end();
|
||||
efault:
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
||||
@@ -975,7 +975,9 @@
|
||||
RUNTIME_CONST(shift, d_hash_shift) \
|
||||
RUNTIME_CONST(ptr, dentry_hashtable) \
|
||||
RUNTIME_CONST(ptr, __dentry_cache) \
|
||||
RUNTIME_CONST(ptr, __names_cache)
|
||||
RUNTIME_CONST(ptr, __names_cache) \
|
||||
RUNTIME_CONST(ptr, __filp_cache) \
|
||||
RUNTIME_CONST(ptr, __bfilp_cache)
|
||||
|
||||
/* Alignment must be consistent with (kunit_suite *) in include/kunit/test.h */
|
||||
#define KUNIT_TABLE() \
|
||||
|
||||
@@ -237,7 +237,7 @@ static inline void wb_get(struct bdi_writeback *wb)
|
||||
}
|
||||
|
||||
/**
|
||||
* wb_put - decrement a wb's refcount
|
||||
* wb_put_many - decrement a wb's refcount
|
||||
* @wb: bdi_writeback to put
|
||||
* @nr: number of references to put
|
||||
*/
|
||||
|
||||
@@ -38,6 +38,7 @@ struct blk_flush_queue;
|
||||
struct kiocb;
|
||||
struct pr_ops;
|
||||
struct rq_qos;
|
||||
struct hd_geometry;
|
||||
struct blk_report_zones_args;
|
||||
struct blk_queue_stats;
|
||||
struct blk_stat_callback;
|
||||
|
||||
@@ -55,8 +55,6 @@ struct bdi_writeback;
|
||||
struct bio;
|
||||
struct io_comp_batch;
|
||||
struct fiemap_extent_info;
|
||||
struct hd_geometry;
|
||||
struct iovec;
|
||||
struct kiocb;
|
||||
struct kobject;
|
||||
struct pipe_inode_info;
|
||||
@@ -1920,7 +1918,6 @@ struct dir_context {
|
||||
*/
|
||||
#define COPY_FILE_SPLICE (1 << 0)
|
||||
|
||||
struct iov_iter;
|
||||
struct io_uring_cmd;
|
||||
struct offset_ctx;
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ typedef int fs_param_type(struct p_log *,
|
||||
* The type of parameter expected.
|
||||
*/
|
||||
fs_param_type fs_param_is_bool, fs_param_is_u32, fs_param_is_s32, fs_param_is_u64,
|
||||
fs_param_is_enum, fs_param_is_string, fs_param_is_blob, fs_param_is_blockdev,
|
||||
fs_param_is_path, fs_param_is_fd, fs_param_is_uid, fs_param_is_gid,
|
||||
fs_param_is_enum, fs_param_is_string, fs_param_is_blockdev,
|
||||
fs_param_is_fd, fs_param_is_uid, fs_param_is_gid,
|
||||
fs_param_is_file_or_string;
|
||||
|
||||
/*
|
||||
@@ -84,8 +84,6 @@ extern int fs_lookup_param(struct fs_context *fc,
|
||||
|
||||
extern int lookup_constant(const struct constant_table tbl[], const char *name, int not_found);
|
||||
|
||||
extern const struct constant_table bool_names[];
|
||||
|
||||
#ifdef CONFIG_VALIDATE_FS_PARSER
|
||||
extern bool fs_validate_description(const char *name,
|
||||
const struct fs_parameter_spec *desc);
|
||||
@@ -127,9 +125,7 @@ static inline bool fs_validate_description(const char *name,
|
||||
#define fsparam_enum(NAME, OPT, array) __fsparam(fs_param_is_enum, NAME, OPT, 0, array)
|
||||
#define fsparam_string(NAME, OPT) \
|
||||
__fsparam(fs_param_is_string, NAME, OPT, 0, NULL)
|
||||
#define fsparam_blob(NAME, OPT) __fsparam(fs_param_is_blob, NAME, OPT, 0, NULL)
|
||||
#define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0, NULL)
|
||||
#define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0, NULL)
|
||||
#define fsparam_fd(NAME, OPT) __fsparam(fs_param_is_fd, NAME, OPT, 0, NULL)
|
||||
#define fsparam_file_or_string(NAME, OPT) \
|
||||
__fsparam(fs_param_is_file_or_string, NAME, OPT, 0, NULL)
|
||||
|
||||
@@ -1283,19 +1283,9 @@ static inline long ksys_lchown(const char __user *filename, uid_t user,
|
||||
AT_SYMLINK_NOFOLLOW);
|
||||
}
|
||||
|
||||
int do_sys_ftruncate(unsigned int fd, loff_t length, int small);
|
||||
|
||||
static inline long ksys_ftruncate(unsigned int fd, loff_t length)
|
||||
{
|
||||
return do_sys_ftruncate(fd, length, 1);
|
||||
}
|
||||
|
||||
int do_sys_truncate(const char __user *pathname, loff_t length);
|
||||
|
||||
static inline long ksys_truncate(const char __user *pathname, loff_t length)
|
||||
{
|
||||
return do_sys_truncate(pathname, length);
|
||||
}
|
||||
#define FTRUNCATE_LFS (1u << 0) /* allow truncating > 32-bit */
|
||||
int ksys_ftruncate(unsigned int fd, loff_t length, unsigned int flags);
|
||||
int ksys_truncate(const char __user *pathname, loff_t length);
|
||||
|
||||
static inline unsigned int ksys_personality(unsigned int personality)
|
||||
{
|
||||
|
||||
45
include/trace/events/coredump.h
Normal file
45
include/trace/events/coredump.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2026 Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) 2026 Breno Leitao <leitao@debian.org>
|
||||
*/
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM coredump
|
||||
|
||||
#if !defined(_TRACE_COREDUMP_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _TRACE_COREDUMP_H
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
/**
|
||||
* coredump - called when a coredump starts
|
||||
* @sig: signal number that triggered the coredump
|
||||
*
|
||||
* This tracepoint fires at the beginning of a coredump attempt,
|
||||
* providing a stable interface for monitoring coredump events.
|
||||
*/
|
||||
TRACE_EVENT(coredump,
|
||||
|
||||
TP_PROTO(int sig),
|
||||
|
||||
TP_ARGS(sig),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(int, sig)
|
||||
__array(char, comm, TASK_COMM_LEN)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->sig = sig;
|
||||
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
|
||||
),
|
||||
|
||||
TP_printk("sig=%d comm=%s",
|
||||
__entry->sig, __entry->comm)
|
||||
);
|
||||
|
||||
#endif /* _TRACE_COREDUMP_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
#include <trace/define_trace.h>
|
||||
@@ -212,7 +212,7 @@ static void __init parse_header(char *s)
|
||||
hdr_csum = parsed[12];
|
||||
}
|
||||
|
||||
/* FSM */
|
||||
/* Finite-state machine */
|
||||
|
||||
static __initdata enum state {
|
||||
Start,
|
||||
|
||||
@@ -41,7 +41,7 @@ int io_ftruncate(struct io_kiocb *req, unsigned int issue_flags)
|
||||
|
||||
WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
|
||||
|
||||
ret = do_ftruncate(req->file, ft->len, 1);
|
||||
ret = do_ftruncate(req->file, ft->len, 0);
|
||||
|
||||
io_req_set_res(req, ret, 0);
|
||||
return IOU_COMPLETE;
|
||||
|
||||
@@ -244,7 +244,7 @@ static int acct_on(const char __user *name)
|
||||
if (!S_ISREG(file_inode(file)->i_mode))
|
||||
return -EACCES;
|
||||
|
||||
/* Exclude kernel kernel internal filesystems. */
|
||||
/* Exclude kernel internal filesystems. */
|
||||
if (file_inode(file)->i_sb->s_flags & (SB_NOUSER | SB_KERNMOUNT))
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -119,9 +119,7 @@ static int do_tiocgptpeer(char *ptmx, char *expected_procfd_contents)
|
||||
goto do_cleanup;
|
||||
}
|
||||
|
||||
#ifdef TIOCGPTPEER
|
||||
slave = ioctl(master, TIOCGPTPEER, O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
#endif
|
||||
if (slave < 0) {
|
||||
if (errno == EINVAL) {
|
||||
fprintf(stderr, "TIOCGPTPEER is not supported. "
|
||||
|
||||
Reference in New Issue
Block a user