]>
Commit | Line | Data |
---|---|---|
6a930a95 BS |
1 | From: Andreas Gruenbacher <agruen@suse.de> |
2 | Subject: Factor out sysctl pathname code | |
3 | ||
4 | Convert the selinux sysctl pathname computation code into a standalone | |
5 | function. | |
6 | ||
7 | Signed-off-by: Andreas Gruenbacher <agruen@suse.de> | |
8 | Signed-off-by: John Johansen <jjohansen@suse.de> | |
9 | Reviewed-by: James Morris <jmorris@namei.org> | |
10 | ||
11 | --- | |
12 | include/linux/sysctl.h | 2 ++ | |
13 | kernel/sysctl.c | 27 +++++++++++++++++++++++++++ | |
14 | security/selinux/hooks.c | 34 +++++----------------------------- | |
15 | 3 files changed, 34 insertions(+), 29 deletions(-) | |
16 | ||
17 | --- a/include/linux/sysctl.h | |
18 | +++ b/include/linux/sysctl.h | |
19 | @@ -996,6 +996,8 @@ extern int proc_doulongvec_minmax(struct | |
20 | extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int, | |
21 | struct file *, void __user *, size_t *, loff_t *); | |
22 | ||
23 | +extern char *sysctl_pathname(ctl_table *, char *, int); | |
24 | + | |
25 | extern int do_sysctl (int __user *name, int nlen, | |
26 | void __user *oldval, size_t __user *oldlenp, | |
27 | void __user *newval, size_t newlen); | |
28 | --- a/kernel/sysctl.c | |
29 | +++ b/kernel/sysctl.c | |
30 | @@ -1552,6 +1552,33 @@ void register_sysctl_root(struct ctl_tab | |
31 | spin_unlock(&sysctl_lock); | |
32 | } | |
33 | ||
34 | +char *sysctl_pathname(struct ctl_table *table, char *buffer, int buflen) | |
35 | +{ | |
36 | + if (buflen < 1) | |
37 | + return NULL; | |
38 | + buffer += --buflen; | |
39 | + *buffer = '\0'; | |
40 | + | |
41 | + while (table) { | |
42 | + int namelen = strlen(table->procname); | |
43 | + | |
44 | + if (buflen < namelen + 1) | |
45 | + return NULL; | |
46 | + buflen -= namelen + 1; | |
47 | + buffer -= namelen; | |
48 | + memcpy(buffer, table->procname, namelen); | |
49 | + *--buffer = '/'; | |
50 | + table = table->parent; | |
51 | + } | |
52 | + if (buflen < 4) | |
53 | + return NULL; | |
54 | + buffer -= 4; | |
55 | + memcpy(buffer, "/sys", 4); | |
56 | + | |
57 | + return buffer; | |
58 | +} | |
59 | +EXPORT_SYMBOL_GPL(sysctl_pathname); | |
60 | + | |
61 | #ifdef CONFIG_SYSCTL_SYSCALL | |
62 | /* Perform the actual read/write of a sysctl table entry. */ | |
63 | static int do_sysctl_strategy(struct ctl_table_root *root, | |
64 | --- a/security/selinux/hooks.c | |
65 | +++ b/security/selinux/hooks.c | |
66 | @@ -1811,40 +1811,16 @@ static int selinux_capable(struct task_s | |
67 | ||
68 | static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) | |
69 | { | |
70 | - int buflen, rc; | |
71 | - char *buffer, *path, *end; | |
72 | + char *buffer, *path; | |
73 | + int rc = -ENOMEM; | |
74 | ||
75 | - rc = -ENOMEM; | |
76 | buffer = (char *)__get_free_page(GFP_KERNEL); | |
77 | if (!buffer) | |
78 | goto out; | |
79 | ||
80 | - buflen = PAGE_SIZE; | |
81 | - end = buffer+buflen; | |
82 | - *--end = '\0'; | |
83 | - buflen--; | |
84 | - path = end-1; | |
85 | - *path = '/'; | |
86 | - while (table) { | |
87 | - const char *name = table->procname; | |
88 | - size_t namelen = strlen(name); | |
89 | - buflen -= namelen + 1; | |
90 | - if (buflen < 0) | |
91 | - goto out_free; | |
92 | - end -= namelen; | |
93 | - memcpy(end, name, namelen); | |
94 | - *--end = '/'; | |
95 | - path = end; | |
96 | - table = table->parent; | |
97 | - } | |
98 | - buflen -= 4; | |
99 | - if (buflen < 0) | |
100 | - goto out_free; | |
101 | - end -= 4; | |
102 | - memcpy(end, "/sys", 4); | |
103 | - path = end; | |
104 | - rc = security_genfs_sid("proc", path, tclass, sid); | |
105 | -out_free: | |
106 | + path = sysctl_pathname(table, buffer, PAGE_SIZE); | |
107 | + if (path) | |
108 | + rc = security_genfs_sid("proc", path, tclass, sid); | |
109 | free_page((unsigned long)buffer); | |
110 | out: | |
111 | return rc; |