4 #include <linux/init.h>
5 #include <linux/sysctl.h>
6 #include <linux/proc_fs.h>
7 #include <linux/security.h>
10 static struct dentry_operations proc_sys_dentry_operations
;
11 static const struct file_operations proc_sys_file_operations
;
12 static const struct inode_operations proc_sys_inode_operations
;
13 static const struct file_operations proc_sys_dir_file_operations
;
14 static const struct inode_operations proc_sys_dir_operations
;
16 static struct inode
*proc_sys_make_inode(struct super_block
*sb
,
17 struct ctl_table_header
*head
, struct ctl_table
*table
)
20 struct proc_inode
*ei
;
22 inode
= new_inode(sb
);
26 sysctl_head_get(head
);
29 ei
->sysctl_entry
= table
;
31 inode
->i_mtime
= inode
->i_atime
= inode
->i_ctime
= CURRENT_TIME
;
32 inode
->i_flags
|= S_PRIVATE
; /* tell selinux to ignore this inode */
33 inode
->i_mode
= table
->mode
;
34 inode
->i_uid
= inode
->i_gid
= 0;
36 inode
->i_mode
|= S_IFREG
;
37 inode
->i_op
= &proc_sys_inode_operations
;
38 inode
->i_fop
= &proc_sys_file_operations
;
40 inode
->i_mode
|= S_IFDIR
;
42 inode
->i_op
= &proc_sys_dir_operations
;
43 inode
->i_fop
= &proc_sys_dir_file_operations
;
49 static struct ctl_table
*find_in_table(struct ctl_table
*p
, struct qstr
*name
)
52 for ( ; p
->ctl_name
|| p
->procname
; p
++) {
57 len
= strlen(p
->procname
);
61 if (memcmp(p
->procname
, name
->name
, len
) != 0)
70 static struct ctl_table_header
*grab_header(struct inode
*inode
)
72 if (PROC_I(inode
)->sysctl
)
73 return sysctl_head_grab(PROC_I(inode
)->sysctl
);
75 return sysctl_head_next(NULL
);
78 static struct dentry
*proc_sys_lookup(struct inode
*dir
, struct dentry
*dentry
,
81 struct ctl_table_header
*head
= grab_header(dir
);
82 struct ctl_table
*table
= PROC_I(dir
)->sysctl_entry
;
83 struct ctl_table_header
*h
= NULL
;
84 struct qstr
*name
= &dentry
->d_name
;
87 struct dentry
*err
= ERR_PTR(-ENOENT
);
90 return ERR_CAST(head
);
92 if (table
&& !table
->child
) {
97 table
= table
? table
->child
: head
->ctl_table
;
99 p
= find_in_table(table
, name
);
101 for (h
= sysctl_head_next(NULL
); h
; h
= sysctl_head_next(h
)) {
102 if (h
->attached_to
!= table
)
104 p
= find_in_table(h
->attached_by
, name
);
113 err
= ERR_PTR(-ENOMEM
);
114 inode
= proc_sys_make_inode(dir
->i_sb
, h
? h
: head
, p
);
116 sysctl_head_finish(h
);
122 dentry
->d_op
= &proc_sys_dentry_operations
;
123 d_add(dentry
, inode
);
126 sysctl_head_finish(head
);
130 static ssize_t
proc_sys_call_handler(struct file
*filp
, void __user
*buf
,
131 size_t count
, loff_t
*ppos
, int write
)
133 struct inode
*inode
= filp
->f_path
.dentry
->d_inode
;
134 struct ctl_table_header
*head
= grab_header(inode
);
135 struct ctl_table
*table
= PROC_I(inode
)->sysctl_entry
;
140 return PTR_ERR(head
);
143 * At this point we know that the sysctl was not unregistered
144 * and won't be until we finish.
147 if (sysctl_perm(head
->root
, table
, write
? MAY_WRITE
: MAY_READ
))
150 /* if that can happen at all, it should be -EINVAL, not -EISDIR */
152 if (!table
->proc_handler
)
155 /* careful: calling conventions are nasty here */
157 error
= table
->proc_handler(table
, write
, filp
, buf
, &res
, ppos
);
161 sysctl_head_finish(head
);
166 static ssize_t
proc_sys_read(struct file
*filp
, char __user
*buf
,
167 size_t count
, loff_t
*ppos
)
169 return proc_sys_call_handler(filp
, (void __user
*)buf
, count
, ppos
, 0);
172 static ssize_t
proc_sys_write(struct file
*filp
, const char __user
*buf
,
173 size_t count
, loff_t
*ppos
)
175 return proc_sys_call_handler(filp
, (void __user
*)buf
, count
, ppos
, 1);
179 static int proc_sys_fill_cache(struct file
*filp
, void *dirent
,
181 struct ctl_table_header
*head
,
182 struct ctl_table
*table
)
184 struct dentry
*child
, *dir
= filp
->f_path
.dentry
;
188 unsigned type
= DT_UNKNOWN
;
190 qname
.name
= table
->procname
;
191 qname
.len
= strlen(table
->procname
);
192 qname
.hash
= full_name_hash(qname
.name
, qname
.len
);
194 child
= d_lookup(dir
, &qname
);
196 child
= d_alloc(dir
, &qname
);
198 inode
= proc_sys_make_inode(dir
->d_sb
, head
, table
);
203 child
->d_op
= &proc_sys_dentry_operations
;
210 inode
= child
->d_inode
;
212 type
= inode
->i_mode
>> 12;
214 return !!filldir(dirent
, qname
.name
, qname
.len
, filp
->f_pos
, ino
, type
);
217 static int scan(struct ctl_table_header
*head
, ctl_table
*table
,
218 unsigned long *pos
, struct file
*file
,
219 void *dirent
, filldir_t filldir
)
222 for (; table
->ctl_name
|| table
->procname
; table
++, (*pos
)++) {
225 /* Can't do anything without a proc name */
226 if (!table
->procname
)
229 if (*pos
< file
->f_pos
)
232 res
= proc_sys_fill_cache(file
, dirent
, filldir
, head
, table
);
236 file
->f_pos
= *pos
+ 1;
241 static int proc_sys_readdir(struct file
*filp
, void *dirent
, filldir_t filldir
)
243 struct dentry
*dentry
= filp
->f_path
.dentry
;
244 struct inode
*inode
= dentry
->d_inode
;
245 struct ctl_table_header
*head
= grab_header(inode
);
246 struct ctl_table
*table
= PROC_I(inode
)->sysctl_entry
;
247 struct ctl_table_header
*h
= NULL
;
252 return PTR_ERR(head
);
254 if (table
&& !table
->child
) {
259 table
= table
? table
->child
: head
->ctl_table
;
262 /* Avoid a switch here: arm builds fail with missing __cmpdi2 */
263 if (filp
->f_pos
== 0) {
264 if (filldir(dirent
, ".", 1, filp
->f_pos
,
265 inode
->i_ino
, DT_DIR
) < 0)
269 if (filp
->f_pos
== 1) {
270 if (filldir(dirent
, "..", 2, filp
->f_pos
,
271 parent_ino(dentry
), DT_DIR
) < 0)
277 ret
= scan(head
, table
, &pos
, filp
, dirent
, filldir
);
281 for (h
= sysctl_head_next(NULL
); h
; h
= sysctl_head_next(h
)) {
282 if (h
->attached_to
!= table
)
284 ret
= scan(h
, h
->attached_by
, &pos
, filp
, dirent
, filldir
);
286 sysctl_head_finish(h
);
292 sysctl_head_finish(head
);
296 static int proc_sys_permission(struct inode
*inode
, int mask
)
299 * sysctl entries that are not writeable,
300 * are _NOT_ writeable, capabilities or not.
302 struct ctl_table_header
*head
;
303 struct ctl_table
*table
;
306 /* Executable files are not allowed under /proc/sys/ */
307 if ((mask
& MAY_EXEC
) && S_ISREG(inode
->i_mode
))
310 head
= grab_header(inode
);
312 return PTR_ERR(head
);
314 table
= PROC_I(inode
)->sysctl_entry
;
315 if (!table
) /* global root - r-xr-xr-x */
316 error
= mask
& MAY_WRITE
? -EACCES
: 0;
317 else /* Use the permissions on the sysctl table entry */
318 error
= sysctl_perm(head
->root
, table
, mask
);
320 sysctl_head_finish(head
);
324 static int proc_sys_setattr(struct dentry
*dentry
, struct iattr
*attr
)
326 struct inode
*inode
= dentry
->d_inode
;
329 if (attr
->ia_valid
& (ATTR_MODE
| ATTR_UID
| ATTR_GID
))
332 error
= inode_change_ok(inode
, attr
);
334 error
= inode_setattr(inode
, attr
);
339 static int proc_sys_getattr(struct vfsmount
*mnt
, struct dentry
*dentry
, struct kstat
*stat
)
341 struct inode
*inode
= dentry
->d_inode
;
342 struct ctl_table_header
*head
= grab_header(inode
);
343 struct ctl_table
*table
= PROC_I(inode
)->sysctl_entry
;
346 return PTR_ERR(head
);
348 generic_fillattr(inode
, stat
);
350 stat
->mode
= (stat
->mode
& S_IFMT
) | table
->mode
;
352 sysctl_head_finish(head
);
356 static const struct file_operations proc_sys_file_operations
= {
357 .read
= proc_sys_read
,
358 .write
= proc_sys_write
,
361 static const struct file_operations proc_sys_dir_file_operations
= {
362 .readdir
= proc_sys_readdir
,
363 .llseek
= generic_file_llseek
,
366 static const struct inode_operations proc_sys_inode_operations
= {
367 .permission
= proc_sys_permission
,
368 .setattr
= proc_sys_setattr
,
369 .getattr
= proc_sys_getattr
,
372 static const struct inode_operations proc_sys_dir_operations
= {
373 .lookup
= proc_sys_lookup
,
374 .permission
= proc_sys_permission
,
375 .setattr
= proc_sys_setattr
,
376 .getattr
= proc_sys_getattr
,
379 static int proc_sys_revalidate(struct dentry
*dentry
, struct nameidata
*nd
)
381 return !PROC_I(dentry
->d_inode
)->sysctl
->unregistering
;
384 static int proc_sys_delete(struct dentry
*dentry
)
386 return !!PROC_I(dentry
->d_inode
)->sysctl
->unregistering
;
389 static int proc_sys_compare(struct dentry
*dir
, struct qstr
*qstr
,
392 struct dentry
*dentry
= container_of(qstr
, struct dentry
, d_name
);
393 if (qstr
->len
!= name
->len
)
395 if (memcmp(qstr
->name
, name
->name
, name
->len
))
397 return !sysctl_is_seen(PROC_I(dentry
->d_inode
)->sysctl
);
400 static struct dentry_operations proc_sys_dentry_operations
= {
401 .d_revalidate
= proc_sys_revalidate
,
402 .d_delete
= proc_sys_delete
,
403 .d_compare
= proc_sys_compare
,
406 int __init
proc_sys_init(void)
408 struct proc_dir_entry
*proc_sys_root
;
410 proc_sys_root
= proc_mkdir("sys", NULL
);
411 proc_sys_root
->proc_iops
= &proc_sys_dir_operations
;
412 proc_sys_root
->proc_fops
= &proc_sys_dir_file_operations
;
413 proc_sys_root
->nlink
= 0;