1 /* $NetBSD: procfs_vfsops.c,v 1.84 2009/10/02 23:00:02 elad Exp $ */
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * @(#)procfs_vfsops.c 8.7 (Berkeley) 5/10/95
38 * Copyright (c) 1993 Jan-Simon Pendry
40 * This code is derived from software contributed to Berkeley by
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 3. All advertising materials mentioning features or use of this software
52 * must display the following acknowledgement:
53 * This product includes software developed by the University of
54 * California, Berkeley and its contributors.
55 * 4. Neither the name of the University nor the names of its contributors
56 * may be used to endorse or promote products derived from this software
57 * without specific prior written permission.
59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
71 * @(#)procfs_vfsops.c 8.7 (Berkeley) 5/10/95
75 * procfs VFS interface
78 #include <sys/cdefs.h>
79 __KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.84 2009/10/02 23:00:02 elad Exp $");
81 #if defined(_KERNEL_OPT)
82 #include "opt_compat_netbsd.h"
85 #include <sys/param.h>
87 #include <sys/kernel.h>
88 #include <sys/systm.h>
89 #include <sys/sysctl.h>
92 #include <sys/syslog.h>
93 #include <sys/mount.h>
94 #include <sys/dirent.h>
95 #include <sys/signalvar.h>
96 #include <sys/vnode.h>
97 #include <sys/malloc.h>
98 #include <sys/kauth.h>
99 #include <sys/module.h>
101 #include <miscfs/genfs/genfs.h>
103 #include <miscfs/procfs/procfs.h>
105 #include <uvm/uvm_extern.h> /* for PAGE_SIZE */
107 MODULE(MODULE_CLASS_VFS
, procfs
, NULL
);
111 static struct sysctllog
*procfs_sysctl_log
;
113 static kauth_listener_t procfs_listener
;
128 struct lwp
*l
= curlwp
;
129 struct procfsmount
*pmnt
;
130 struct procfs_args
*args
= data
;
133 if (UIO_MX
& (UIO_MX
-1)) {
134 log(LOG_ERR
, "procfs: invalid directory entry size");
138 if (mp
->mnt_flag
& MNT_GETARGS
) {
139 if (*data_len
< sizeof *args
)
142 pmnt
= VFSTOPROC(mp
);
145 args
->version
= PROCFS_ARGSVERSION
;
146 args
->flags
= pmnt
->pmnt_flags
;
147 *data_len
= sizeof *args
;
151 if (mp
->mnt_flag
& MNT_UPDATE
)
154 if (*data_len
>= sizeof *args
&& args
->version
!= PROCFS_ARGSVERSION
)
157 pmnt
= (struct procfsmount
*) malloc(sizeof(struct procfsmount
),
158 M_UFSMNT
, M_WAITOK
); /* XXX need new malloc type */
160 mp
->mnt_stat
.f_namemax
= MAXNAMLEN
;
161 mp
->mnt_flag
|= MNT_LOCAL
;
165 error
= set_statvfs_info(path
, UIO_USERSPACE
, "procfs", UIO_SYSSPACE
,
166 mp
->mnt_op
->vfs_name
, mp
, l
);
167 pmnt
->pmnt_exechook
= exechook_establish(procfs_revoke_vnodes
, mp
);
168 if (*data_len
>= sizeof *args
)
169 pmnt
->pmnt_flags
= args
->flags
;
171 pmnt
->pmnt_flags
= 0;
173 mp
->mnt_iflag
|= IMNT_MPSAFE
;
178 * unmount system call
181 procfs_unmount(struct mount
*mp
, int mntflags
)
186 if (mntflags
& MNT_FORCE
)
189 if ((error
= vflush(mp
, 0, flags
)) != 0)
192 exechook_disestablish(VFSTOPROC(mp
)->pmnt_exechook
);
194 free(mp
->mnt_data
, M_UFSMNT
);
201 procfs_root(struct mount
*mp
, struct vnode
**vpp
)
204 return (procfs_allocvp(mp
, vpp
, 0, PFSroot
, -1, NULL
));
209 procfs_start(struct mount
*mp
, int flags
)
216 * Get file system statistics.
219 procfs_statvfs(struct mount
*mp
, struct statvfs
*sbp
)
222 genfs_statvfs(mp
, sbp
);
224 sbp
->f_bsize
= PAGE_SIZE
;
225 sbp
->f_frsize
= PAGE_SIZE
;
226 sbp
->f_iosize
= PAGE_SIZE
;
228 sbp
->f_files
= maxproc
; /* approx */
229 sbp
->f_ffree
= maxproc
- nprocs
; /* approx */
230 sbp
->f_favail
= maxproc
- nprocs
; /* approx */
248 procfs_vget(struct mount
*mp
, ino_t ino
,
272 extern const struct vnodeopv_desc procfs_vnodeop_opv_desc
;
274 const struct vnodeopv_desc
* const procfs_vnodeopv_descs
[] = {
275 &procfs_vnodeop_opv_desc
,
279 struct vfsops procfs_vfsops
= {
281 sizeof (struct procfs_args
),
286 (void *)eopnotsupp
, /* vfs_quotactl */
290 (void *)eopnotsupp
, /* vfs_fhtovp */
291 (void *)eopnotsupp
, /* vfs_vptofh */
295 NULL
, /* vfs_mountroot */
296 (int (*)(struct mount
*, struct vnode
*, struct timespec
*)) eopnotsupp
,
298 (void *)eopnotsupp
, /* vfs_suspendctl */
299 genfs_renamelock_enter
,
300 genfs_renamelock_exit
,
302 procfs_vnodeopv_descs
,
308 procfs_listener_cb(kauth_cred_t cred
, kauth_action_t action
, void *cookie
,
309 void *arg0
, void *arg1
, void *arg2
, void *arg3
)
313 enum kauth_process_req req
;
316 result
= KAUTH_RESULT_DEFER
;
319 req
= (enum kauth_process_req
)(unsigned long)arg2
;
321 if (action
!= KAUTH_PROCESS_PROCFS
)
324 /* Privileged; let secmodel handle that. */
325 if (req
== KAUTH_REQ_PROCESS_PROCFS_CTL
)
328 switch (pfs
->pfs_type
) {
332 if (kauth_cred_getuid(cred
) != kauth_cred_getuid(p
->p_cred
) ||
333 ISSET(p
->p_flag
, PK_SUGID
))
338 result
= KAUTH_RESULT_ALLOW
;
347 procfs_modcmd(modcmd_t cmd
, void *arg
)
352 case MODULE_CMD_INIT
:
353 error
= vfs_attach(&procfs_vfsops
);
356 sysctl_createv(&procfs_sysctl_log
, 0, NULL
, NULL
,
358 CTLTYPE_NODE
, "vfs", NULL
,
361 sysctl_createv(&procfs_sysctl_log
, 0, NULL
, NULL
,
363 CTLTYPE_NODE
, "procfs",
364 SYSCTL_DESCR("Process file system"),
366 CTL_VFS
, 12, CTL_EOL
);
368 * XXX the "12" above could be dynamic, thereby eliminating
369 * one more instance of the "number to vfs" mapping problem,
370 * but "12" is the order as taken from sys/mount.h
373 procfs_listener
= kauth_listen_scope(KAUTH_SCOPE_PROCESS
,
374 procfs_listener_cb
, NULL
);
377 case MODULE_CMD_FINI
:
378 error
= vfs_detach(&procfs_vfsops
);
381 sysctl_teardown(&procfs_sysctl_log
);
382 kauth_unlisten_scope(procfs_listener
);