Denis Kirjanovsysctl_check: drop dead code256c53a15 years agoHistory
160 lines · 3.8 KB · C
RawDownload
#include <linux/stat.h>#include <linux/sysctl.h>#include "../fs/xfs/linux-2.6/xfs_sysctl.h"#include <linux/sunrpc/debug.h>#include <linux/string.h>#include <net/ip_vs.h>  static int sysctl_depth(struct ctl_table *table){	struct ctl_table *tmp;	int depth; 	depth = 0;	for (tmp = table; tmp->parent; tmp = tmp->parent)		depth++; 	return depth;} static struct ctl_table *sysctl_parent(struct ctl_table *table, int n){	int i; 	for (i = 0; table && i < n; i++)		table = table->parent; 	return table;}  static void sysctl_print_path(struct ctl_table *table){	struct ctl_table *tmp;	int depth, i;	depth = sysctl_depth(table);	if (table->procname) {		for (i = depth; i >= 0; i--) {			tmp = sysctl_parent(table, i);			printk("/%s", tmp->procname?tmp->procname:"");		}	}	printk(" ");} static struct ctl_table *sysctl_check_lookup(struct nsproxy *namespaces,						struct ctl_table *table){	struct ctl_table_header *head;	struct ctl_table *ref, *test;	int depth, cur_depth; 	depth = sysctl_depth(table); 	for (head = __sysctl_head_next(namespaces, NULL); head;	     head = __sysctl_head_next(namespaces, head)) {		cur_depth = depth;		ref = head->ctl_table;repeat:		test = sysctl_parent(table, cur_depth);		for (; ref->procname; ref++) {			int match = 0;			if (cur_depth && !ref->child)				continue; 			if (test->procname && ref->procname &&			    (strcmp(test->procname, ref->procname) == 0))					match++; 			if (match) {				if (cur_depth != 0) {					cur_depth--;					ref = ref->child;					goto repeat;				}				goto out;			}		}	}	ref = NULL;out:	sysctl_head_finish(head);	return ref;} static void set_fail(const char **fail, struct ctl_table *table, const char *str){	if (*fail) {		printk(KERN_ERR "sysctl table check failed: ");		sysctl_print_path(table);		printk(" %s\n", *fail);		dump_stack();	}	*fail = str;} static void sysctl_check_leaf(struct nsproxy *namespaces,				struct ctl_table *table, const char **fail){	struct ctl_table *ref; 	ref = sysctl_check_lookup(namespaces, table);	if (ref && (ref != table))		set_fail(fail, table, "Sysctl already exists");} int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table){	int error = 0;	for (; table->procname; table++) {		const char *fail = NULL; 		if (table->parent) {			if (!table->parent->procname)				set_fail(&fail, table, "Parent without procname");		}		if (table->child) {			if (table->data)				set_fail(&fail, table, "Directory with data?");			if (table->maxlen)				set_fail(&fail, table, "Directory with maxlen?");			if ((table->mode & (S_IRUGO|S_IXUGO)) != table->mode)				set_fail(&fail, table, "Writable sysctl directory");			if (table->proc_handler)				set_fail(&fail, table, "Directory with proc_handler");			if (table->extra1)				set_fail(&fail, table, "Directory with extra1");			if (table->extra2)				set_fail(&fail, table, "Directory with extra2");		} else {			if ((table->proc_handler == proc_dostring) ||			    (table->proc_handler == proc_dointvec) ||			    (table->proc_handler == proc_dointvec_minmax) ||			    (table->proc_handler == proc_dointvec_jiffies) ||			    (table->proc_handler == proc_dointvec_userhz_jiffies) ||			    (table->proc_handler == proc_dointvec_ms_jiffies) ||			    (table->proc_handler == proc_doulongvec_minmax) ||			    (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {				if (!table->data)					set_fail(&fail, table, "No data");				if (!table->maxlen)					set_fail(&fail, table, "No maxlen");			}#ifdef CONFIG_PROC_SYSCTL			if (!table->proc_handler)				set_fail(&fail, table, "No proc_handler");#endif			sysctl_check_leaf(namespaces, table, &fail);		}		if (table->mode > 0777)			set_fail(&fail, table, "bogus .mode");		if (fail) {			set_fail(&fail, table, NULL);			error = -EINVAL;		}		if (table->child)			error |= sysctl_check_table(namespaces, table->child);	}	return error;}