diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-01-21 13:03:13 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2012-01-24 19:37:55 -0500 |
commit | f05e53a7fbb28c951c0c8cf3963fa8019ae1d4d3 (patch) | |
tree | aa8f66eb061b79be46619cfe7717bd64663cee1b /fs/proc/proc_sysctl.c | |
parent | bd295b56cfae85f2dd6c2b03951480c91e6d08f3 (diff) |
sysctl: Create local copies of directory names used in paths
Creating local copies of directory names is a good idea for
two reasons.
- The dynamic names used by callers must be copied into new
strings by the callers today to ensure the strings do not
change between register and unregister of the sysctl table.
- Sysctl directories have a potentially different lifetime
than the time between register and unregister of any
particular sysctl table.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Diffstat (limited to 'fs/proc/proc_sysctl.c')
-rw-r--r-- | fs/proc/proc_sysctl.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 86d32a318e2c..bcf60fb8dce5 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -943,10 +943,12 @@ struct ctl_table_header *__register_sysctl_paths( | |||
943 | struct ctl_table *new, **prevp; | 943 | struct ctl_table *new, **prevp; |
944 | unsigned int n, npath; | 944 | unsigned int n, npath; |
945 | struct ctl_table_set *set; | 945 | struct ctl_table_set *set; |
946 | size_t path_bytes = 0; | ||
947 | char *new_name; | ||
946 | 948 | ||
947 | /* Count the path components */ | 949 | /* Count the path components */ |
948 | for (npath = 0; path[npath].procname; ++npath) | 950 | for (npath = 0; path[npath].procname; ++npath) |
949 | ; | 951 | path_bytes += strlen(path[npath].procname) + 1; |
950 | 952 | ||
951 | /* | 953 | /* |
952 | * For each path component, allocate a 2-element ctl_table array. | 954 | * For each path component, allocate a 2-element ctl_table array. |
@@ -956,24 +958,27 @@ struct ctl_table_header *__register_sysctl_paths( | |||
956 | * We allocate everything in one go so that we don't have to | 958 | * We allocate everything in one go so that we don't have to |
957 | * worry about freeing additional memory in unregister_sysctl_table. | 959 | * worry about freeing additional memory in unregister_sysctl_table. |
958 | */ | 960 | */ |
959 | header = kzalloc(sizeof(struct ctl_table_header) + | 961 | header = kzalloc(sizeof(struct ctl_table_header) + path_bytes + |
960 | (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL); | 962 | (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL); |
961 | if (!header) | 963 | if (!header) |
962 | return NULL; | 964 | return NULL; |
963 | 965 | ||
964 | new = (struct ctl_table *) (header + 1); | 966 | new = (struct ctl_table *) (header + 1); |
967 | new_name = (char *)(new + (2 * npath)); | ||
965 | 968 | ||
966 | /* Now connect the dots */ | 969 | /* Now connect the dots */ |
967 | prevp = &header->ctl_table; | 970 | prevp = &header->ctl_table; |
968 | for (n = 0; n < npath; ++n, ++path) { | 971 | for (n = 0; n < npath; ++n, ++path) { |
969 | /* Copy the procname */ | 972 | /* Copy the procname */ |
970 | new->procname = path->procname; | 973 | strcpy(new_name, path->procname); |
974 | new->procname = new_name; | ||
971 | new->mode = 0555; | 975 | new->mode = 0555; |
972 | 976 | ||
973 | *prevp = new; | 977 | *prevp = new; |
974 | prevp = &new->child; | 978 | prevp = &new->child; |
975 | 979 | ||
976 | new += 2; | 980 | new += 2; |
981 | new_name += strlen(new_name) + 1; | ||
977 | } | 982 | } |
978 | *prevp = table; | 983 | *prevp = table; |
979 | header->ctl_table_arg = table; | 984 | header->ctl_table_arg = table; |