| .. | .. |
|---|
| 16 | 16 | #include <linux/module.h> |
|---|
| 17 | 17 | #include <linux/bpf-cgroup.h> |
|---|
| 18 | 18 | #include <linux/mount.h> |
|---|
| 19 | +#include <linux/kmemleak.h> |
|---|
| 19 | 20 | #include "internal.h" |
|---|
| 20 | 21 | |
|---|
| 21 | 22 | static const struct dentry_operations proc_sys_dentry_operations; |
|---|
| .. | .. |
|---|
| 27 | 28 | /* shared constants to be used in various sysctls */ |
|---|
| 28 | 29 | const int sysctl_vals[] = { 0, 1, INT_MAX }; |
|---|
| 29 | 30 | EXPORT_SYMBOL(sysctl_vals); |
|---|
| 31 | +const int android_gki_sysctl_vals[] = { -1, 0, 1, 2, 4, 100, 200, 1000, 3000, INT_MAX }; |
|---|
| 32 | +EXPORT_SYMBOL(android_gki_sysctl_vals); |
|---|
| 30 | 33 | |
|---|
| 31 | 34 | /* Support for permanently empty directories */ |
|---|
| 32 | 35 | |
|---|
| .. | .. |
|---|
| 1105 | 1108 | err |= sysctl_err(path, table, "array not allowed"); |
|---|
| 1106 | 1109 | } |
|---|
| 1107 | 1110 | |
|---|
| 1111 | + if (table->proc_handler == proc_dou8vec_minmax) { |
|---|
| 1112 | + if (table->maxlen != sizeof(u8)) |
|---|
| 1113 | + err |= sysctl_err(path, table, "array not allowed"); |
|---|
| 1114 | + } |
|---|
| 1115 | + |
|---|
| 1108 | 1116 | return err; |
|---|
| 1109 | 1117 | } |
|---|
| 1110 | 1118 | |
|---|
| .. | .. |
|---|
| 1120 | 1128 | (table->proc_handler == proc_douintvec) || |
|---|
| 1121 | 1129 | (table->proc_handler == proc_douintvec_minmax) || |
|---|
| 1122 | 1130 | (table->proc_handler == proc_dointvec_minmax) || |
|---|
| 1131 | + (table->proc_handler == proc_dou8vec_minmax) || |
|---|
| 1123 | 1132 | (table->proc_handler == proc_dointvec_jiffies) || |
|---|
| 1124 | 1133 | (table->proc_handler == proc_dointvec_userhz_jiffies) || |
|---|
| 1125 | 1134 | (table->proc_handler == proc_dointvec_ms_jiffies) || |
|---|
| .. | .. |
|---|
| 1380 | 1389 | } |
|---|
| 1381 | 1390 | EXPORT_SYMBOL(register_sysctl); |
|---|
| 1382 | 1391 | |
|---|
| 1392 | +/** |
|---|
| 1393 | + * __register_sysctl_init() - register sysctl table to path |
|---|
| 1394 | + * @path: path name for sysctl base |
|---|
| 1395 | + * @table: This is the sysctl table that needs to be registered to the path |
|---|
| 1396 | + * @table_name: The name of sysctl table, only used for log printing when |
|---|
| 1397 | + * registration fails |
|---|
| 1398 | + * |
|---|
| 1399 | + * The sysctl interface is used by userspace to query or modify at runtime |
|---|
| 1400 | + * a predefined value set on a variable. These variables however have default |
|---|
| 1401 | + * values pre-set. Code which depends on these variables will always work even |
|---|
| 1402 | + * if register_sysctl() fails. If register_sysctl() fails you'd just loose the |
|---|
| 1403 | + * ability to query or modify the sysctls dynamically at run time. Chances of |
|---|
| 1404 | + * register_sysctl() failing on init are extremely low, and so for both reasons |
|---|
| 1405 | + * this function does not return any error as it is used by initialization code. |
|---|
| 1406 | + * |
|---|
| 1407 | + * Context: Can only be called after your respective sysctl base path has been |
|---|
| 1408 | + * registered. So for instance, most base directories are registered early on |
|---|
| 1409 | + * init before init levels are processed through proc_sys_init() and |
|---|
| 1410 | + * sysctl_init(). |
|---|
| 1411 | + */ |
|---|
| 1412 | +void __init __register_sysctl_init(const char *path, struct ctl_table *table, |
|---|
| 1413 | + const char *table_name) |
|---|
| 1414 | +{ |
|---|
| 1415 | + struct ctl_table_header *hdr = register_sysctl(path, table); |
|---|
| 1416 | + |
|---|
| 1417 | + if (unlikely(!hdr)) { |
|---|
| 1418 | + pr_err("failed when register_sysctl %s to %s\n", table_name, path); |
|---|
| 1419 | + return; |
|---|
| 1420 | + } |
|---|
| 1421 | + kmemleak_not_leak(hdr); |
|---|
| 1422 | +} |
|---|
| 1423 | + |
|---|
| 1383 | 1424 | static char *append_path(const char *path, char *pos, const char *name) |
|---|
| 1384 | 1425 | { |
|---|
| 1385 | 1426 | int namelen; |
|---|