mark system calls as being MPSAFE:
- Stop conditionally acquiring Giant around system call invocations.
- Remove all of the 'M' prefixes from the master system call files.
- Remove support for the 'M' prefix from the script that generates the
syscall-related files from the master system call files.
- Don't explicitly set SYF_MPSAFE when registering nfssvc.
except for s_family (which is read-only once after it is set when the
structure is created).
- Mark svr4_sys_ioctl(), svr4_sys_getmsg(), and svr4_sys_putmsg() MPSAFE.
kern_accept() and accept1(). If another thread closed the new file
descriptor and the first thread later got an error trying to copyout the
socket address, then it would attempt to close the wrong file object. To
fix, add a struct file ** argument to kern_accept(). If it is non-NULL,
then on success kern_accept() will store a pointer to the new file object
there and not release any of the references. It is up to the calling code
to drop the references appropriately (including a call to fdclose() in case
of error to safely handle the aforementioned race). While I'm at it, go
ahead and fix the svr4 streams code to not leak the accept fd if it gets an
error trying to copyout the streams structures.
locked.
- Move all the svr4 socket cache code into svr4_socket.c, specifically
move svr4_delete_socket() over from streams.c. Make the socket cache
entry structure and svr4_head private to svr4_socket.c as a result.
- Add a mutex to protect the svr4 socket cache.
- Change svr4_find_socket() to copy the sockaddr_un struct into a
caller-supplied sockaddr_un rather than giving the caller a pointer to
our internal one. This removes the one case where code outside of
svr4_socket.c could access data in the cache.
- Add an eventhandler for process_exit and process_exec to purge the cache
of any entries for the exiting or execing process.
- Add methods to init and destroy the socket cache and call them from the
svr4 ABI module's event handler.
- Conditionally grab Giant around socreate() in streamsopen().
- Use fdclose() instead of inlining it in streamsopen() when handling
socreate() failure.
- Only allocate a stream structure and attach it to a socket in
streamsopen(). Previously, if a svr4 program performed a stream
operation on an arbitrary socket not opened via the streams device,
we would attach streams state data to it and change f_ops of the
associated struct file while it was in use. The latter was especially
not safe, and if a program wants a stream object it should open it via
the streams device anyway.
- Don't bother locking so_emuldata in the streams code now that we only
touch it right after creating a socket (in streamsopen()) or when
tearing it down when the file is closed.
- Remove D_NEEDGIANT from the streams device as it is no longer needed.
Also, call change_dir() instead of doing part of it inline (this now adds
a mac_check_vnode_chdir() call) to match fchdir() and call
mac_check_vnode_chroot() to match chroot(). Also, use the change_root()
function to do the actual change root to match chroot().
Reviewed by: rwatson
Giant VFS locking in that function.
- Remove bogus code to handle the case where namei() returns success but a
NULL vnode pointer.
- Note that this code duplicates exec_check_permissions() and annotate
where it differs.
- Hold the vnode lock longer to protect the write to set VV_TEXT in
v_vflag.
- Mark linux_uselib() MPSAFE.
Reviewed by: rwatson
- If the WNOWAIT flag isn't specified and either of WEXITED or WTRAPPED is
set, then just call kern_wait() and let it do all the work. This means
that this function no longer has to duplicate the work to teardown
zombies that is done in kern_wait(). Instead, if the above conditions
aren't true, then it uses a simpler loop to implement WNOWAIT and/or
tracing for only stopped or continued processes. This function still
has to duplicate code from kern_wait() for the latter two cases, but
those are much simpler.
- Sync the code to handle the WCONTINUED and WSTOPPED cases with the
equivalent code in kern_wait().
- Fix several places that would return with the proctree lock still held.
- Lock the current process to prevent lost wakeup races when blocking.
ibcs2_getdents(), ibcs2_read(), ogetdirentries(), svr4_sys_getdents(),
and svr4_sys_getdents64() similar to that in getdirentries().
- Mark ibcs2_getdents(), ibcs2_read(), linux_getdents(), linux_getdents64(),
linux_readdir(), ogetdirentries(), svr4_sys_getdents(), and
svr4_sys_getdents64() MPSAFE.
use by ABI emulators.
- Alter the interface of kern_recvit() somewhat. Specifically, go ahead
and hard code UIO_USERSPACE in the uio as that's what all the callers
specify. In place, add a new uioseg to indicate what type of pointer
is in mp->msg_name. Previously it was always a userland address, but
ABI emulators may pass in kernel-side sockaddrs. Also, remove the
namelenp field and instead require the two places that used it to
explicitly copy mp->msg_namelen out to userland.
- Use the patched kern_recvit() to replace svr4_recvit() and the stock
kern_sendit() to replace svr4_sendit().
- Use kern_bind() instead of stackgap use in ti_bind().
- Use kern_getpeername() and kern_getsockname() instead of stackgap in
svr4_stream_ti_ioctl().
- Use kern_connect() instead of stackgap in svr4_do_putmsg().
- Use kern_getpeername() and kern_accept() instead of stackgap in
svr4_do_getmsg().
- Retire the stackgap from SVR4 compat as it is no longer used.
mostly consists of pushing a few copyin's and copyout's up into
__semctl() as all the other callers were already doing the UIO_SYSSPACE
case. This also changes kern_semctl() to set the return value in a passed
in pointer to a register_t rather than td->td_retval[0] directly so that
callers can only set td->td_retval[0] if all the various copyout's succeed.
As a result of these changes, kern_semctl() no longer does copyin/copyout
(except for GETALL/SETALL) so simplify the locking to acquire the semakptr
mutex before the MAC check and hold it all the way until the end of the
big switch statement. The GETALL/SETALL cases have to temporarily drop it
while they do copyin/malloc and copyout. Also, simplify the SETALL case to
remove handling for a non-existent race condition.
shmctl(). None of the other ABI's do this (including the native FreeBSD
ABI), and uselessly trying to do a copyin() can actually result in a
bogus EFAULT if the a process specifies NULL for the optional argument
(which is what they should do in this case).
- process state (idle, sleeping, running, ...) [1]
- the process group ID of the process which owns the connected tty
- some page fault stats
- time spend in kernel/userland
- priority/nice value
- starttime [1]
- memory/swap stats
- scheduling policy
Additionally add some new fields and correct some not filled out ones.
This brings us down to 15 dummy fields.
The fields marked with [1] are needed to get Oracle 10 running. The starttime
field is not completely right, since it displays the _same_ starttime for
_every_ process, but at least it is not 0 and Oracle accepts this.
This is a RELENG_x_y candidate.
Noticed by: Dmitry Ganenko <dima@apk-inform.com> [1]
Reviewed by: des, rdivacky
MFC after: 1 week
to a copied-in copy of the 'union semun' and a uioseg to indicate which
memory space the 'buf' pointer of the union points to. This is then used
in linux_semctl() and svr4_sys_semctl() to eliminate use of the stackgap.
- Mark linux_ipc() and svr4_sys_semsys() MPSAFE.
from going away. mount(2) is now MPSAFE.
- Expand the scope of Giant some in unmount(2) to protect the mp structure
(or rather, to handle concurrent unmount races) from going away.
umount(2) is now MPSAFE, as well as linux_umount() and linux_oldumount().
- nmount(2) and linux_mount() were already MPSAFE.
and don't panic.
This fix is different from the patch submitted as it not only prevents
a NULL-pointer dereference, but also skips some work in this case.
Noticed by: Dmitry Ganenko <dima@apk-inform.com>
Reviewed by: rdivacky (the original version as in emulation@)
MFC after: 1 week
Security: This is a RELENG_x_y candidate (local DoS).
Go ahead by: secteam (cperciva)
file objects calling a user-specified predicate function on each object.
The iteration terminates either when the entire list has been iterated
over or the predicate function returns a non-zero value.
linker_file_foreach() returns the value returned by the last invocation
of the predicate function. It also accepts a void * context pointer that
is passed to the predicate function as well. Using an iterator function
avoids exposing linker internals to the rest of the kernel making locking
simpler.
- Use linker_file_foreach() instead of walking the list of linker files
manually to lookup ndis files in ndis(4).
- Use linker_file_foreach() to implement linker_hwpmc_list_objects().