@@ -49,6 +49,55 @@ static struct ctl_table_root sysctl_table_root = {
49
49
50
50
static DEFINE_SPINLOCK (sysctl_lock );
51
51
52
+ static int namecmp (const char * name1 , int len1 , const char * name2 , int len2 )
53
+ {
54
+ int minlen ;
55
+ int cmp ;
56
+
57
+ minlen = len1 ;
58
+ if (minlen > len2 )
59
+ minlen = len2 ;
60
+
61
+ cmp = memcmp (name1 , name2 , minlen );
62
+ if (cmp == 0 )
63
+ cmp = len1 - len2 ;
64
+ return cmp ;
65
+ }
66
+
67
+ static struct ctl_table * find_entry (struct ctl_table_header * * phead ,
68
+ struct ctl_table_set * set ,
69
+ struct ctl_table_header * dir_head , struct ctl_table * dir ,
70
+ const char * name , int namelen )
71
+ {
72
+ struct ctl_table_header * head ;
73
+ struct ctl_table * entry ;
74
+
75
+ if (dir_head -> set == set ) {
76
+ for (entry = dir ; entry -> procname ; entry ++ ) {
77
+ const char * procname = entry -> procname ;
78
+ if (namecmp (procname , strlen (procname ), name , namelen ) == 0 ) {
79
+ * phead = dir_head ;
80
+ return entry ;
81
+ }
82
+ }
83
+ }
84
+
85
+ list_for_each_entry (head , & set -> list , ctl_entry ) {
86
+ if (head -> unregistering )
87
+ continue ;
88
+ if (head -> attached_to != dir )
89
+ continue ;
90
+ for (entry = head -> attached_by ; entry -> procname ; entry ++ ) {
91
+ const char * procname = entry -> procname ;
92
+ if (namecmp (procname , strlen (procname ), name , namelen ) == 0 ) {
93
+ * phead = head ;
94
+ return entry ;
95
+ }
96
+ }
97
+ }
98
+ return NULL ;
99
+ }
100
+
52
101
static void init_header (struct ctl_table_header * head ,
53
102
struct ctl_table_root * root , struct ctl_table_set * set ,
54
103
struct ctl_table * table )
@@ -168,6 +217,32 @@ lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
168
217
return & set -> list ;
169
218
}
170
219
220
+ static struct ctl_table * lookup_entry (struct ctl_table_header * * phead ,
221
+ struct ctl_table_header * dir_head ,
222
+ struct ctl_table * dir ,
223
+ const char * name , int namelen )
224
+ {
225
+ struct ctl_table_header * head ;
226
+ struct ctl_table * entry ;
227
+ struct ctl_table_root * root ;
228
+ struct ctl_table_set * set ;
229
+
230
+ spin_lock (& sysctl_lock );
231
+ root = & sysctl_table_root ;
232
+ do {
233
+ set = lookup_header_set (root , current -> nsproxy );
234
+ entry = find_entry (& head , set , dir_head , dir , name , namelen );
235
+ if (entry && use_table (head ))
236
+ * phead = head ;
237
+ else
238
+ entry = NULL ;
239
+ root = list_entry (root -> root_list .next ,
240
+ struct ctl_table_root , root_list );
241
+ } while (!entry && root != & sysctl_table_root );
242
+ spin_unlock (& sysctl_lock );
243
+ return entry ;
244
+ }
245
+
171
246
static struct ctl_table_header * __sysctl_head_next (struct nsproxy * namespaces ,
172
247
struct ctl_table_header * prev )
173
248
{
@@ -284,21 +359,6 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
284
359
return inode ;
285
360
}
286
361
287
- static struct ctl_table * find_in_table (struct ctl_table * p , struct qstr * name )
288
- {
289
- for ( ; p -> procname ; p ++ ) {
290
- if (strlen (p -> procname ) != name -> len )
291
- continue ;
292
-
293
- if (memcmp (p -> procname , name -> name , name -> len ) != 0 )
294
- continue ;
295
-
296
- /* I have a match */
297
- return p ;
298
- }
299
- return NULL ;
300
- }
301
-
302
362
static struct ctl_table_header * grab_header (struct inode * inode )
303
363
{
304
364
struct ctl_table_header * head = PROC_I (inode )-> sysctl ;
@@ -328,17 +388,7 @@ static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
328
388
329
389
table = table ? table -> child : & head -> ctl_table [1 ];
330
390
331
- p = find_in_table (table , name );
332
- if (!p ) {
333
- for (h = sysctl_head_next (NULL ); h ; h = sysctl_head_next (h )) {
334
- if (h -> attached_to != table )
335
- continue ;
336
- p = find_in_table (h -> attached_by , name );
337
- if (p )
338
- break ;
339
- }
340
- }
341
-
391
+ p = lookup_entry (& h , head , table , name -> name , name -> len );
342
392
if (!p )
343
393
goto out ;
344
394
0 commit comments