2005-01-06 23:22:04 +00:00
|
|
|
/*-
|
1995-10-10 07:27:24 +00:00
|
|
|
* Copyright (c) 1995 Scott Bartram
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2003-06-02 06:48:51 +00:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
|
1998-02-04 04:12:29 +00:00
|
|
|
#include "opt_spx_hack.h"
|
|
|
|
|
1995-10-10 07:27:24 +00:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
2011-08-11 12:30:23 +00:00
|
|
|
#include <sys/capability.h>
|
1997-03-23 03:37:54 +00:00
|
|
|
#include <sys/fcntl.h>
|
1995-10-10 07:27:24 +00:00
|
|
|
#include <sys/file.h>
|
|
|
|
#include <sys/filedesc.h>
|
2001-05-01 08:13:21 +00:00
|
|
|
#include <sys/lock.h>
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
#include <sys/malloc.h>
|
2001-05-01 08:13:21 +00:00
|
|
|
#include <sys/mutex.h>
|
2004-08-24 20:21:21 +00:00
|
|
|
#include <sys/syscallsubr.h>
|
Remove old files no longer needed.
Add new files created for emulator.
Modify NetBSD import to work with FreeBSD and add new features and
code. The complete emulator is essentially a combination of work/code
implemented by Sean Eric Fagan, Soren Schmidt, Scott Bartram, and myself,
Steven Wallace.
Features of this new emulator system include:
o "clean" code, including strict prototyping.
o Auto-generation of ibcs2 system calls, xenix system calls, isc system
calls. Generation includes system tables, structure definitions,
and prototyping of function calls.
o ibcs2 emulator does not rely on any COMPAT_43 system calls.
o embedded socksys support
o ibcs2 msgsys, semsys, shmsys calls supported if supported in kernel
o alternate /emul/ibcs2 namespace searched first for files in ibcs2
system. Usefull to keep sysv libraries, binaries in /emul/ibcs2.
o many other finer details and functions fixed or implemented.
1995-10-10 07:59:30 +00:00
|
|
|
#include <sys/sysproto.h>
|
2001-05-01 08:13:21 +00:00
|
|
|
#include <sys/ttycom.h>
|
1995-10-10 07:27:24 +00:00
|
|
|
|
Remove old files no longer needed.
Add new files created for emulator.
Modify NetBSD import to work with FreeBSD and add new features and
code. The complete emulator is essentially a combination of work/code
implemented by Sean Eric Fagan, Soren Schmidt, Scott Bartram, and myself,
Steven Wallace.
Features of this new emulator system include:
o "clean" code, including strict prototyping.
o Auto-generation of ibcs2 system calls, xenix system calls, isc system
calls. Generation includes system tables, structure definitions,
and prototyping of function calls.
o ibcs2 emulator does not rely on any COMPAT_43 system calls.
o embedded socksys support
o ibcs2 msgsys, semsys, shmsys calls supported if supported in kernel
o alternate /emul/ibcs2 namespace searched first for files in ibcs2
system. Usefull to keep sysv libraries, binaries in /emul/ibcs2.
o many other finer details and functions fixed or implemented.
1995-10-10 07:59:30 +00:00
|
|
|
#include <i386/ibcs2/ibcs2_fcntl.h>
|
|
|
|
#include <i386/ibcs2/ibcs2_signal.h>
|
|
|
|
#include <i386/ibcs2/ibcs2_proto.h>
|
|
|
|
#include <i386/ibcs2/ibcs2_util.h>
|
1995-10-10 07:27:24 +00:00
|
|
|
|
2002-03-20 05:48:58 +00:00
|
|
|
static void cvt_iflock2flock(struct ibcs2_flock *, struct flock *);
|
|
|
|
static void cvt_flock2iflock(struct flock *, struct ibcs2_flock *);
|
|
|
|
static int cvt_o_flags(int);
|
|
|
|
static int oflags2ioflags(int);
|
|
|
|
static int ioflags2oflags(int);
|
1995-10-10 07:27:24 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
cvt_o_flags(flags)
|
|
|
|
int flags;
|
|
|
|
{
|
|
|
|
int r = 0;
|
|
|
|
|
|
|
|
/* convert mode into NetBSD mode */
|
|
|
|
if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
|
Remove old files no longer needed.
Add new files created for emulator.
Modify NetBSD import to work with FreeBSD and add new features and
code. The complete emulator is essentially a combination of work/code
implemented by Sean Eric Fagan, Soren Schmidt, Scott Bartram, and myself,
Steven Wallace.
Features of this new emulator system include:
o "clean" code, including strict prototyping.
o Auto-generation of ibcs2 system calls, xenix system calls, isc system
calls. Generation includes system tables, structure definitions,
and prototyping of function calls.
o ibcs2 emulator does not rely on any COMPAT_43 system calls.
o embedded socksys support
o ibcs2 msgsys, semsys, shmsys calls supported if supported in kernel
o alternate /emul/ibcs2 namespace searched first for files in ibcs2
system. Usefull to keep sysv libraries, binaries in /emul/ibcs2.
o many other finer details and functions fixed or implemented.
1995-10-10 07:59:30 +00:00
|
|
|
if (flags & IBCS2_O_RDWR) r |= O_RDWR;
|
1995-10-10 07:27:24 +00:00
|
|
|
if (flags & (IBCS2_O_NDELAY | IBCS2_O_NONBLOCK)) r |= O_NONBLOCK;
|
|
|
|
if (flags & IBCS2_O_APPEND) r |= O_APPEND;
|
Remove old files no longer needed.
Add new files created for emulator.
Modify NetBSD import to work with FreeBSD and add new features and
code. The complete emulator is essentially a combination of work/code
implemented by Sean Eric Fagan, Soren Schmidt, Scott Bartram, and myself,
Steven Wallace.
Features of this new emulator system include:
o "clean" code, including strict prototyping.
o Auto-generation of ibcs2 system calls, xenix system calls, isc system
calls. Generation includes system tables, structure definitions,
and prototyping of function calls.
o ibcs2 emulator does not rely on any COMPAT_43 system calls.
o embedded socksys support
o ibcs2 msgsys, semsys, shmsys calls supported if supported in kernel
o alternate /emul/ibcs2 namespace searched first for files in ibcs2
system. Usefull to keep sysv libraries, binaries in /emul/ibcs2.
o many other finer details and functions fixed or implemented.
1995-10-10 07:59:30 +00:00
|
|
|
if (flags & IBCS2_O_SYNC) r |= O_FSYNC;
|
|
|
|
if (flags & IBCS2_O_CREAT) r |= O_CREAT;
|
|
|
|
if (flags & IBCS2_O_TRUNC) r |= O_TRUNC /* | O_CREAT ??? */;
|
|
|
|
if (flags & IBCS2_O_EXCL) r |= O_EXCL;
|
|
|
|
if (flags & IBCS2_O_RDONLY) r |= O_RDONLY;
|
|
|
|
if (flags & IBCS2_O_PRIV) r |= O_EXLOCK;
|
|
|
|
if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY;
|
1995-10-10 07:27:24 +00:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
cvt_flock2iflock(flp, iflp)
|
|
|
|
struct flock *flp;
|
|
|
|
struct ibcs2_flock *iflp;
|
|
|
|
{
|
|
|
|
switch (flp->l_type) {
|
|
|
|
case F_RDLCK:
|
|
|
|
iflp->l_type = IBCS2_F_RDLCK;
|
|
|
|
break;
|
|
|
|
case F_WRLCK:
|
|
|
|
iflp->l_type = IBCS2_F_WRLCK;
|
|
|
|
break;
|
|
|
|
case F_UNLCK:
|
|
|
|
iflp->l_type = IBCS2_F_UNLCK;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
iflp->l_whence = (short)flp->l_whence;
|
|
|
|
iflp->l_start = (ibcs2_off_t)flp->l_start;
|
|
|
|
iflp->l_len = (ibcs2_off_t)flp->l_len;
|
2008-03-26 15:23:12 +00:00
|
|
|
iflp->l_sysid = flp->l_sysid;
|
1995-10-10 07:27:24 +00:00
|
|
|
iflp->l_pid = (ibcs2_pid_t)flp->l_pid;
|
|
|
|
}
|
|
|
|
|
Remove old files no longer needed.
Add new files created for emulator.
Modify NetBSD import to work with FreeBSD and add new features and
code. The complete emulator is essentially a combination of work/code
implemented by Sean Eric Fagan, Soren Schmidt, Scott Bartram, and myself,
Steven Wallace.
Features of this new emulator system include:
o "clean" code, including strict prototyping.
o Auto-generation of ibcs2 system calls, xenix system calls, isc system
calls. Generation includes system tables, structure definitions,
and prototyping of function calls.
o ibcs2 emulator does not rely on any COMPAT_43 system calls.
o embedded socksys support
o ibcs2 msgsys, semsys, shmsys calls supported if supported in kernel
o alternate /emul/ibcs2 namespace searched first for files in ibcs2
system. Usefull to keep sysv libraries, binaries in /emul/ibcs2.
o many other finer details and functions fixed or implemented.
1995-10-10 07:59:30 +00:00
|
|
|
#ifdef DEBUG_IBCS2
|
|
|
|
static void
|
|
|
|
print_flock(struct flock *flp)
|
|
|
|
{
|
|
|
|
printf("flock: start=%x len=%x pid=%d type=%d whence=%d\n",
|
|
|
|
(int)flp->l_start, (int)flp->l_len, (int)flp->l_pid,
|
|
|
|
flp->l_type, flp->l_whence);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1995-10-10 07:27:24 +00:00
|
|
|
static void
|
|
|
|
cvt_iflock2flock(iflp, flp)
|
|
|
|
struct ibcs2_flock *iflp;
|
|
|
|
struct flock *flp;
|
|
|
|
{
|
|
|
|
flp->l_start = (off_t)iflp->l_start;
|
|
|
|
flp->l_len = (off_t)iflp->l_len;
|
|
|
|
flp->l_pid = (pid_t)iflp->l_pid;
|
|
|
|
switch (iflp->l_type) {
|
|
|
|
case IBCS2_F_RDLCK:
|
|
|
|
flp->l_type = F_RDLCK;
|
|
|
|
break;
|
|
|
|
case IBCS2_F_WRLCK:
|
|
|
|
flp->l_type = F_WRLCK;
|
|
|
|
break;
|
|
|
|
case IBCS2_F_UNLCK:
|
|
|
|
flp->l_type = F_UNLCK;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
flp->l_whence = iflp->l_whence;
|
2008-03-26 15:23:12 +00:00
|
|
|
flp->l_sysid = iflp->l_sysid;
|
1995-10-10 07:27:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert iBCS2 mode into NetBSD mode */
|
|
|
|
static int
|
|
|
|
ioflags2oflags(flags)
|
|
|
|
int flags;
|
|
|
|
{
|
|
|
|
int r = 0;
|
|
|
|
|
|
|
|
if (flags & IBCS2_O_RDONLY) r |= O_RDONLY;
|
|
|
|
if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
|
|
|
|
if (flags & IBCS2_O_RDWR) r |= O_RDWR;
|
|
|
|
if (flags & IBCS2_O_NDELAY) r |= O_NONBLOCK;
|
|
|
|
if (flags & IBCS2_O_APPEND) r |= O_APPEND;
|
|
|
|
if (flags & IBCS2_O_SYNC) r |= O_FSYNC;
|
|
|
|
if (flags & IBCS2_O_NONBLOCK) r |= O_NONBLOCK;
|
|
|
|
if (flags & IBCS2_O_CREAT) r |= O_CREAT;
|
|
|
|
if (flags & IBCS2_O_TRUNC) r |= O_TRUNC;
|
|
|
|
if (flags & IBCS2_O_EXCL) r |= O_EXCL;
|
|
|
|
if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert NetBSD mode into iBCS2 mode */
|
|
|
|
static int
|
|
|
|
oflags2ioflags(flags)
|
|
|
|
int flags;
|
|
|
|
{
|
|
|
|
int r = 0;
|
|
|
|
|
|
|
|
if (flags & O_RDONLY) r |= IBCS2_O_RDONLY;
|
|
|
|
if (flags & O_WRONLY) r |= IBCS2_O_WRONLY;
|
|
|
|
if (flags & O_RDWR) r |= IBCS2_O_RDWR;
|
|
|
|
if (flags & O_NDELAY) r |= IBCS2_O_NONBLOCK;
|
|
|
|
if (flags & O_APPEND) r |= IBCS2_O_APPEND;
|
|
|
|
if (flags & O_FSYNC) r |= IBCS2_O_SYNC;
|
|
|
|
if (flags & O_NONBLOCK) r |= IBCS2_O_NONBLOCK;
|
|
|
|
if (flags & O_CREAT) r |= IBCS2_O_CREAT;
|
|
|
|
if (flags & O_TRUNC) r |= IBCS2_O_TRUNC;
|
|
|
|
if (flags & O_EXCL) r |= IBCS2_O_EXCL;
|
|
|
|
if (flags & O_NOCTTY) r |= IBCS2_O_NOCTTY;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2001-09-12 08:38:13 +00:00
|
|
|
ibcs2_open(td, uap)
|
|
|
|
struct thread *td;
|
1995-10-10 07:27:24 +00:00
|
|
|
struct ibcs2_open_args *uap;
|
|
|
|
{
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
struct proc *p;
|
|
|
|
char *path;
|
|
|
|
int flags, noctty, ret;
|
1995-10-10 07:27:24 +00:00
|
|
|
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
p = td->td_proc;
|
|
|
|
noctty = uap->flags & IBCS2_O_NOCTTY;
|
|
|
|
flags = cvt_o_flags(uap->flags);
|
2002-12-14 01:56:26 +00:00
|
|
|
if (uap->flags & O_CREAT)
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
CHECKALTCREAT(td, uap->path, &path);
|
1995-10-10 07:27:24 +00:00
|
|
|
else
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
CHECKALTEXIST(td, uap->path, &path);
|
|
|
|
ret = kern_open(td, path, UIO_SYSSPACE, flags, uap->mode);
|
1995-10-10 07:27:24 +00:00
|
|
|
|
Add a hack to emulator to emulat spx device for local X connections.
This is truly a hack. The idea is taken from the Linux ibcs2 emulator.
To use this feature, you must use the option,
options SPX_HACK
in your config.
Also, in /compat/ibcs2/dev, you must do:
lrwxr-xr-x 1 root wheel 9 Oct 15 22:20 X0R@ -> /dev/null
lrwxr-xr-x 1 root wheel 7 Oct 15 22:20 nfsd@ -> socksys
lrwxr-xr-x 1 root wheel 9 Oct 15 22:20 socksys@ -> /dev/null
crw-rw-rw- 1 root wheel 41, 1 Oct 15 22:14 spx
Do NOT use old socksys driver as that has been removed.
This hack needs /compat/ibcs2/dev/spx to be any device that does NOT
exist/configured (so the now non-existant spx major/minor works fine).
When an open() is called, the error ENXIO is checked and then the
path is checked. If spx open detected, then a unix socket is opened
to the hardcoded path "/tmp/.X11-unix/X0".
As the Linux hacker author mentioned, the real way would be to detect
the getmsg/putmsg through /dev/X0R and /dev/spx. Until this true
solution is implemented (if ever), I think this hack is important
enough to be put into the tree, even though I don't like it dirtying
up my clean code (which is what #ifdef SPX_HACK is for).
1995-10-16 05:52:55 +00:00
|
|
|
#ifdef SPX_HACK
|
1999-05-06 18:13:11 +00:00
|
|
|
if (ret == ENXIO) {
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
if (!strcmp(path, "/compat/ibcs2/dev/spx"))
|
|
|
|
ret = spx_open(td);
|
|
|
|
free(path, M_TEMP);
|
1999-05-06 18:13:11 +00:00
|
|
|
} else
|
Add a hack to emulator to emulat spx device for local X connections.
This is truly a hack. The idea is taken from the Linux ibcs2 emulator.
To use this feature, you must use the option,
options SPX_HACK
in your config.
Also, in /compat/ibcs2/dev, you must do:
lrwxr-xr-x 1 root wheel 9 Oct 15 22:20 X0R@ -> /dev/null
lrwxr-xr-x 1 root wheel 7 Oct 15 22:20 nfsd@ -> socksys
lrwxr-xr-x 1 root wheel 9 Oct 15 22:20 socksys@ -> /dev/null
crw-rw-rw- 1 root wheel 41, 1 Oct 15 22:14 spx
Do NOT use old socksys driver as that has been removed.
This hack needs /compat/ibcs2/dev/spx to be any device that does NOT
exist/configured (so the now non-existant spx major/minor works fine).
When an open() is called, the error ENXIO is checked and then the
path is checked. If spx open detected, then a unix socket is opened
to the hardcoded path "/tmp/.X11-unix/X0".
As the Linux hacker author mentioned, the real way would be to detect
the getmsg/putmsg through /dev/X0R and /dev/spx. Until this true
solution is implemented (if ever), I think this hack is important
enough to be put into the tree, even though I don't like it dirtying
up my clean code (which is what #ifdef SPX_HACK is for).
1995-10-16 05:52:55 +00:00
|
|
|
#endif /* SPX_HACK */
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
free(path, M_TEMP);
|
2001-01-23 23:59:38 +00:00
|
|
|
PROC_LOCK(p);
|
1995-10-10 07:27:24 +00:00
|
|
|
if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
|
Change the cap_rights_t type from uint64_t to a structure that we can extend
in the future in a backward compatible (API and ABI) way.
The cap_rights_t represents capability rights. We used to use one bit to
represent one right, but we are running out of spare bits. Currently the new
structure provides place for 114 rights (so 50 more than the previous
cap_rights_t), but it is possible to grow the structure to hold at least 285
rights, although we can make it even larger if 285 rights won't be enough.
The structure definition looks like this:
struct cap_rights {
uint64_t cr_rights[CAP_RIGHTS_VERSION + 2];
};
The initial CAP_RIGHTS_VERSION is 0.
The top two bits in the first element of the cr_rights[] array contain total
number of elements in the array - 2. This means if those two bits are equal to
0, we have 2 array elements.
The top two bits in all remaining array elements should be 0.
The next five bits in all array elements contain array index. Only one bit is
used and bit position in this five-bits range defines array index. This means
there can be at most five array elements in the future.
To define new right the CAPRIGHT() macro must be used. The macro takes two
arguments - an array index and a bit to set, eg.
#define CAP_PDKILL CAPRIGHT(1, 0x0000000000000800ULL)
We still support aliases that combine few rights, but the rights have to belong
to the same array element, eg:
#define CAP_LOOKUP CAPRIGHT(0, 0x0000000000000400ULL)
#define CAP_FCHMOD CAPRIGHT(0, 0x0000000000002000ULL)
#define CAP_FCHMODAT (CAP_FCHMOD | CAP_LOOKUP)
There is new API to manage the new cap_rights_t structure:
cap_rights_t *cap_rights_init(cap_rights_t *rights, ...);
void cap_rights_set(cap_rights_t *rights, ...);
void cap_rights_clear(cap_rights_t *rights, ...);
bool cap_rights_is_set(const cap_rights_t *rights, ...);
bool cap_rights_is_valid(const cap_rights_t *rights);
void cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src);
void cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src);
bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little);
Capability rights to the cap_rights_init(), cap_rights_set(),
cap_rights_clear() and cap_rights_is_set() functions are provided by
separating them with commas, eg:
cap_rights_t rights;
cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT);
There is no need to terminate the list of rights, as those functions are
actually macros that take care of the termination, eg:
#define cap_rights_set(rights, ...) \
__cap_rights_set((rights), __VA_ARGS__, 0ULL)
void __cap_rights_set(cap_rights_t *rights, ...);
Thanks to using one bit as an array index we can assert in those functions that
there are no two rights belonging to different array elements provided
together. For example this is illegal and will be detected, because CAP_LOOKUP
belongs to element 0 and CAP_PDKILL to element 1:
cap_rights_init(&rights, CAP_LOOKUP | CAP_PDKILL);
Providing several rights that belongs to the same array's element this way is
correct, but is not advised. It should only be used for aliases definition.
This commit also breaks compatibility with some existing Capsicum system calls,
but I see no other way to do that. This should be fine as Capsicum is still
experimental and this change is not going to 9.x.
Sponsored by: The FreeBSD Foundation
2013-09-05 00:09:56 +00:00
|
|
|
cap_rights_t rights;
|
2002-01-13 11:58:06 +00:00
|
|
|
struct file *fp;
|
2002-01-14 00:13:45 +00:00
|
|
|
int error;
|
1995-10-10 07:27:24 +00:00
|
|
|
|
Change the cap_rights_t type from uint64_t to a structure that we can extend
in the future in a backward compatible (API and ABI) way.
The cap_rights_t represents capability rights. We used to use one bit to
represent one right, but we are running out of spare bits. Currently the new
structure provides place for 114 rights (so 50 more than the previous
cap_rights_t), but it is possible to grow the structure to hold at least 285
rights, although we can make it even larger if 285 rights won't be enough.
The structure definition looks like this:
struct cap_rights {
uint64_t cr_rights[CAP_RIGHTS_VERSION + 2];
};
The initial CAP_RIGHTS_VERSION is 0.
The top two bits in the first element of the cr_rights[] array contain total
number of elements in the array - 2. This means if those two bits are equal to
0, we have 2 array elements.
The top two bits in all remaining array elements should be 0.
The next five bits in all array elements contain array index. Only one bit is
used and bit position in this five-bits range defines array index. This means
there can be at most five array elements in the future.
To define new right the CAPRIGHT() macro must be used. The macro takes two
arguments - an array index and a bit to set, eg.
#define CAP_PDKILL CAPRIGHT(1, 0x0000000000000800ULL)
We still support aliases that combine few rights, but the rights have to belong
to the same array element, eg:
#define CAP_LOOKUP CAPRIGHT(0, 0x0000000000000400ULL)
#define CAP_FCHMOD CAPRIGHT(0, 0x0000000000002000ULL)
#define CAP_FCHMODAT (CAP_FCHMOD | CAP_LOOKUP)
There is new API to manage the new cap_rights_t structure:
cap_rights_t *cap_rights_init(cap_rights_t *rights, ...);
void cap_rights_set(cap_rights_t *rights, ...);
void cap_rights_clear(cap_rights_t *rights, ...);
bool cap_rights_is_set(const cap_rights_t *rights, ...);
bool cap_rights_is_valid(const cap_rights_t *rights);
void cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src);
void cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src);
bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little);
Capability rights to the cap_rights_init(), cap_rights_set(),
cap_rights_clear() and cap_rights_is_set() functions are provided by
separating them with commas, eg:
cap_rights_t rights;
cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT);
There is no need to terminate the list of rights, as those functions are
actually macros that take care of the termination, eg:
#define cap_rights_set(rights, ...) \
__cap_rights_set((rights), __VA_ARGS__, 0ULL)
void __cap_rights_set(cap_rights_t *rights, ...);
Thanks to using one bit as an array index we can assert in those functions that
there are no two rights belonging to different array elements provided
together. For example this is illegal and will be detected, because CAP_LOOKUP
belongs to element 0 and CAP_PDKILL to element 1:
cap_rights_init(&rights, CAP_LOOKUP | CAP_PDKILL);
Providing several rights that belongs to the same array's element this way is
correct, but is not advised. It should only be used for aliases definition.
This commit also breaks compatibility with some existing Capsicum system calls,
but I see no other way to do that. This should be fine as Capsicum is still
experimental and this change is not going to 9.x.
Sponsored by: The FreeBSD Foundation
2013-09-05 00:09:56 +00:00
|
|
|
error = fget(td, td->td_retval[0],
|
|
|
|
cap_rights_init(&rights, CAP_IOCTL), &fp);
|
2001-01-23 23:59:38 +00:00
|
|
|
PROC_UNLOCK(p);
|
2002-01-14 00:13:45 +00:00
|
|
|
if (error)
|
2002-01-13 11:58:06 +00:00
|
|
|
return (EBADF);
|
|
|
|
|
1995-10-10 07:27:24 +00:00
|
|
|
/* ignore any error, just give it a try */
|
|
|
|
if (fp->f_type == DTYPE_VNODE)
|
2002-08-17 02:36:16 +00:00
|
|
|
fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred,
|
|
|
|
td);
|
2002-01-13 11:58:06 +00:00
|
|
|
fdrop(fp, td);
|
2001-01-23 23:59:38 +00:00
|
|
|
} else
|
|
|
|
PROC_UNLOCK(p);
|
1995-10-10 07:27:24 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2001-09-12 08:38:13 +00:00
|
|
|
ibcs2_creat(td, uap)
|
|
|
|
struct thread *td;
|
1995-10-10 07:27:24 +00:00
|
|
|
struct ibcs2_creat_args *uap;
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
{
|
|
|
|
char *path;
|
|
|
|
int error;
|
1995-10-10 07:27:24 +00:00
|
|
|
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
CHECKALTCREAT(td, uap->path, &path);
|
|
|
|
error = kern_open(td, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC,
|
|
|
|
uap->mode);
|
|
|
|
free(path, M_TEMP);
|
|
|
|
return (error);
|
1995-10-10 07:27:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2001-09-12 08:38:13 +00:00
|
|
|
ibcs2_access(td, uap)
|
|
|
|
struct thread *td;
|
1995-10-10 07:27:24 +00:00
|
|
|
struct ibcs2_access_args *uap;
|
|
|
|
{
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
char *path;
|
|
|
|
int error;
|
1995-10-10 07:27:24 +00:00
|
|
|
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
CHECKALTEXIST(td, uap->path, &path);
|
2011-11-19 06:35:15 +00:00
|
|
|
error = kern_access(td, path, UIO_SYSSPACE, uap->amode);
|
- Implement ibcs2_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
pointer rather than a user space pointer. This required changing the
arguments to the CHECKALT*() macros some and changing the various system
calls that used pathnames to use the kern_foo() functions that can accept
kernel space filename pointers instead of calling the system call
directly.
- Use kern_open(), kern_access(), kern_execve(), kern_mkfifo(), kern_mknod(),
kern_setitimer(), kern_getrusage(), kern_utimes(), kern_unlink(),
kern_chdir(), kern_chmod(), kern_chown(), kern_symlink(), kern_readlink(),
kern_select(), kern_statfs(), kern_fstatfs(), kern_stat(), kern_lstat(),
kern_fstat().
- Drop the unused 'uap' argument from spx_open().
- Replace a stale duplication of vn_access() in xenix_access() lacking
recent additions such as MAC checks, etc. with a call to kern_access().
2005-02-07 22:02:18 +00:00
|
|
|
free(path, M_TEMP);
|
|
|
|
return (error);
|
1995-10-10 07:27:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2001-09-12 08:38:13 +00:00
|
|
|
ibcs2_fcntl(td, uap)
|
|
|
|
struct thread *td;
|
1995-10-10 07:27:24 +00:00
|
|
|
struct ibcs2_fcntl_args *uap;
|
|
|
|
{
|
2004-08-24 20:21:21 +00:00
|
|
|
intptr_t arg;
|
1995-10-10 07:27:24 +00:00
|
|
|
int error;
|
2004-08-24 20:21:21 +00:00
|
|
|
struct flock fl;
|
1995-10-10 07:27:24 +00:00
|
|
|
struct ibcs2_flock ifl;
|
2004-08-24 20:21:21 +00:00
|
|
|
|
|
|
|
arg = (intptr_t)uap->arg;
|
2002-12-14 01:56:26 +00:00
|
|
|
switch(uap->cmd) {
|
1995-10-10 07:27:24 +00:00
|
|
|
case IBCS2_F_DUPFD:
|
2004-08-24 20:21:21 +00:00
|
|
|
return (kern_fcntl(td, uap->fd, F_DUPFD, arg));
|
1995-10-10 07:27:24 +00:00
|
|
|
case IBCS2_F_GETFD:
|
2004-08-24 20:21:21 +00:00
|
|
|
return (kern_fcntl(td, uap->fd, F_GETFD, arg));
|
1995-10-10 07:27:24 +00:00
|
|
|
case IBCS2_F_SETFD:
|
2004-08-24 20:21:21 +00:00
|
|
|
return (kern_fcntl(td, uap->fd, F_SETFD, arg));
|
1995-10-10 07:27:24 +00:00
|
|
|
case IBCS2_F_GETFL:
|
2004-08-24 20:21:21 +00:00
|
|
|
error = kern_fcntl(td, uap->fd, F_GETFL, arg);
|
1995-10-10 07:27:24 +00:00
|
|
|
if (error)
|
|
|
|
return error;
|
2001-09-12 08:38:13 +00:00
|
|
|
td->td_retval[0] = oflags2ioflags(td->td_retval[0]);
|
1995-10-10 07:27:24 +00:00
|
|
|
return error;
|
|
|
|
case IBCS2_F_SETFL:
|
2004-08-24 20:21:21 +00:00
|
|
|
return (kern_fcntl(td, uap->fd, F_SETFL,
|
|
|
|
ioflags2oflags(arg)));
|
1995-10-10 07:27:24 +00:00
|
|
|
|
|
|
|
case IBCS2_F_GETLK:
|
|
|
|
{
|
2002-12-14 01:56:26 +00:00
|
|
|
error = copyin((caddr_t)uap->arg, (caddr_t)&ifl,
|
1995-10-10 07:27:24 +00:00
|
|
|
ibcs2_flock_len);
|
|
|
|
if (error)
|
|
|
|
return error;
|
2004-08-24 20:21:21 +00:00
|
|
|
cvt_iflock2flock(&ifl, &fl);
|
|
|
|
error = kern_fcntl(td, uap->fd, F_GETLK, (intptr_t)&fl);
|
1995-10-10 07:27:24 +00:00
|
|
|
if (error)
|
|
|
|
return error;
|
2004-08-24 20:21:21 +00:00
|
|
|
cvt_flock2iflock(&fl, &ifl);
|
2002-12-14 01:56:26 +00:00
|
|
|
return copyout((caddr_t)&ifl, (caddr_t)uap->arg,
|
1995-10-10 07:27:24 +00:00
|
|
|
ibcs2_flock_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
case IBCS2_F_SETLK:
|
|
|
|
{
|
2002-12-14 01:56:26 +00:00
|
|
|
error = copyin((caddr_t)uap->arg, (caddr_t)&ifl,
|
1995-10-10 07:27:24 +00:00
|
|
|
ibcs2_flock_len);
|
|
|
|
if (error)
|
|
|
|
return error;
|
2004-08-24 20:21:21 +00:00
|
|
|
cvt_iflock2flock(&ifl, &fl);
|
|
|
|
return (kern_fcntl(td, uap->fd, F_SETLK, (intptr_t)&fl));
|
1995-10-10 07:27:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case IBCS2_F_SETLKW:
|
|
|
|
{
|
2002-12-14 01:56:26 +00:00
|
|
|
error = copyin((caddr_t)uap->arg, (caddr_t)&ifl,
|
1995-10-10 07:27:24 +00:00
|
|
|
ibcs2_flock_len);
|
|
|
|
if (error)
|
|
|
|
return error;
|
2004-08-24 20:21:21 +00:00
|
|
|
cvt_iflock2flock(&ifl, &fl);
|
|
|
|
return (kern_fcntl(td, uap->fd, F_SETLKW, (intptr_t)&fl));
|
1995-10-10 07:27:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return ENOSYS;
|
|
|
|
}
|