mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-22 07:53:11 -05:00
Summary
* sysctl ctl_table constification Constifying ctl_table structs prevents the modification of proc_handler function pointers. All ctl_table struct arguments are const qualified in the sysctl API in such a way that the ctl_table arrays being defined elsewhere and passed through sysctl can be constified one-by-one. We kick the constification off by qualifying user_table in kernel/ucount.c and expect all the ctl_tables to be constified in the coming releases. * Misc fixes Adjust comments in two places to better reflect the code. Remove superfluous dput calls. Remove Luis from sysctl maintainership. Replace comments about holding a lock with calls to lockdep_assert_held. * Testing All these went through 0-day and they have all been in linux-next for at least 1 month (since Oct-24). I also rand these through the sysctl selftest for x86_64. -----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEErkcJVyXmMSXOyyeQupfNUreWQU8FAmdAXMsACgkQupfNUreW QU/KfQv8Daq9sew98ohmS/lkdoE1dfpI72motzEn1993CbLjN2h3CZauaHjBPFnr rpr8qPrphdWTyDbDMgx63oxcNxM07g7a9H0y/K3IwdUsx7fGINgHF5kfWeVn09ov X8I3NuL/+xSHAZRsLQeBykbY6BD5e0uuxL6ayGzkejrgRd+80dmC3MzXqX207v1z rlrUFXEXwqKYgxP/H+pxmvmVWKAeFsQt/E49GOkg2qSg9mVFhtKpxHwMJVqS2a8u qAKHgcZhB5T8TQSb1eKnyCzXLDLpzqUBj9ejqJSsQm16fweawv221Ji6a1k53QYG chreoB9R8qCZ/jGoWI3ZKGRZ/Vl37l+GF/82X/sDrMbKwVlxvaERpb1KXrnh/D1v qNze1Eea0eYv22weGGEa3J5N2tKfgX6NcRFioDNe9VEXX6zDcAtJKTKZtbMB3gXX CzQicH5yXApyAk3aNCq0S3s+WRQR0syGAYCmtxhaRgXRnSu9qifKZ1XhZQyhgKIG Flt9MsU2 =bOJ0 -----END PGP SIGNATURE----- Merge tag 'sysctl-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl Pull sysctl updates from Joel Granados: "sysctl ctl_table constification: - Constifying ctl_table structs prevents the modification of proc_handler function pointers. All ctl_table struct arguments are const qualified in the sysctl API in such a way that the ctl_table arrays being defined elsewhere and passed through sysctl can be constified one-by-one. We kick the constification off by qualifying user_table in kernel/ucount.c and expect all the ctl_tables to be constified in the coming releases. Misc fixes: - Adjust comments in two places to better reflect the code - Remove superfluous dput calls - Remove Luis from sysctl maintainership - Replace comments about holding a lock with calls to lockdep_assert_held" * tag 'sysctl-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl: sysctl: Reduce dput(child) calls in proc_sys_fill_cache() sysctl: Reorganize kerneldoc parameter names ucounts: constify sysctl table user_table sysctl: update comments to new registration APIs MAINTAINERS: remove me from sysctl sysctl: Convert locking comments to lockdep assertions const_structs.checkpatch: add ctl_table sysctl: make internal ctl_tables const sysctl: allow registration of const struct ctl_table sysctl: move internal interfaces to const struct ctl_table bpf: Constify ctl_table argument of filter function
This commit is contained in:
commit
980f8f8fd4
9 changed files with 73 additions and 69 deletions
|
@ -18641,7 +18641,6 @@ F: include/linux/proc_fs.h
|
||||||
F: tools/testing/selftests/proc/
|
F: tools/testing/selftests/proc/
|
||||||
|
|
||||||
PROC SYSCTL
|
PROC SYSCTL
|
||||||
M: Luis Chamberlain <mcgrof@kernel.org>
|
|
||||||
M: Kees Cook <kees@kernel.org>
|
M: Kees Cook <kees@kernel.org>
|
||||||
M: Joel Granados <joel.granados@kernel.org>
|
M: Joel Granados <joel.granados@kernel.org>
|
||||||
L: linux-kernel@vger.kernel.org
|
L: linux-kernel@vger.kernel.org
|
||||||
|
|
|
@ -102,7 +102,7 @@ struct proc_inode {
|
||||||
union proc_op op;
|
union proc_op op;
|
||||||
struct proc_dir_entry *pde;
|
struct proc_dir_entry *pde;
|
||||||
struct ctl_table_header *sysctl;
|
struct ctl_table_header *sysctl;
|
||||||
struct ctl_table *sysctl_entry;
|
const struct ctl_table *sysctl_entry;
|
||||||
struct hlist_node sibling_inodes;
|
struct hlist_node sibling_inodes;
|
||||||
const struct proc_ns_operations *ns_ops;
|
const struct proc_ns_operations *ns_ops;
|
||||||
struct inode vfs_inode;
|
struct inode vfs_inode;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/bpf-cgroup.h>
|
#include <linux/bpf-cgroup.h>
|
||||||
#include <linux/mount.h>
|
#include <linux/mount.h>
|
||||||
#include <linux/kmemleak.h>
|
#include <linux/kmemleak.h>
|
||||||
|
#include <linux/lockdep.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#define list_for_each_table_entry(entry, header) \
|
#define list_for_each_table_entry(entry, header) \
|
||||||
|
@ -33,7 +34,7 @@ static const struct inode_operations proc_sys_dir_operations;
|
||||||
* Support for permanently empty directories.
|
* Support for permanently empty directories.
|
||||||
* Must be non-empty to avoid sharing an address with other tables.
|
* Must be non-empty to avoid sharing an address with other tables.
|
||||||
*/
|
*/
|
||||||
static struct ctl_table sysctl_mount_point[] = {
|
static const struct ctl_table sysctl_mount_point[] = {
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ void proc_sys_poll_notify(struct ctl_table_poll *poll)
|
||||||
wake_up_interruptible(&poll->wait);
|
wake_up_interruptible(&poll->wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ctl_table root_table[] = {
|
static const struct ctl_table root_table[] = {
|
||||||
{
|
{
|
||||||
.procname = "",
|
.procname = "",
|
||||||
.mode = S_IFDIR|S_IRUGO|S_IXUGO,
|
.mode = S_IFDIR|S_IRUGO|S_IXUGO,
|
||||||
|
@ -88,7 +89,7 @@ static DEFINE_SPINLOCK(sysctl_lock);
|
||||||
|
|
||||||
static void drop_sysctl_table(struct ctl_table_header *header);
|
static void drop_sysctl_table(struct ctl_table_header *header);
|
||||||
static int sysctl_follow_link(struct ctl_table_header **phead,
|
static int sysctl_follow_link(struct ctl_table_header **phead,
|
||||||
struct ctl_table **pentry);
|
const struct ctl_table **pentry);
|
||||||
static int insert_links(struct ctl_table_header *head);
|
static int insert_links(struct ctl_table_header *head);
|
||||||
static void put_links(struct ctl_table_header *header);
|
static void put_links(struct ctl_table_header *header);
|
||||||
|
|
||||||
|
@ -109,14 +110,15 @@ static int namecmp(const char *name1, int len1, const char *name2, int len2)
|
||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called under sysctl_lock */
|
static const struct ctl_table *find_entry(struct ctl_table_header **phead,
|
||||||
static struct ctl_table *find_entry(struct ctl_table_header **phead,
|
|
||||||
struct ctl_dir *dir, const char *name, int namelen)
|
struct ctl_dir *dir, const char *name, int namelen)
|
||||||
{
|
{
|
||||||
struct ctl_table_header *head;
|
struct ctl_table_header *head;
|
||||||
struct ctl_table *entry;
|
const struct ctl_table *entry;
|
||||||
struct rb_node *node = dir->root.rb_node;
|
struct rb_node *node = dir->root.rb_node;
|
||||||
|
|
||||||
|
lockdep_assert_held(&sysctl_lock);
|
||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
struct ctl_node *ctl_node;
|
struct ctl_node *ctl_node;
|
||||||
|
@ -141,7 +143,7 @@ static struct ctl_table *find_entry(struct ctl_table_header **phead,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int insert_entry(struct ctl_table_header *head, struct ctl_table *entry)
|
static int insert_entry(struct ctl_table_header *head, const struct ctl_table *entry)
|
||||||
{
|
{
|
||||||
struct rb_node *node = &head->node[entry - head->ctl_table].node;
|
struct rb_node *node = &head->node[entry - head->ctl_table].node;
|
||||||
struct rb_node **p = &head->parent->root.rb_node;
|
struct rb_node **p = &head->parent->root.rb_node;
|
||||||
|
@ -151,7 +153,7 @@ static int insert_entry(struct ctl_table_header *head, struct ctl_table *entry)
|
||||||
|
|
||||||
while (*p) {
|
while (*p) {
|
||||||
struct ctl_table_header *parent_head;
|
struct ctl_table_header *parent_head;
|
||||||
struct ctl_table *parent_entry;
|
const struct ctl_table *parent_entry;
|
||||||
struct ctl_node *parent_node;
|
struct ctl_node *parent_node;
|
||||||
const char *parent_name;
|
const char *parent_name;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
@ -180,7 +182,7 @@ static int insert_entry(struct ctl_table_header *head, struct ctl_table *entry)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void erase_entry(struct ctl_table_header *head, struct ctl_table *entry)
|
static void erase_entry(struct ctl_table_header *head, const struct ctl_table *entry)
|
||||||
{
|
{
|
||||||
struct rb_node *node = &head->node[entry - head->ctl_table].node;
|
struct rb_node *node = &head->node[entry - head->ctl_table].node;
|
||||||
|
|
||||||
|
@ -189,7 +191,7 @@ static void erase_entry(struct ctl_table_header *head, struct ctl_table *entry)
|
||||||
|
|
||||||
static void init_header(struct ctl_table_header *head,
|
static void init_header(struct ctl_table_header *head,
|
||||||
struct ctl_table_root *root, struct ctl_table_set *set,
|
struct ctl_table_root *root, struct ctl_table_set *set,
|
||||||
struct ctl_node *node, struct ctl_table *table, size_t table_size)
|
struct ctl_node *node, const struct ctl_table *table, size_t table_size)
|
||||||
{
|
{
|
||||||
head->ctl_table = table;
|
head->ctl_table = table;
|
||||||
head->ctl_table_size = table_size;
|
head->ctl_table_size = table_size;
|
||||||
|
@ -204,7 +206,7 @@ static void init_header(struct ctl_table_header *head,
|
||||||
head->node = node;
|
head->node = node;
|
||||||
INIT_HLIST_HEAD(&head->inodes);
|
INIT_HLIST_HEAD(&head->inodes);
|
||||||
if (node) {
|
if (node) {
|
||||||
struct ctl_table *entry;
|
const struct ctl_table *entry;
|
||||||
|
|
||||||
list_for_each_table_entry(entry, head) {
|
list_for_each_table_entry(entry, head) {
|
||||||
node->header = head;
|
node->header = head;
|
||||||
|
@ -217,7 +219,7 @@ static void init_header(struct ctl_table_header *head,
|
||||||
|
|
||||||
static void erase_header(struct ctl_table_header *head)
|
static void erase_header(struct ctl_table_header *head)
|
||||||
{
|
{
|
||||||
struct ctl_table *entry;
|
const struct ctl_table *entry;
|
||||||
|
|
||||||
list_for_each_table_entry(entry, head)
|
list_for_each_table_entry(entry, head)
|
||||||
erase_entry(head, entry);
|
erase_entry(head, entry);
|
||||||
|
@ -225,7 +227,7 @@ static void erase_header(struct ctl_table_header *head)
|
||||||
|
|
||||||
static int insert_header(struct ctl_dir *dir, struct ctl_table_header *header)
|
static int insert_header(struct ctl_dir *dir, struct ctl_table_header *header)
|
||||||
{
|
{
|
||||||
struct ctl_table *entry;
|
const struct ctl_table *entry;
|
||||||
struct ctl_table_header *dir_h = &dir->header;
|
struct ctl_table_header *dir_h = &dir->header;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -263,18 +265,20 @@ static int insert_header(struct ctl_dir *dir, struct ctl_table_header *header)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called under sysctl_lock */
|
|
||||||
static int use_table(struct ctl_table_header *p)
|
static int use_table(struct ctl_table_header *p)
|
||||||
{
|
{
|
||||||
|
lockdep_assert_held(&sysctl_lock);
|
||||||
|
|
||||||
if (unlikely(p->unregistering))
|
if (unlikely(p->unregistering))
|
||||||
return 0;
|
return 0;
|
||||||
p->used++;
|
p->used++;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called under sysctl_lock */
|
|
||||||
static void unuse_table(struct ctl_table_header *p)
|
static void unuse_table(struct ctl_table_header *p)
|
||||||
{
|
{
|
||||||
|
lockdep_assert_held(&sysctl_lock);
|
||||||
|
|
||||||
if (!--p->used)
|
if (!--p->used)
|
||||||
if (unlikely(p->unregistering))
|
if (unlikely(p->unregistering))
|
||||||
complete(p->unregistering);
|
complete(p->unregistering);
|
||||||
|
@ -285,9 +289,11 @@ static void proc_sys_invalidate_dcache(struct ctl_table_header *head)
|
||||||
proc_invalidate_siblings_dcache(&head->inodes, &sysctl_lock);
|
proc_invalidate_siblings_dcache(&head->inodes, &sysctl_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called under sysctl_lock, will reacquire if has to wait */
|
|
||||||
static void start_unregistering(struct ctl_table_header *p)
|
static void start_unregistering(struct ctl_table_header *p)
|
||||||
{
|
{
|
||||||
|
/* will reacquire if has to wait */
|
||||||
|
lockdep_assert_held(&sysctl_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if p->used is 0, nobody will ever touch that entry again;
|
* if p->used is 0, nobody will ever touch that entry again;
|
||||||
* we'll eliminate all paths to it before dropping sysctl_lock
|
* we'll eliminate all paths to it before dropping sysctl_lock
|
||||||
|
@ -344,12 +350,12 @@ lookup_header_set(struct ctl_table_root *root)
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ctl_table *lookup_entry(struct ctl_table_header **phead,
|
static const struct ctl_table *lookup_entry(struct ctl_table_header **phead,
|
||||||
struct ctl_dir *dir,
|
struct ctl_dir *dir,
|
||||||
const char *name, int namelen)
|
const char *name, int namelen)
|
||||||
{
|
{
|
||||||
struct ctl_table_header *head;
|
struct ctl_table_header *head;
|
||||||
struct ctl_table *entry;
|
const struct ctl_table *entry;
|
||||||
|
|
||||||
spin_lock(&sysctl_lock);
|
spin_lock(&sysctl_lock);
|
||||||
entry = find_entry(&head, dir, name, namelen);
|
entry = find_entry(&head, dir, name, namelen);
|
||||||
|
@ -374,10 +380,10 @@ static struct ctl_node *first_usable_entry(struct rb_node *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void first_entry(struct ctl_dir *dir,
|
static void first_entry(struct ctl_dir *dir,
|
||||||
struct ctl_table_header **phead, struct ctl_table **pentry)
|
struct ctl_table_header **phead, const struct ctl_table **pentry)
|
||||||
{
|
{
|
||||||
struct ctl_table_header *head = NULL;
|
struct ctl_table_header *head = NULL;
|
||||||
struct ctl_table *entry = NULL;
|
const struct ctl_table *entry = NULL;
|
||||||
struct ctl_node *ctl_node;
|
struct ctl_node *ctl_node;
|
||||||
|
|
||||||
spin_lock(&sysctl_lock);
|
spin_lock(&sysctl_lock);
|
||||||
|
@ -391,10 +397,10 @@ static void first_entry(struct ctl_dir *dir,
|
||||||
*pentry = entry;
|
*pentry = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void next_entry(struct ctl_table_header **phead, struct ctl_table **pentry)
|
static void next_entry(struct ctl_table_header **phead, const struct ctl_table **pentry)
|
||||||
{
|
{
|
||||||
struct ctl_table_header *head = *phead;
|
struct ctl_table_header *head = *phead;
|
||||||
struct ctl_table *entry = *pentry;
|
const struct ctl_table *entry = *pentry;
|
||||||
struct ctl_node *ctl_node = &head->node[entry - head->ctl_table];
|
struct ctl_node *ctl_node = &head->node[entry - head->ctl_table];
|
||||||
|
|
||||||
spin_lock(&sysctl_lock);
|
spin_lock(&sysctl_lock);
|
||||||
|
@ -427,7 +433,7 @@ static int test_perm(int mode, int op)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sysctl_perm(struct ctl_table_header *head, struct ctl_table *table, int op)
|
static int sysctl_perm(struct ctl_table_header *head, const struct ctl_table *table, int op)
|
||||||
{
|
{
|
||||||
struct ctl_table_root *root = head->root;
|
struct ctl_table_root *root = head->root;
|
||||||
int mode;
|
int mode;
|
||||||
|
@ -441,7 +447,7 @@ static int sysctl_perm(struct ctl_table_header *head, struct ctl_table *table, i
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct inode *proc_sys_make_inode(struct super_block *sb,
|
static struct inode *proc_sys_make_inode(struct super_block *sb,
|
||||||
struct ctl_table_header *head, struct ctl_table *table)
|
struct ctl_table_header *head, const struct ctl_table *table)
|
||||||
{
|
{
|
||||||
struct ctl_table_root *root = head->root;
|
struct ctl_table_root *root = head->root;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
@ -512,7 +518,7 @@ static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
struct ctl_table_header *head = grab_header(dir);
|
struct ctl_table_header *head = grab_header(dir);
|
||||||
struct ctl_table_header *h = NULL;
|
struct ctl_table_header *h = NULL;
|
||||||
const struct qstr *name = &dentry->d_name;
|
const struct qstr *name = &dentry->d_name;
|
||||||
struct ctl_table *p;
|
const struct ctl_table *p;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct dentry *err = ERR_PTR(-ENOENT);
|
struct dentry *err = ERR_PTR(-ENOENT);
|
||||||
struct ctl_dir *ctl_dir;
|
struct ctl_dir *ctl_dir;
|
||||||
|
@ -550,7 +556,7 @@ static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
|
||||||
{
|
{
|
||||||
struct inode *inode = file_inode(iocb->ki_filp);
|
struct inode *inode = file_inode(iocb->ki_filp);
|
||||||
struct ctl_table_header *head = grab_header(inode);
|
struct ctl_table_header *head = grab_header(inode);
|
||||||
struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
const struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
||||||
size_t count = iov_iter_count(iter);
|
size_t count = iov_iter_count(iter);
|
||||||
char *kbuf;
|
char *kbuf;
|
||||||
ssize_t error;
|
ssize_t error;
|
||||||
|
@ -624,7 +630,7 @@ static ssize_t proc_sys_write(struct kiocb *iocb, struct iov_iter *iter)
|
||||||
static int proc_sys_open(struct inode *inode, struct file *filp)
|
static int proc_sys_open(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
struct ctl_table_header *head = grab_header(inode);
|
struct ctl_table_header *head = grab_header(inode);
|
||||||
struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
const struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
||||||
|
|
||||||
/* sysctl was unregistered */
|
/* sysctl was unregistered */
|
||||||
if (IS_ERR(head))
|
if (IS_ERR(head))
|
||||||
|
@ -642,7 +648,7 @@ static __poll_t proc_sys_poll(struct file *filp, poll_table *wait)
|
||||||
{
|
{
|
||||||
struct inode *inode = file_inode(filp);
|
struct inode *inode = file_inode(filp);
|
||||||
struct ctl_table_header *head = grab_header(inode);
|
struct ctl_table_header *head = grab_header(inode);
|
||||||
struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
const struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
||||||
__poll_t ret = DEFAULT_POLLMASK;
|
__poll_t ret = DEFAULT_POLLMASK;
|
||||||
unsigned long event;
|
unsigned long event;
|
||||||
|
|
||||||
|
@ -673,7 +679,7 @@ static __poll_t proc_sys_poll(struct file *filp, poll_table *wait)
|
||||||
static bool proc_sys_fill_cache(struct file *file,
|
static bool proc_sys_fill_cache(struct file *file,
|
||||||
struct dir_context *ctx,
|
struct dir_context *ctx,
|
||||||
struct ctl_table_header *head,
|
struct ctl_table_header *head,
|
||||||
struct ctl_table *table)
|
const struct ctl_table *table)
|
||||||
{
|
{
|
||||||
struct dentry *child, *dir = file->f_path.dentry;
|
struct dentry *child, *dir = file->f_path.dentry;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
@ -698,11 +704,11 @@ static bool proc_sys_fill_cache(struct file *file,
|
||||||
res = d_splice_alias(inode, child);
|
res = d_splice_alias(inode, child);
|
||||||
d_lookup_done(child);
|
d_lookup_done(child);
|
||||||
if (unlikely(res)) {
|
if (unlikely(res)) {
|
||||||
if (IS_ERR(res)) {
|
|
||||||
dput(child);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dput(child);
|
dput(child);
|
||||||
|
|
||||||
|
if (IS_ERR(res))
|
||||||
|
return false;
|
||||||
|
|
||||||
child = res;
|
child = res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -717,7 +723,7 @@ static bool proc_sys_fill_cache(struct file *file,
|
||||||
static bool proc_sys_link_fill_cache(struct file *file,
|
static bool proc_sys_link_fill_cache(struct file *file,
|
||||||
struct dir_context *ctx,
|
struct dir_context *ctx,
|
||||||
struct ctl_table_header *head,
|
struct ctl_table_header *head,
|
||||||
struct ctl_table *table)
|
const struct ctl_table *table)
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
|
@ -735,7 +741,7 @@ static bool proc_sys_link_fill_cache(struct file *file,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int scan(struct ctl_table_header *head, struct ctl_table *table,
|
static int scan(struct ctl_table_header *head, const struct ctl_table *table,
|
||||||
unsigned long *pos, struct file *file,
|
unsigned long *pos, struct file *file,
|
||||||
struct dir_context *ctx)
|
struct dir_context *ctx)
|
||||||
{
|
{
|
||||||
|
@ -759,7 +765,7 @@ static int proc_sys_readdir(struct file *file, struct dir_context *ctx)
|
||||||
{
|
{
|
||||||
struct ctl_table_header *head = grab_header(file_inode(file));
|
struct ctl_table_header *head = grab_header(file_inode(file));
|
||||||
struct ctl_table_header *h = NULL;
|
struct ctl_table_header *h = NULL;
|
||||||
struct ctl_table *entry;
|
const struct ctl_table *entry;
|
||||||
struct ctl_dir *ctl_dir;
|
struct ctl_dir *ctl_dir;
|
||||||
unsigned long pos;
|
unsigned long pos;
|
||||||
|
|
||||||
|
@ -792,7 +798,7 @@ static int proc_sys_permission(struct mnt_idmap *idmap,
|
||||||
* are _NOT_ writeable, capabilities or not.
|
* are _NOT_ writeable, capabilities or not.
|
||||||
*/
|
*/
|
||||||
struct ctl_table_header *head;
|
struct ctl_table_header *head;
|
||||||
struct ctl_table *table;
|
const struct ctl_table *table;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Executable files are not allowed under /proc/sys/ */
|
/* Executable files are not allowed under /proc/sys/ */
|
||||||
|
@ -836,7 +842,7 @@ static int proc_sys_getattr(struct mnt_idmap *idmap,
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(path->dentry);
|
struct inode *inode = d_inode(path->dentry);
|
||||||
struct ctl_table_header *head = grab_header(inode);
|
struct ctl_table_header *head = grab_header(inode);
|
||||||
struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
const struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
||||||
|
|
||||||
if (IS_ERR(head))
|
if (IS_ERR(head))
|
||||||
return PTR_ERR(head);
|
return PTR_ERR(head);
|
||||||
|
@ -935,7 +941,7 @@ static struct ctl_dir *find_subdir(struct ctl_dir *dir,
|
||||||
const char *name, int namelen)
|
const char *name, int namelen)
|
||||||
{
|
{
|
||||||
struct ctl_table_header *head;
|
struct ctl_table_header *head;
|
||||||
struct ctl_table *entry;
|
const struct ctl_table *entry;
|
||||||
|
|
||||||
entry = find_entry(&head, dir, name, namelen);
|
entry = find_entry(&head, dir, name, namelen);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
|
@ -1046,12 +1052,12 @@ static struct ctl_dir *xlate_dir(struct ctl_table_set *set, struct ctl_dir *dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sysctl_follow_link(struct ctl_table_header **phead,
|
static int sysctl_follow_link(struct ctl_table_header **phead,
|
||||||
struct ctl_table **pentry)
|
const struct ctl_table **pentry)
|
||||||
{
|
{
|
||||||
struct ctl_table_header *head;
|
struct ctl_table_header *head;
|
||||||
|
const struct ctl_table *entry;
|
||||||
struct ctl_table_root *root;
|
struct ctl_table_root *root;
|
||||||
struct ctl_table_set *set;
|
struct ctl_table_set *set;
|
||||||
struct ctl_table *entry;
|
|
||||||
struct ctl_dir *dir;
|
struct ctl_dir *dir;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -1078,7 +1084,7 @@ static int sysctl_follow_link(struct ctl_table_header **phead,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sysctl_err(const char *path, struct ctl_table *table, char *fmt, ...)
|
static int sysctl_err(const char *path, const struct ctl_table *table, char *fmt, ...)
|
||||||
{
|
{
|
||||||
struct va_format vaf;
|
struct va_format vaf;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -1094,7 +1100,7 @@ static int sysctl_err(const char *path, struct ctl_table *table, char *fmt, ...)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sysctl_check_table_array(const char *path, struct ctl_table *table)
|
static int sysctl_check_table_array(const char *path, const struct ctl_table *table)
|
||||||
{
|
{
|
||||||
unsigned int extra;
|
unsigned int extra;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -1133,7 +1139,7 @@ static int sysctl_check_table_array(const char *path, struct ctl_table *table)
|
||||||
|
|
||||||
static int sysctl_check_table(const char *path, struct ctl_table_header *header)
|
static int sysctl_check_table(const char *path, struct ctl_table_header *header)
|
||||||
{
|
{
|
||||||
struct ctl_table *entry;
|
const struct ctl_table *entry;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
list_for_each_table_entry(entry, header) {
|
list_for_each_table_entry(entry, header) {
|
||||||
if (!entry->procname)
|
if (!entry->procname)
|
||||||
|
@ -1169,8 +1175,9 @@ static int sysctl_check_table(const char *path, struct ctl_table_header *header)
|
||||||
|
|
||||||
static struct ctl_table_header *new_links(struct ctl_dir *dir, struct ctl_table_header *head)
|
static struct ctl_table_header *new_links(struct ctl_dir *dir, struct ctl_table_header *head)
|
||||||
{
|
{
|
||||||
struct ctl_table *link_table, *entry, *link;
|
struct ctl_table *link_table, *link;
|
||||||
struct ctl_table_header *links;
|
struct ctl_table_header *links;
|
||||||
|
const struct ctl_table *entry;
|
||||||
struct ctl_node *node;
|
struct ctl_node *node;
|
||||||
char *link_name;
|
char *link_name;
|
||||||
int name_bytes;
|
int name_bytes;
|
||||||
|
@ -1215,7 +1222,7 @@ static bool get_links(struct ctl_dir *dir,
|
||||||
struct ctl_table_root *link_root)
|
struct ctl_table_root *link_root)
|
||||||
{
|
{
|
||||||
struct ctl_table_header *tmp_head;
|
struct ctl_table_header *tmp_head;
|
||||||
struct ctl_table *entry, *link;
|
const struct ctl_table *entry, *link;
|
||||||
|
|
||||||
if (header->ctl_table_size == 0 ||
|
if (header->ctl_table_size == 0 ||
|
||||||
sysctl_is_perm_empty_ctl_header(header))
|
sysctl_is_perm_empty_ctl_header(header))
|
||||||
|
@ -1358,7 +1365,7 @@ static struct ctl_dir *sysctl_mkdir_p(struct ctl_dir *dir, const char *path)
|
||||||
*/
|
*/
|
||||||
struct ctl_table_header *__register_sysctl_table(
|
struct ctl_table_header *__register_sysctl_table(
|
||||||
struct ctl_table_set *set,
|
struct ctl_table_set *set,
|
||||||
const char *path, struct ctl_table *table, size_t table_size)
|
const char *path, const struct ctl_table *table, size_t table_size)
|
||||||
{
|
{
|
||||||
struct ctl_table_root *root = set->dir.header.root;
|
struct ctl_table_root *root = set->dir.header.root;
|
||||||
struct ctl_table_header *header;
|
struct ctl_table_header *header;
|
||||||
|
@ -1419,7 +1426,7 @@ struct ctl_table_header *__register_sysctl_table(
|
||||||
*
|
*
|
||||||
* See __register_sysctl_table for more details.
|
* See __register_sysctl_table for more details.
|
||||||
*/
|
*/
|
||||||
struct ctl_table_header *register_sysctl_sz(const char *path, struct ctl_table *table,
|
struct ctl_table_header *register_sysctl_sz(const char *path, const struct ctl_table *table,
|
||||||
size_t table_size)
|
size_t table_size)
|
||||||
{
|
{
|
||||||
return __register_sysctl_table(&sysctl_table_root.default_set,
|
return __register_sysctl_table(&sysctl_table_root.default_set,
|
||||||
|
@ -1448,7 +1455,7 @@ EXPORT_SYMBOL(register_sysctl_sz);
|
||||||
*
|
*
|
||||||
* Context: if your base directory does not exist it will be created for you.
|
* Context: if your base directory does not exist it will be created for you.
|
||||||
*/
|
*/
|
||||||
void __init __register_sysctl_init(const char *path, struct ctl_table *table,
|
void __init __register_sysctl_init(const char *path, const struct ctl_table *table,
|
||||||
const char *table_name, size_t table_size)
|
const char *table_name, size_t table_size)
|
||||||
{
|
{
|
||||||
struct ctl_table_header *hdr = register_sysctl_sz(path, table, table_size);
|
struct ctl_table_header *hdr = register_sysctl_sz(path, table, table_size);
|
||||||
|
@ -1466,7 +1473,7 @@ static void put_links(struct ctl_table_header *header)
|
||||||
struct ctl_table_root *root = header->root;
|
struct ctl_table_root *root = header->root;
|
||||||
struct ctl_dir *parent = header->parent;
|
struct ctl_dir *parent = header->parent;
|
||||||
struct ctl_dir *core_parent;
|
struct ctl_dir *core_parent;
|
||||||
struct ctl_table *entry;
|
const struct ctl_table *entry;
|
||||||
|
|
||||||
if (header->set == root_set)
|
if (header->set == root_set)
|
||||||
return;
|
return;
|
||||||
|
@ -1477,7 +1484,7 @@ static void put_links(struct ctl_table_header *header)
|
||||||
|
|
||||||
list_for_each_table_entry(entry, header) {
|
list_for_each_table_entry(entry, header) {
|
||||||
struct ctl_table_header *link_head;
|
struct ctl_table_header *link_head;
|
||||||
struct ctl_table *link;
|
const struct ctl_table *link;
|
||||||
const char *name = entry->procname;
|
const char *name = entry->procname;
|
||||||
|
|
||||||
link = find_entry(&link_head, core_parent, name, strlen(name));
|
link = find_entry(&link_head, core_parent, name, strlen(name));
|
||||||
|
|
|
@ -138,7 +138,7 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
|
||||||
short access, enum cgroup_bpf_attach_type atype);
|
short access, enum cgroup_bpf_attach_type atype);
|
||||||
|
|
||||||
int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
|
int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
|
||||||
struct ctl_table *table, int write,
|
const struct ctl_table *table, int write,
|
||||||
char **buf, size_t *pcount, loff_t *ppos,
|
char **buf, size_t *pcount, loff_t *ppos,
|
||||||
enum cgroup_bpf_attach_type atype);
|
enum cgroup_bpf_attach_type atype);
|
||||||
|
|
||||||
|
|
|
@ -90,9 +90,7 @@ int proc_do_static_key(const struct ctl_table *table, int write, void *buffer,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register a set of sysctl names by calling register_sysctl
|
* Register a set of sysctl names by calling register_sysctl
|
||||||
* with an initialised array of struct ctl_table's. An entry with
|
* with an initialised array of struct ctl_table's.
|
||||||
* NULL procname terminates the table. table->de will be
|
|
||||||
* set up by the registration and need not be initialised in advance.
|
|
||||||
*
|
*
|
||||||
* sysctl names can be mirrored automatically under /proc/sys. The
|
* sysctl names can be mirrored automatically under /proc/sys. The
|
||||||
* procname supplied controls /proc naming.
|
* procname supplied controls /proc naming.
|
||||||
|
@ -133,7 +131,7 @@ static inline void *proc_sys_poll_event(struct ctl_table_poll *poll)
|
||||||
|
|
||||||
/* A sysctl table is an array of struct ctl_table: */
|
/* A sysctl table is an array of struct ctl_table: */
|
||||||
struct ctl_table {
|
struct ctl_table {
|
||||||
const char *procname; /* Text ID for /proc/sys, or zero */
|
const char *procname; /* Text ID for /proc/sys */
|
||||||
void *data;
|
void *data;
|
||||||
int maxlen;
|
int maxlen;
|
||||||
umode_t mode;
|
umode_t mode;
|
||||||
|
@ -162,7 +160,7 @@ struct ctl_node {
|
||||||
struct ctl_table_header {
|
struct ctl_table_header {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
struct ctl_table *ctl_table;
|
const struct ctl_table *ctl_table;
|
||||||
int ctl_table_size;
|
int ctl_table_size;
|
||||||
int used;
|
int used;
|
||||||
int count;
|
int count;
|
||||||
|
@ -223,13 +221,13 @@ extern void retire_sysctl_set(struct ctl_table_set *set);
|
||||||
|
|
||||||
struct ctl_table_header *__register_sysctl_table(
|
struct ctl_table_header *__register_sysctl_table(
|
||||||
struct ctl_table_set *set,
|
struct ctl_table_set *set,
|
||||||
const char *path, struct ctl_table *table, size_t table_size);
|
const char *path, const struct ctl_table *table, size_t table_size);
|
||||||
struct ctl_table_header *register_sysctl_sz(const char *path, struct ctl_table *table,
|
struct ctl_table_header *register_sysctl_sz(const char *path, const struct ctl_table *table,
|
||||||
size_t table_size);
|
size_t table_size);
|
||||||
void unregister_sysctl_table(struct ctl_table_header * table);
|
void unregister_sysctl_table(struct ctl_table_header * table);
|
||||||
|
|
||||||
extern int sysctl_init_bases(void);
|
extern int sysctl_init_bases(void);
|
||||||
extern void __register_sysctl_init(const char *path, struct ctl_table *table,
|
extern void __register_sysctl_init(const char *path, const struct ctl_table *table,
|
||||||
const char *table_name, size_t table_size);
|
const char *table_name, size_t table_size);
|
||||||
#define register_sysctl_init(path, table) \
|
#define register_sysctl_init(path, table) \
|
||||||
__register_sysctl_init(path, table, #table, ARRAY_SIZE(table))
|
__register_sysctl_init(path, table, #table, ARRAY_SIZE(table))
|
||||||
|
@ -251,7 +249,7 @@ extern int no_unaligned_warning;
|
||||||
|
|
||||||
#else /* CONFIG_SYSCTL */
|
#else /* CONFIG_SYSCTL */
|
||||||
|
|
||||||
static inline void register_sysctl_init(const char *path, struct ctl_table *table)
|
static inline void register_sysctl_init(const char *path, const struct ctl_table *table)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +259,7 @@ static inline struct ctl_table_header *register_sysctl_mount_point(const char *p
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct ctl_table_header *register_sysctl_sz(const char *path,
|
static inline struct ctl_table_header *register_sysctl_sz(const char *path,
|
||||||
struct ctl_table *table,
|
const struct ctl_table *table,
|
||||||
size_t table_size)
|
size_t table_size)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -1708,7 +1708,7 @@ const struct bpf_verifier_ops cg_dev_verifier_ops = {
|
||||||
* returned value != 1 during execution. In all other cases 0 is returned.
|
* returned value != 1 during execution. In all other cases 0 is returned.
|
||||||
*/
|
*/
|
||||||
int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
|
int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
|
||||||
struct ctl_table *table, int write,
|
const struct ctl_table *table, int write,
|
||||||
char **buf, size_t *pcount, loff_t *ppos,
|
char **buf, size_t *pcount, loff_t *ppos,
|
||||||
enum cgroup_bpf_attach_type atype)
|
enum cgroup_bpf_attach_type atype)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1305,7 +1305,6 @@ int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int write,
|
||||||
* @write: %TRUE if this is a write to the sysctl file
|
* @write: %TRUE if this is a write to the sysctl file
|
||||||
* @buffer: the user buffer
|
* @buffer: the user buffer
|
||||||
* @lenp: the size of the user buffer
|
* @lenp: the size of the user buffer
|
||||||
* @ppos: file position
|
|
||||||
* @ppos: the current position in the file
|
* @ppos: the current position in the file
|
||||||
*
|
*
|
||||||
* Reads/writes up to table->maxlen/sizeof(unsigned int) integer
|
* Reads/writes up to table->maxlen/sizeof(unsigned int) integer
|
||||||
|
|
|
@ -70,7 +70,7 @@ static long ue_int_max = INT_MAX;
|
||||||
.extra1 = &ue_zero, \
|
.extra1 = &ue_zero, \
|
||||||
.extra2 = &ue_int_max, \
|
.extra2 = &ue_int_max, \
|
||||||
}
|
}
|
||||||
static struct ctl_table user_table[] = {
|
static const struct ctl_table user_table[] = {
|
||||||
UCOUNT_ENTRY("max_user_namespaces"),
|
UCOUNT_ENTRY("max_user_namespaces"),
|
||||||
UCOUNT_ENTRY("max_pid_namespaces"),
|
UCOUNT_ENTRY("max_pid_namespaces"),
|
||||||
UCOUNT_ENTRY("max_uts_namespaces"),
|
UCOUNT_ENTRY("max_uts_namespaces"),
|
||||||
|
|
|
@ -6,6 +6,7 @@ bus_type
|
||||||
clk_ops
|
clk_ops
|
||||||
comedi_lrange
|
comedi_lrange
|
||||||
component_ops
|
component_ops
|
||||||
|
ctl_table
|
||||||
dentry_operations
|
dentry_operations
|
||||||
dev_pm_ops
|
dev_pm_ops
|
||||||
device_type
|
device_type
|
||||||
|
|
Loading…
Reference in a new issue