Skip to content

Commit

Permalink
sysctl: always perform sysctl checks
Browse files Browse the repository at this point in the history
I'm not sure if we should always perform checks without giving
EMBEDDED folks a chance to skip these checks. If the system is
verified with sysctl checks, one can disable them to skip some
performance penalties.

Two of these checks will be more costly than the others:
- sysctl_check_netns_correspondents
- sysctl_check_duplicates

The first check is run for all regular (not netns dependent) sysctl
directories that are registered. For each element of a path
(e.g. kernel/sched_domain/cpu0/domain0/) we scan the current netns's
list of netns correspondents and check for matches.

This is O(len(current-netns-corresp-list)) * O(depth(registered path))

The second check compares every item in a registered table with all
siblings (other tables or subdirectories that are children of the same
parent directory).

This is O(len(table-being-registered)) * O(sum(len(already-registered-tables))+nr-subdirs).

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
  • Loading branch information
luciang committed Dec 5, 2011
1 parent 9154348 commit d1f0c4a
Show file tree
Hide file tree
Showing 4 changed files with 2 additions and 21 deletions.
2 changes: 0 additions & 2 deletions include/linux/sysctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1134,14 +1134,12 @@ extern struct ctl_table_header *register_sysctl_paths(const struct ctl_path *pat
struct ctl_table *table);
extern void unregister_sysctl_table(struct ctl_table_header *table);

#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
extern int sysctl_check_table(const struct ctl_path *path,
int nr_dirs,
struct ctl_table *table);
extern int sysctl_check_duplicates(struct ctl_table_header *header);
extern int sysctl_check_netns_correspondents(struct ctl_table_header *header,
struct ctl_table_group *group);
#endif /* CONFIG_SYSCTL_SYSCALL_CHECK */

#endif /* __KERNEL__ */

Expand Down
5 changes: 2 additions & 3 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

obj-y = sched.o fork.o exec_domain.o panic.o printk.o \
cpu.o exit.o itimer.o time.o softirq.o resource.o \
sysctl.o sysctl_binary.o capability.o ptrace.o timer.o user.o \
signal.o sys.o kmod.o workqueue.o pid.o \
sysctl.o sysctl_binary.o sysctl_check.o capability.o ptrace.o \
timer.o user.o signal.o sys.o kmod.o workqueue.o pid.o \
rcupdate.o extable.o params.o posix-timers.o \
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
Expand All @@ -26,7 +26,6 @@ endif

obj-$(CONFIG_FREEZER) += freezer.o
obj-$(CONFIG_PROFILING) += profile.o
obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += time/
obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
Expand Down
8 changes: 0 additions & 8 deletions kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1953,12 +1953,10 @@ static struct ctl_table_header *sysctl_mkdirs(struct ctl_table_header *parent,
sysctl_write_unlock_head(parent);
parent = h;
dirs[i] = NULL; /* I'm used, don't free me */
#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
if (sysctl_check_netns_correspondents(parent, group)) {
unregister_sysctl_table_impl(h);
goto err_check_netns_correspondents;
}
#endif
(*p_dirs_created)++;
continue;
}
Expand Down Expand Up @@ -1990,11 +1988,9 @@ static struct ctl_table_header *sysctl_mkdirs(struct ctl_table_header *parent,

return parent;

#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
err_check_netns_correspondents:
if (__netns_corresp)
kmem_cache_free(sysctl_header_cachep, __netns_corresp);
#endif

err_alloc_coresp:
i = nr_dirs;
Expand Down Expand Up @@ -2064,10 +2060,8 @@ struct ctl_table_header *__register_sysctl_paths_impl(struct ctl_table_group *gr
int nr_dirs = ctl_path_items(path);
int dirs_created = 0;

#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
if (sysctl_check_table(path, nr_dirs, table))
return NULL;
#endif

header = alloc_sysctl_header(group);
if (!header)
Expand All @@ -2086,9 +2080,7 @@ struct ctl_table_header *__register_sysctl_paths_impl(struct ctl_table_group *gr

sysctl_write_lock_head(header->parent);

#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
failed_duplicate_check = sysctl_check_duplicates(header);
#endif
if (!failed_duplicate_check)
list_add_tail(&header->ctl_entry, &header->parent->ctl_tables);

Expand Down
8 changes: 0 additions & 8 deletions lib/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -1113,14 +1113,6 @@ config LATENCYTOP
Enable this option if you want to use the LatencyTOP tool
to find out which userspace is blocking on what kernel operations.

config SYSCTL_SYSCALL_CHECK
bool "Sysctl checks"
depends on SYSCTL
---help---
sys_sysctl uses binary paths that have been found challenging
to properly maintain and use. This enables checks that help
you to keep things correct.

source mm/Kconfig.debug
source kernel/trace/Kconfig

Expand Down

0 comments on commit d1f0c4a

Please sign in to comment.