📄 sysctl_check.c
字号:
{ 54, "in_speed_max" }, { 55, "out_speed_max" }, { 56, "measure_rate" }, { 57, "pre_Command_Wait" }, { 58, "rx_tweak1" }, { 59, "rx_tweak2" }, { 60, "tx_queue_len" }, { 150, "arlan3-txRing" }, { 151, "arlan3-rxRing" }, { 152, "arlan3-18" }, { 153, "arlan3-ring" }, { 154, "arlan3-shm-cpy" }, { 155, "config3" }, { 156, "reset3" }, {}};static const struct trans_ctl_table trans_arlan_table[] = { { 1, "arlan0", trans_arlan_conf_table0 }, { 2, "arlan1", trans_arlan_conf_table1 }, { 3, "arlan2", trans_arlan_conf_table2 }, { 4, "arlan3", trans_arlan_conf_table3 }, {}};static const struct trans_ctl_table trans_s390dbf_table[] = { { 5678 /* CTL_S390DBF_STOPPABLE */, "debug_stoppable" }, { 5679 /* CTL_S390DBF_ACTIVE */, "debug_active" }, {}};static const struct trans_ctl_table trans_sunrpc_table[] = { { CTL_RPCDEBUG, "rpc_debug" }, { CTL_NFSDEBUG, "nfs_debug" }, { CTL_NFSDDEBUG, "nfsd_debug" }, { CTL_NLMDEBUG, "nlm_debug" }, { CTL_SLOTTABLE_UDP, "udp_slot_table_entries" }, { CTL_SLOTTABLE_TCP, "tcp_slot_table_entries" }, { CTL_MIN_RESVPORT, "min_resvport" }, { CTL_MAX_RESVPORT, "max_resvport" }, {}};static const struct trans_ctl_table trans_pm_table[] = { { 1 /* CTL_PM_SUSPEND */, "suspend" }, { 2 /* CTL_PM_CMODE */, "cmode" }, { 3 /* CTL_PM_P0 */, "p0" }, { 4 /* CTL_PM_CM */, "cm" }, {}};static const struct trans_ctl_table trans_frv_table[] = { { 1, "cache-mode" }, { 2, "pin-cxnr" }, {}};static const struct trans_ctl_table trans_root_table[] = { { CTL_KERN, "kernel", trans_kern_table }, { CTL_VM, "vm", trans_vm_table }, { CTL_NET, "net", trans_net_table }, /* CTL_PROC not used */ { CTL_FS, "fs", trans_fs_table }, { CTL_DEBUG, "debug", trans_debug_table }, { CTL_DEV, "dev", trans_dev_table }, { CTL_BUS, "bus", trans_bus_table }, { CTL_ABI, "abi" }, /* CTL_CPU not used */ { CTL_ARLAN, "arlan", trans_arlan_table }, { CTL_S390DBF, "s390dbf", trans_s390dbf_table }, { CTL_SUNRPC, "sunrpc", trans_sunrpc_table }, { CTL_PM, "pm", trans_pm_table }, { CTL_FRV, "frv", trans_frv_table }, {}};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 const struct trans_ctl_table *sysctl_binary_lookup(struct ctl_table *table){ struct ctl_table *test; const struct trans_ctl_table *ref; int cur_depth; cur_depth = sysctl_depth(table); ref = trans_root_table;repeat: test = sysctl_parent(table, cur_depth); for (; ref->ctl_name || ref->procname || ref->child; ref++) { int match = 0; if (cur_depth && !ref->child) continue; if (test->procname && ref->procname && (strcmp(test->procname, ref->procname) == 0)) match++; if (test->ctl_name && ref->ctl_name && (test->ctl_name == ref->ctl_name)) match++; if (!ref->ctl_name && !ref->procname) match++; if (match) { if (cur_depth != 0) { cur_depth--; ref = ref->child; goto repeat; } goto out; } } ref = NULL;out: return ref;}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(" "); if (table->ctl_name) { for (i = depth; i >= 0; i--) { tmp = sysctl_parent(table, i); printk(".%d", tmp->ctl_name); } }}static void sysctl_repair_table(struct ctl_table *table){ /* Don't complain about the classic default * sysctl strategy routine. Maybe later we * can get the tables fixed and complain about * this. */ if (table->ctl_name && table->procname && (table->proc_handler == proc_dointvec) && (!table->strategy)) { table->strategy = sysctl_data; }}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->ctl_name || 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 (test->ctl_name && ref->ctl_name && (test->ctl_name == ref->ctl_name)) 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 int sysctl_check_dir(struct nsproxy *namespaces, struct ctl_table *table){ struct ctl_table *ref; int error; error = 0; ref = sysctl_check_lookup(namespaces, table); if (ref) { int match = 0; if ((!table->procname && !ref->procname) || (table->procname && ref->procname && (strcmp(table->procname, ref->procname) == 0))) match++; if ((!table->ctl_name && !ref->ctl_name) || (table->ctl_name && ref->ctl_name && (table->ctl_name == ref->ctl_name))) match++; if (match != 2) { printk(KERN_ERR "%s: failed: ", __func__); sysctl_print_path(table); printk(" ref: "); sysctl_print_path(ref); printk("\n"); error = -EINVAL; } } return error;}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");}static void sysctl_check_bin_path(struct ctl_table *table, const char **fail){ const struct trans_ctl_table *ref; ref = sysctl_binary_lookup(table); if (table->ctl_name && !ref) set_fail(fail, table, "Unknown sysctl binary path"); if (ref) { if (ref->procname && (!table->procname || (strcmp(table->procname, ref->procname) != 0))) set_fail(fail, table, "procname does not match binary path procname"); if (ref->ctl_name && table->ctl_name && (table->ctl_name != ref->ctl_name)) set_fail(fail, table, "ctl_name does not match binary path ctl_name"); }}int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table){ int error = 0; for (; table->ctl_name || table->procname; table++) { const char *fail = NULL; sysctl_repair_table(table); if (table->parent) { if (table->procname && !table->parent->procname) set_fail(&fail, table, "Parent without procname"); if (table->ctl_name && !table->parent->ctl_name) set_fail(&fail, table, "Parent without ctl_name"); } if (!table->procname) set_fail(&fail, table, "No 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->strategy) set_fail(&fail, table, "Directory with strategy"); if (table->extra1) set_fail(&fail, table, "Directory with extra1"); if (table->extra2) set_fail(&fail, table, "Directory with extra2"); if (sysctl_check_dir(namespaces, table)) set_fail(&fail, table, "Inconsistent directory names"); } else { if ((table->strategy == sysctl_data) || (table->strategy == sysctl_string) || (table->strategy == sysctl_intvec) || (table->strategy == sysctl_jiffies) || (table->strategy == sysctl_ms_jiffies) || (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"); } if ((table->proc_handler == proc_doulongvec_minmax) || (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) { if (table->maxlen > sizeof (unsigned long)) { if (!table->extra1) set_fail(&fail, table, "No min"); if (!table->extra2) set_fail(&fail, table, "No max"); } }#ifdef CONFIG_SYSCTL_SYSCALL if (table->ctl_name && !table->strategy) set_fail(&fail, table, "Missing strategy");#endif#if 0 if (!table->ctl_name && table->strategy) set_fail(&fail, table, "Strategy without ctl_name");#endif#ifdef CONFIG_PROC_FS if (table->procname && !table->proc_handler) set_fail(&fail, table, "No proc_handler");#endif#if 0 if (!table->procname && table->proc_handler) set_fail(&fail, table, "proc_handler without procname");#endif sysctl_check_leaf(namespaces, table, &fail); } sysctl_check_bin_path(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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -