Hi,
I found out that dazuko cannot be compiled on freebsd7.x. I created a
quick patch which is attached. It is made against the latest
dazuko-2.3.6 version. I tested it with the example utility shipped
within the dazuko package and it works fine. Basically the code for
freebsd7 is taken from dazukofs_freebsd5.c file. There are just small
changes in syscall table hooking. I created a new file
called dazuko_freebsd7.c to avoid ifdefs.
How to proceed.
1) copy dazuko-2.3.6-freebsd7.patch to the dazuko-2.3.6 source code
2) in dazuko-2.3.6 apply patch
$ patch -p1 < dazuko-2.3.6-freebsd7.patch
3) configure and make as usual
-FH
diff -Nru dazuko-2.3.6a/configure dazuko-2.3.6b/configure
--- dazuko-2.3.6a/configure 2008-07-17 20:00:33.000000000 +0200
+++ dazuko-2.3.6b/configure 2009-03-07 15:16:10.000000000 +0100
@@ -56,7 +56,8 @@
echo " --redirfsdir=DIR RedirFS development files"
echo " --system=SYS configure for system SYS (linux22,linux24,linux26,"
echo " freebsd4,freebsd5"
- echo " freebsd6,dummyos)"
+ echo " freebsd6,freebsd7)"
+ echo " dummyos)"
echo ""
echo "optional features"
echo " --disable-FEATURE do not include FEATURE"
@@ -1155,9 +1156,17 @@
if [ ${FREEBSD_VERSION} -eq 4 ]
then
DAZUKO_EXT_C="dazuko_freebsd.c"
- else
+ elif [ ${FREEBSD_VERSION} -eq 5 ]
+ then
echo "CFLAGS += -DFREEBSD5_SUPPORT" >> Makefile
DAZUKO_EXT_C="dazuko_freebsd5.c"
+ elif [ ${FREEBSD_VERSION} -eq 6 ]
+ then
+ echo "CFLAGS += -DFREEBSD5_SUPPORT" >> Makefile
+ DAZUKO_EXT_C="dazuko_freebsd5.c"
+ else
+ echo "CFLAGS += -DFREEBSD7_SUPPORT" >> Makefile
+ DAZUKO_EXT_C="dazuko_freebsd7.c"
fi
if [ ${DEBUG} -eq 1 ]
@@ -1247,6 +1256,12 @@
echo ".include <bsd.kmod.mk>" >> Makefile
}
+do_freebsd7()
+{
+ FREEBSD_VERSION=7
+ do_freebsd
+}
+
do_freebsd6()
{
FREEBSD_VERSION=6
@@ -1799,6 +1814,10 @@
UNAME="FreeBSD"
UNAME_R="6.x"
;;
+ freebsd7)
+ UNAME="FreeBSD"
+ UNAME_R="7.x"
+ ;;
dummyos)
UNAME="DummyOS"
UNAME_R="0.x"
@@ -2076,9 +2095,12 @@
elif echo $UNAME_R | grep -qi ^6\.
then
SYSTEM="freebsd6"
+ elif echo $UNAME_R | grep -qi ^7\.
+ then
+ SYSTEM="freebsd7"
else
- # default to FreeBSD 6
- SYSTEM="freebsd6"
+ # default to FreeBSD 7
+ SYSTEM="freebsd7"
fi
fi
fi
diff -Nru dazuko-2.3.6a/dazuko_freebsd7.c dazuko-2.3.6b/dazuko_freebsd7.c
--- dazuko-2.3.6a/dazuko_freebsd7.c 1970-01-01 01:00:00.000000000 +0100
+++ dazuko-2.3.6b/dazuko_freebsd7.c 2009-03-07 14:56:03.000000000 +0100
@@ -0,0 +1,1772 @@
+/* Dazuko FreeBSD. Allow FreeBSD file access control for 3rd-party applications.
+ Written by John Ogness <[email protected]>
+
+ Copyright (c) 2004, 2005 H+BEDV Datentechnik GmbH
+ Copyright (c) 2006 Avira GmbH
+ 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. Neither the name of Dazuko nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+*/
+
+
+#include <sys/types.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/proc.h>
+#include <sys/ioccom.h>
+#include <sys/malloc.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <sys/syscall.h>
+#include <sys/filio.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/sx.h>
+
+#include <sys/namei.h>
+#include <sys/param.h>
+#include <sys/vnode.h>
+
+#include "dazuko_freebsd5.h"
+#include "dazuko_core.h"
+
+
+d_read_t freebsd_dazuko_device_read;
+d_write_t freebsd_dazuko_device_write;
+d_open_t freebsd_dazuko_device_open;
+d_close_t freebsd_dazuko_device_close;
+
+extern struct xp_atomic active;
+
+static int syscall_in_use = 0;
+static int dev_major = 0;
+static struct cdev *sdev = NULL;
+
+#define AS(name) (sizeof(struct name) / sizeof(register_t))
+
+#if defined(ON_OPEN_SUPPORT)
+static int freebsd_dazuko_sys_open(struct thread *t, struct open_args *uap);
+static struct sysent freebsd_dazuko_sys_open_sysent = { AS(open_args), (sy_call_t *)freebsd_dazuko_sys_open, AUE_OPEN_RWTC, NULL, 0, 0 };
+static sy_call_t *original_sys_open = NULL;
+
+static int freebsd_dazuko_sys_dup(struct thread *t, struct dup_args *uap);
+static struct sysent freebsd_dazuko_sys_dup_sysent = { AS(dup_args), (sy_call_t *)freebsd_dazuko_sys_dup, AUE_DUP, NULL, 0, 0 };
+static sy_call_t *original_sys_dup = NULL;
+#endif
+
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+static int freebsd_dazuko_sys_dup2(struct thread *t, struct dup2_args *uap);
+static struct sysent freebsd_dazuko_sys_dup2_sysent = { AS(dup2_args), (sy_call_t *)freebsd_dazuko_sys_dup2, AUE_DUP2, NULL, 0, 0 };
+static sy_call_t *original_sys_dup2 = NULL;
+#endif
+
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+static int freebsd_dazuko_sys_close(struct thread *t, struct close_args *uap);
+static struct sysent freebsd_dazuko_sys_close_sysent = { AS(close_args), (sy_call_t *)freebsd_dazuko_sys_close, AUE_CLOSE, NULL, 0, 0 };
+static sy_call_t *original_sys_close = NULL;
+#endif
+
+#ifdef ON_EXEC_SUPPORT
+static int freebsd_dazuko_sys_execve(struct thread *t, struct execve_args *uap);
+static struct sysent freebsd_dazuko_sys_execve_sysent = { AS(execve_args), (sy_call_t *)freebsd_dazuko_sys_execve, AUE_EXECVE, NULL, 0, 0 };
+static sy_call_t *original_sys_execve = NULL;
+#endif
+
+#ifdef ON_UNLINK_SUPPORT
+static int freebsd_dazuko_sys_unlink(struct thread *t, struct unlink_args *uap);
+static struct sysent freebsd_dazuko_sys_unlink_sysent = { AS(unlink_args), (sy_call_t *)freebsd_dazuko_sys_unlink, AUE_UNLINK, NULL, 0, 0 };
+static sy_call_t *original_sys_unlink = NULL;
+#endif
+
+#ifdef ON_RMDIR_SUPPORT
+static int freebsd_dazuko_sys_rmdir(struct thread *t, struct rmdir_args *uap);
+static struct sysent freebsd_dazuko_sys_rmdir_sysent = { AS(rmdir_args), (sy_call_t *)freebsd_dazuko_sys_rmdir, AUE_RMDIR, NULL, 0, 0 };
+static sy_call_t *original_sys_rmdir = NULL;
+#endif
+
+static struct vnode *orig_rootmnt = NULL;
+
+static struct cdevsw cdepts = {
+ .d_open = freebsd_dazuko_device_open,
+ .d_close = freebsd_dazuko_device_close,
+ .d_read = freebsd_dazuko_device_read,
+ .d_write = freebsd_dazuko_device_write,
+ .d_name = DEVICE_NAME,
+#if defined(D_VERSION)
+ .d_version = D_VERSION,
+#endif
+};
+
+
+MALLOC_DECLARE(M_DAZUKOBUF);
+MALLOC_DEFINE(M_DAZUKOBUF, "dazukobuffer", "buffer for dazuko module");
+
+
+static inline int freebsd_getpid(struct thread *t)
+{
+ if (t == NULL)
+ {
+ xp_print("dazuko: warning: freebsd_getpid(NULL)\n");
+ return -1;
+ }
+
+ if (t->td_proc == NULL)
+ {
+ xp_print("dazuko: warning: freebsd_getpid.t->td_proc=NULL\n");
+ return -1;
+ }
+
+ return t->td_proc->p_pid;
+}
+
+static inline void freebsd5_setupid(struct xp_daemon_id *xp_id, struct thread *t)
+{
+ if (xp_id == NULL || t == NULL)
+ {
+ xp_print("dazuko: warning: freebsd5_setupid() received NULL\n");
+ return;
+ }
+
+ if (t->td_proc == NULL)
+ {
+ xp_print("dazuko: warning: freebsd5_setupid().td_proc == NULL\n");
+ return;
+ }
+
+ if (t->td_proc->p_fd == NULL)
+ {
+ xp_print("dazuko: warning: freebsd5_setupid().td_proc.p_fd == NULL\n");
+ return;
+ }
+
+ xp_id->proc = t->td_proc;
+ xp_id->pid = t->td_proc->p_pid;
+ xp_id->fd = t->td_proc->p_fd;
+}
+
+
+/* mutex */
+
+inline void xp_init_mutex(struct xp_mutex *mutex)
+{
+ mtx_init(&(mutex->lock), DEVICE_NAME, NULL, MTX_DEF);
+}
+
+inline void xp_down(struct xp_mutex *mutex)
+{
+ mtx_lock(&(mutex->lock));
+}
+
+inline void xp_up(struct xp_mutex *mutex)
+{
+ mtx_unlock(&(mutex->lock));
+}
+
+inline void xp_destroy_mutex(struct xp_mutex *mutex)
+{
+ mtx_destroy(&(mutex->lock));
+}
+
+
+/* read-write lock */
+
+inline void xp_init_rwlock(struct xp_rwlock *rwlock)
+{
+ lockinit(&(rwlock->lock), PVM, DEVICE_NAME, 0, 0);
+}
+
+inline void xp_write_lock(struct xp_rwlock *rwlock)
+{
+ lockmgr(&(rwlock->lock), LK_EXCLUSIVE, 0, curthread);
+}
+
+inline void xp_write_unlock(struct xp_rwlock *rwlock)
+{
+ lockmgr(&(rwlock->lock), LK_RELEASE, 0, curthread);
+}
+
+inline void xp_read_lock(struct xp_rwlock *rlock)
+{
+ lockmgr(&(rlock->lock), LK_SHARED, 0, curthread);
+}
+
+inline void xp_read_unlock(struct xp_rwlock *rlock)
+{
+ lockmgr(&(rlock->lock), LK_RELEASE, 0, curthread);
+}
+
+inline void xp_destroy_rwlock(struct xp_rwlock *rwlock)
+{
+ lockdestroy(&(rwlock->lock));
+}
+
+
+/* wait-notify queue */
+
+inline int xp_init_queue(struct xp_queue *queue)
+{
+ xp_init_mutex(&(queue->mutex));
+
+ return 0;
+}
+
+inline int xp_wait_until_condition(struct xp_queue *queue, int (*cfunction)(void *), void *cparam, int allow_interrupt)
+{
+ int rc = 0;
+ int prio = PVM;
+
+ if (allow_interrupt)
+ prio |= PCATCH;
+
+/* DOWN */
+ xp_down(&(queue->mutex));
+
+ for (;;)
+ {
+
+ if (cfunction(cparam))
+ break;
+
+ if (msleep(queue, &(queue->mutex.lock), prio, DEVICE_NAME, 0) != 0) /* UP+DOWN */
+ {
+ rc = -1;
+ break;
+ }
+ }
+
+ xp_up(&(queue->mutex));
+/* UP */
+
+ return rc;
+}
+
+inline int xp_notify(struct xp_queue *queue)
+{
+/* DOWN */
+ xp_down(&(queue->mutex));
+
+ wakeup(queue);
+
+ xp_up(&(queue->mutex));
+/* UP */
+
+ return 0;
+}
+
+inline int xp_destroy_queue(struct xp_queue *queue)
+{
+ xp_destroy_mutex(&(queue->mutex));
+
+ return 0;
+}
+
+
+/* memory */
+
+inline void* xp_malloc(size_t size)
+{
+ return malloc(size, M_DAZUKOBUF, M_WAITOK);
+}
+
+inline int xp_free(void *ptr)
+{
+ free(ptr, M_DAZUKOBUF);
+
+ return 0;
+}
+
+inline int xp_copyin(const void *user_src, void *kernel_dest, size_t size)
+{
+ return copyin(user_src, kernel_dest, size);
+}
+
+inline int xp_copyout(const void *kernel_src, void *user_dest, size_t size)
+{
+ return copyout(kernel_src, user_dest, size);
+}
+
+inline int xp_verify_user_writable(const void *user_ptr, size_t size)
+{
+ return 0;
+}
+
+inline int xp_verify_user_readable(const void *user_ptr, size_t size)
+{
+ return 0;
+}
+
+
+/* path attribute */
+
+inline int xp_is_absolute_path(const char *path)
+{
+ return (path[0] == '/');
+}
+
+
+/* atomic */
+
+inline int xp_atomic_set(struct xp_atomic *atomic, int value)
+{
+ atomic->value = value;
+
+ return 0;
+}
+
+inline int xp_atomic_inc(struct xp_atomic *atomic)
+{
+ (atomic->value)++;
+
+ return 0;
+}
+
+inline int xp_atomic_dec(struct xp_atomic *atomic)
+{
+ (atomic->value)--;
+
+ return 0;
+}
+
+inline int xp_atomic_read(struct xp_atomic *atomic)
+{
+ return atomic->value;
+}
+
+
+/* file structure */
+
+static void freebsd_get_filename_full_fileinfo(struct thread *t, const char *path, char **fullpath, char **freefullpath, struct file_properties *file_p, int follow_symlinks)
+{
+ struct thread localt;
+ struct proc localp;
+ struct nameidata nd;
+ struct filedesc localfd;
+ struct vattr vattr;
+ int error = 0;
+
+ if (t == NULL || path == NULL || fullpath == NULL || freefullpath == NULL || file_p == NULL)
+ return;
+
+ dazuko_bzero(&nd, sizeof(nd));
+ dazuko_bzero(&localt, sizeof(localt));
+ dazuko_bzero(&localp, sizeof(localp));
+ dazuko_bzero(&localfd, sizeof(localfd));
+ dazuko_bzero(file_p, sizeof(struct file_properties));
+
+ NDINIT(&nd, LOOKUP, follow_symlinks ? FOLLOW : NOFOLLOW, UIO_USERSPACE, path, t);
+
+ error = namei(&nd);
+
+ if (error != 0)
+ {
+ if (error == ENOENT)
+ {
+ /* let's try to resolve the parent dir (if possible) */
+ char * kpath = xp_malloc(MAXPATHLEN+1);
+ char * fname = kpath;
+ char * lookuppath = ".";
+ char * pfullpath = NULL;
+ char * pfreefullpath = NULL;
+ size_t len;
+ int i;
+ struct nameidata ndparent;
+
+ if (kpath == NULL)
+ return;
+
+ dazuko_bzero(kpath, MAXPATHLEN+1);
+ copyinstr(path, kpath, MAXPATHLEN+1, &len);
+
+ /* find the last "/" */
+ for (i=strlen(kpath) ; i>=0 ; i--)
+ {
+ if (kpath[i] == '/')
+ {
+ if (i == 0)
+ {
+ /* the only "/" is the root */
+ lookuppath = "/";
+ }
+ else
+ {
+ kpath[i] = 0;
+ lookuppath = kpath;
+ }
+
+ fname = kpath + i + 1;
+
+ break;
+ }
+ }
+
+ /* at this point we have:
+ * lookuppath = the name of the parent directory to lookup
+ * fname = the file name that was not found by the previous namei
+ */
+
+ dazuko_bzero(&ndparent, sizeof(ndparent));
+
+ NDINIT(&ndparent, LOOKUP, NOFOLLOW, UIO_SYSSPACE, lookuppath, t);
+
+ error = namei(&ndparent);
+
+ if (error)
+ {
+ xp_free(kpath);
+ return;
+ }
+
+ if (ndparent.ni_vp != NULL)
+ {
+ localt.td_proc = &localp;
+ localt.td_proc->p_fd = &localfd;
+ localt.td_proc->p_fd->fd_sx = t->td_proc->p_fd->fd_sx;
+
+ if (orig_rootmnt != NULL)
+ localt.td_proc->p_fd->fd_rdir = orig_rootmnt;
+ else
+ localt.td_proc->p_fd->fd_rdir = ndparent.ni_rootdir;
+
+ vn_fullpath(&localt, ndparent.ni_vp, &pfullpath, &pfreefullpath);
+
+ if (pfreefullpath != NULL)
+ {
+ len = strlen(pfullpath) + strlen(fname) + 2;
+ *fullpath = malloc(len, M_TEMP, M_WAITOK);
+ if (*fullpath != NULL)
+ {
+ strcpy(*fullpath, pfullpath);
+
+ /* we don't add "/" if it is root */
+ if ((pfullpath[0] != '/') || (pfullpath[1] != 0))
+ strcat(*fullpath, "/");
+
+ strcat(*fullpath, fname);
+
+ *freefullpath = *fullpath;
+ }
+ free(pfreefullpath, M_TEMP);
+ }
+ }
+
+ NDFREE(&ndparent, 0);
+ xp_free(kpath);
+ }
+ else
+ {
+ /*
+ * we need to understand why this fails sometimes
+ */
+ }
+ }
+ else
+ {
+ localt.td_proc = &localp;
+ localt.td_proc->p_fd = &localfd;
+ localt.td_proc->p_fd->fd_sx = t->td_proc->p_fd->fd_sx;
+
+ if (orig_rootmnt != NULL)
+ localt.td_proc->p_fd->fd_rdir = orig_rootmnt;
+ else
+ localt.td_proc->p_fd->fd_rdir = nd.ni_rootdir;
+
+ vn_fullpath(&localt, nd.ni_vp, fullpath, freefullpath);
+
+ if (nd.ni_vp != NULL)
+ {
+ if (VOP_GETATTR(nd.ni_vp, &vattr, t->td_proc->p_ucred, t) == 0)
+ {
+ file_p->size = vattr.va_size;
+ file_p->set_size = 1;
+ file_p->uid = vattr.va_uid;
+ file_p->set_uid = 1;
+ file_p->gid = vattr.va_gid;
+ file_p->set_gid = 1;
+ file_p->mode = vattr.va_mode;
+ file_p->set_mode = 1;
+ file_p->device_type = vattr.va_fsid;
+ file_p->set_device_type = 1;
+
+ switch (nd.ni_vp->v_type)
+ {
+ case VDIR:
+ file_p->type = DAZUKO_DIRECTORY;
+ file_p->set_type = 1;
+ break;
+ case VREG:
+ file_p->type = DAZUKO_REGULAR;
+ file_p->set_type = 1;
+ break;
+ case VLNK:
+ file_p->type = DAZUKO_LINK;
+ file_p->set_type = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /* deref looked up vnode */
+ NDFREE(&nd, 0);
+ }
+}
+
+static void freebsd_get_fd_full_fileinfo(struct thread *t, int fd, char **fullpath, char **freefullpath, struct file_properties *file_p)
+{
+ struct thread localt;
+ struct proc localp;
+ struct filedesc localfd;
+ struct vattr vattr;
+ struct file *fp;
+ struct vnode *vp;
+
+ if (t == NULL || fullpath == NULL || freefullpath == NULL || file_p == NULL || orig_rootmnt == NULL)
+ return;
+
+ if (t->td_proc == NULL)
+ return;
+
+ if (t->td_proc->p_fd == NULL)
+ return;
+
+ if (getvnode(t->td_proc->p_fd, fd, &fp) != 0)
+ return;
+
+ if (fp == NULL)
+ {
+ fdrop(fp, t);
+ return;
+ }
+
+ vp = fp->f_vnode;
+
+ if (vp == NULL)
+ {
+ fdrop(fp, t);
+ return;
+ }
+
+ dazuko_bzero(&localt, sizeof(localt));
+ dazuko_bzero(&localp, sizeof(localp));
+ dazuko_bzero(&localfd, sizeof(localfd));
+ dazuko_bzero(file_p, sizeof(struct file_properties));
+
+ localt.td_proc = &localp;
+ localt.td_proc->p_fd = &localfd;
+ localt.td_proc->p_fd->fd_sx = t->td_proc->p_fd->fd_sx;
+
+ localt.td_proc->p_fd->fd_rdir = orig_rootmnt;
+
+ vn_fullpath(&localt, vp, fullpath, freefullpath);
+
+ if (VOP_GETATTR(vp, &vattr, t->td_proc->p_ucred, t) == 0)
+ {
+ file_p->size = vattr.va_size;
+ file_p->set_size = 1;
+ file_p->uid = vattr.va_uid;
+ file_p->set_uid = 1;
+ file_p->gid = vattr.va_gid;
+ file_p->set_gid = 1;
+ file_p->mode = vattr.va_mode;
+ file_p->set_mode = 1;
+ file_p->device_type = vattr.va_fsid;
+ file_p->set_device_type = 1;
+
+ switch (vp->v_type)
+ {
+ case VDIR:
+ file_p->type = DAZUKO_DIRECTORY;
+ file_p->set_type = 1;
+ break;
+ case VREG:
+ file_p->type = DAZUKO_REGULAR;
+ file_p->set_type = 1;
+ break;
+ case VLNK:
+ file_p->type = DAZUKO_LINK;
+ file_p->set_type = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ fdrop(fp, t);
+}
+
+inline int xp_fill_file_struct(struct dazuko_file_struct *dfs)
+{
+ char *fullpath = NULL;
+ char *freefullpath = NULL;
+ int length;
+ struct dazuko_file_listnode *listnode;
+ int follow_symlinks = 0;
+ int error = 0;
+ int loopcount = 0;
+
+ if (dfs == NULL)
+ return -1;
+
+ /* check if filenames have already been filled in */
+ if (dfs->aliases != NULL)
+ return 0;
+
+ if (dfs->extra_data == NULL)
+ return -1;
+
+ while (1)
+ {
+ loopcount++;
+
+ listnode = (struct dazuko_file_listnode *)xp_malloc(sizeof(struct dazuko_file_listnode));
+ if (listnode == NULL)
+ {
+ error = -1;
+ break;
+ }
+
+ dazuko_bzero(listnode, sizeof(struct dazuko_file_listnode));
+
+ if (dfs->extra_data->user_filename != NULL)
+ {
+ freebsd_get_filename_full_fileinfo(dfs->extra_data->t, dfs->extra_data->user_filename, &fullpath, &freefullpath, &(dfs->file_p), follow_symlinks);
+ }
+ else
+ {
+ freebsd_get_fd_full_fileinfo(dfs->extra_data->t, dfs->extra_data->fd, &fullpath, &freefullpath, &(dfs->file_p));
+
+ /* make sure we don't loop a 2nd time */
+ loopcount++;
+ }
+
+ if (freefullpath)
+ {
+ length = dazuko_strlen(fullpath);
+
+ listnode->filename = (char *)xp_malloc(length + 1);
+ if (listnode->filename != NULL)
+ {
+ memcpy(listnode->filename, fullpath, length);
+ listnode->filename[length] = 0;
+ listnode->filename_length = length; /* the string length */
+ }
+
+ /* this memory is freed from a different pool than
+ * xp_malloc would use */
+
+ free(freefullpath, M_TEMP);
+ }
+
+ if (dfs->aliases == NULL)
+ {
+ listnode->next = dfs->aliases;
+ dfs->aliases = listnode;
+ }
+ else
+ {
+ listnode->next = dfs->aliases->next;
+ dfs->aliases->next = listnode;
+ }
+
+ if (!follow_symlinks && dfs->file_p.set_type && dfs->file_p.type == DAZUKO_LINK && loopcount < 2)
+ {
+ /* this is a link, we will grab the real path now */
+
+ follow_symlinks = 1;
+ }
+ else
+ {
+ /* we've grabbed the real path (or we already have 2 paths), so we are done */
+
+ break;
+ }
+ }
+
+ if (!error && dfs->aliases->filename == NULL && dfs->extra_data->user_filename != NULL)
+ {
+ /* we couldn't get any filename, so we'll just grab the user parameter
+ * note: dfs->aliases was already allocated previously, we just have to fill it */
+
+ for (length=0 ; fubyte((dfs->extra_data->user_filename)+length) ; length++);
+
+ length++;
+
+ dfs->aliases->filename = (char *)xp_malloc(length);
+ if (dfs->aliases->filename != NULL)
+ {
+ if (xp_copyin(dfs->extra_data->user_filename, dfs->aliases->filename, length) != 0)
+ {
+ xp_print("dazuko: error: xp_fill_file_struct.xp_copyin() failed\n");
+ xp_free(dfs->aliases->filename);
+ dfs->aliases->filename = NULL;
+ dfs->aliases->filename_length = 0;
+ }
+ else
+ {
+ dfs->aliases->filename_length = length - 1; /* the string length */
+ }
+ }
+ }
+
+ return error;
+}
+
+static int dazuko_file_struct_cleanup(struct dazuko_file_struct **dfs)
+{
+ struct dazuko_file_listnode *cur;
+
+ if (dfs == NULL)
+ return 0;
+
+ if (*dfs == NULL)
+ return 0;
+
+ while ((*dfs)->aliases != NULL)
+ {
+ cur = (*dfs)->aliases;
+ (*dfs)->aliases = cur->next;
+
+ if (cur->filename != NULL)
+ xp_free(cur->filename);
+
+ xp_free(cur);
+ }
+
+ if ((*dfs)->extra_data != NULL)
+ xp_free((*dfs)->extra_data);
+
+ xp_free(*dfs);
+
+ *dfs = NULL;
+
+ return 0;
+}
+
+
+/* daemon id */
+
+static inline int check_parent(struct proc *parent, struct proc *child)
+{
+ struct proc *ts = child;
+ int rc = -1;
+
+ if (parent == NULL || child == NULL)
+ return -1;
+
+/* LOCK */
+ sx_slock(&proctree_lock);
+
+ while (1)
+ {
+ if (ts == parent)
+ {
+ rc = 0;
+ break;
+ }
+
+ if (ts->p_pptr == NULL)
+ break;
+
+ if (ts == ts->p_pptr)
+ break;
+
+ ts = ts->p_pptr;
+ }
+
+ sx_sunlock(&proctree_lock);
+/* UNLOCK */
+
+ return rc;
+}
+
+inline int xp_id_compare(struct xp_daemon_id *id1, struct xp_daemon_id *id2, int check_related)
+{
+ if (id1 == NULL || id2 == NULL)
+ return DAZUKO_DIFFERENT;
+
+ if (id1->pid == id2->pid && id1->proc == id2->proc && id1->fd == id2->fd)
+ return DAZUKO_SAME;
+
+ if (check_related)
+ {
+ if (check_parent(id1->proc, id2->proc) == 0)
+ {
+ return DAZUKO_CHILD;
+ }
+ else if (id1->pid == id2->pid || id1->proc == id2->proc || id1->fd == id2->fd)
+ {
+ return DAZUKO_SUSPICIOUS;
+ }
+ }
+
+ return DAZUKO_DIFFERENT;
+}
+
+inline int xp_id_free(struct xp_daemon_id *id)
+{
+ xp_free(id);
+
+ return 0;
+}
+
+inline struct xp_daemon_id* xp_id_copy(struct xp_daemon_id *id)
+{
+ struct xp_daemon_id *ptr;
+
+ if (id == NULL)
+ return NULL;
+
+ ptr = (struct xp_daemon_id *)xp_malloc(sizeof(struct xp_daemon_id));
+
+ if (ptr != NULL)
+ {
+ ptr->pid = id->pid;
+ ptr->proc = id->proc;
+ ptr->fd = id->fd;
+ }
+
+ return ptr;
+}
+
+
+/* event */
+
+int xp_set_event_properties(struct event_properties *event_p, struct xp_daemon_id *xp_id)
+{
+ event_p->pid = xp_id->pid;
+ event_p->set_pid = 1;
+
+ return 0;
+}
+
+
+/* cache settings */
+
+int xp_init_cache(unsigned long ttl)
+{
+ return -1;
+}
+
+
+/* include/exclude paths */
+
+int xp_set_path(const char *path, int type)
+{
+ return 0;
+}
+
+
+/* system calls */
+
+static inline int check_fd(struct proc *p, int fd)
+{
+ if (p == NULL)
+ {
+ return -1;
+ }
+ else if (p->p_fd == NULL)
+ {
+ return -1;
+ }
+ else if (fd < 0)
+ {
+ return -1;
+ }
+ else if (fd >= p->p_fd->fd_nfiles)
+ {
+ return -1;
+ }
+ else if (p->p_fd->fd_ofiles == NULL)
+ {
+ return -1;
+ }
+ else if (p->p_fd->fd_ofiles[fd] == NULL)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+#define DAZUKO_SYSCALL_WRAPPER(syscall_func) static int freebsd_dazuko_sys_##syscall_func(struct thread *t, struct syscall_func##_args *uap) \
+{ \
+ int ret; \
+ syscall_in_use++; \
+ ret = freebsd_dazuko_sys_##syscall_func##_inner(t, uap); \
+ syscall_in_use--; \
+ return ret; \
+}
+
+#if defined(ON_OPEN_SUPPORT)
+static inline int freebsd_dazuko_sys_open_inner(struct thread *t, struct open_args *uap)
+{
+ struct dazuko_file_struct *dfs = NULL;
+ struct event_properties event_p;
+ struct xp_daemon_id xp_id;
+ int error = 0;
+ int check_error = 0;
+
+ if (t == NULL)
+ {
+ xp_print("dazuko: warning: freebsd_dazuko_sys_open(NULL, ...)\n");
+ check_error = -1;
+ }
+ else
+ {
+ freebsd5_setupid(&xp_id, t);
+ check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL);
+ }
+
+ if (!check_error)
+ {
+ dazuko_bzero(&event_p, sizeof(event_p));
+
+ if (uap == NULL)
+ {
+ check_error = -1;
+ }
+ else if (t->td_proc == NULL)
+ {
+ check_error = -1;
+ }
+ else if (t->td_proc->p_ucred == NULL)
+ {
+ check_error = -1;
+ }
+ else
+ {
+ event_p.flags = uap->flags;
+ event_p.set_flags = 1;
+ event_p.mode = uap->mode;
+ event_p.set_mode = 1;
+ event_p.pid = freebsd_getpid(t);
+ event_p.set_pid = 1;
+ event_p.uid = t->td_proc->p_ucred->cr_ruid;
+ event_p.set_uid = 1;
+
+ dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+ if (dfs != NULL)
+ {
+ dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+ dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+ if (dfs->extra_data != NULL)
+ {
+ dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+ dfs->extra_data->user_filename = uap->path;
+ dfs->extra_data->t = t;
+
+ error = dazuko_process_access(DAZUKO_ON_OPEN, dfs, &event_p, NULL);
+
+ dazuko_file_struct_cleanup(&dfs);
+ }
+ else
+ {
+ xp_free(dfs);
+ dfs = NULL;
+ }
+ }
+ }
+ }
+
+ if (error)
+ {
+ /* access should be blocked */
+
+ error = EPERM;
+ }
+ else
+ {
+ /* call the standard open function */
+ error = original_sys_open(t, uap);
+ }
+
+ return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(open)
+
+static inline int freebsd_dazuko_sys_dup_inner(struct thread *t, struct dup_args *uap)
+{
+ struct dazuko_file_struct *dfs = NULL;
+ int error = 0;
+ int check_error = 0;
+ struct event_properties event_p;
+ struct xp_daemon_id xp_id;
+
+ if (t == NULL)
+ {
+ xp_print("dazuko: warning: freebsd_dazuko_sys_dup(NULL, ...)\n");
+ check_error = -1;
+ }
+ else
+ {
+ freebsd5_setupid(&xp_id, t);
+ check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL);
+ }
+
+ if (!check_error)
+ {
+ if (uap == NULL)
+ {
+ check_error = -1;
+ }
+ else if (check_fd(t->td_proc, uap->fd) != 0)
+ {
+ check_error = -1;
+ }
+ else if (t->td_proc->p_ucred == NULL)
+ {
+ check_error = -1;
+ }
+ else
+ {
+ dazuko_bzero(&event_p, sizeof(event_p));
+
+ event_p.pid = freebsd_getpid(t);
+ event_p.set_pid = 1;
+ event_p.uid = t->td_proc->p_ucred->cr_ruid;
+ event_p.set_uid = 1;
+
+ dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+ if (dfs != NULL)
+ {
+ dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+ dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+ if (dfs->extra_data != NULL)
+ {
+ dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+ dfs->extra_data->fd = uap->fd;
+ dfs->extra_data->t = t;
+
+ error = dazuko_process_access(DAZUKO_ON_OPEN, dfs, &event_p, NULL);
+
+ dazuko_file_struct_cleanup(&dfs);
+ }
+ else
+ {
+ xp_free(dfs);
+ dfs = NULL;
+ }
+ }
+ }
+ }
+
+ if (error)
+ {
+ /* access should be blocked */
+
+ error = EPERM;
+ }
+ else
+ {
+ /* call the standard dup function */
+ error = original_sys_dup(t, uap);
+ }
+
+ return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(dup)
+#endif
+
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+static inline int freebsd_dazuko_sys_dup2_inner(struct thread *t, struct dup2_args *uap)
+{
+ struct dazuko_file_struct *dfs = NULL;
+ struct event_properties open_event_p;
+ struct xp_daemon_id xp_id;
+ int error = 0;
+ int open_check_error = 0;
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+ struct event_properties close_event_p;
+ int close_check_error = 0;
+ int will_close_newfd = 0;
+#endif
+
+ if (t == NULL)
+ {
+ xp_print("dazuko: warning: freebsd_dazuko_sys_dup2(NULL, ...)\n");
+ open_check_error = -1;
+ }
+ else
+ {
+ freebsd5_setupid(&xp_id, t);
+ open_check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL);
+ }
+
+ if (!open_check_error)
+ {
+ dazuko_bzero(&open_event_p, sizeof(open_event_p));
+
+ if (uap == NULL)
+ {
+ open_check_error = -1;
+ }
+ else if (uap->from == uap->to)
+ {
+ /* oldfd and newfd are equal, there is nothing to do */
+ open_check_error = -1;
+ }
+ else if (check_fd(t->td_proc, uap->from) != 0)
+ {
+ open_check_error = -1;
+ }
+ else if (t->td_proc->p_ucred == NULL)
+ {
+ open_check_error = -1;
+ }
+ else
+ {
+ open_event_p.pid = freebsd_getpid(t);
+ open_event_p.set_pid = 1;
+ open_event_p.uid = t->td_proc->p_ucred->cr_ruid;
+ open_event_p.set_uid = 1;
+
+ dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+ if (dfs != NULL)
+ {
+ dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+ dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+ if (dfs->extra_data != NULL)
+ {
+ dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+ dfs->extra_data->fd = uap->from;
+ dfs->extra_data->t = t;
+
+ error = dazuko_process_access(DAZUKO_ON_OPEN, dfs, &open_event_p, NULL);
+
+ dazuko_file_struct_cleanup(&dfs);
+ }
+ else
+ {
+ xp_free(dfs);
+ dfs = NULL;
+ }
+ }
+ }
+ }
+
+ if (error)
+ {
+ /* access should be blocked */
+
+ error = EPERM;
+ }
+ else
+ {
+ #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+ {
+ close_check_error = dazuko_check_access(DAZUKO_ON_CLOSE, 1, &xp_id, NULL);
+
+ if (!close_check_error)
+ {
+
+ if (check_fd(t->td_proc, uap->to) == 0)
+ {
+ will_close_newfd = 1;
+ }
+ }
+ }
+ #endif
+
+ /* call the standard dup2 function */
+ error = original_sys_dup2(t, uap);
+
+ #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+ {
+ if (!close_check_error)
+ {
+ if (!error && will_close_newfd && check_fd(t->td_proc, t->td_retval[0]) == 0)
+ {
+ dazuko_bzero(&close_event_p, sizeof(close_event_p));
+
+ close_event_p.pid = freebsd_getpid(t);
+ close_event_p.set_pid = 1;
+ close_event_p.uid = t->td_proc->p_ucred->cr_ruid;
+ close_event_p.set_uid = 1;
+
+ dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+ if (dfs != NULL)
+ {
+ dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+ dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+ if (dfs->extra_data != NULL)
+ {
+ dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+ dfs->extra_data->fd = t->td_retval[0];
+ dfs->extra_data->t = t;
+
+ dazuko_process_access(DAZUKO_ON_CLOSE, dfs, &close_event_p, NULL);
+
+ dazuko_file_struct_cleanup(&dfs);
+ }
+ else
+ {
+ xp_free(dfs);
+ dfs = NULL;
+ }
+ }
+ }
+ }
+ }
+ #endif
+ }
+
+ return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(dup2)
+
+#endif
+
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+static inline int freebsd_dazuko_sys_close_inner(struct thread *t, struct close_args *uap)
+{
+ /* The kernel wants to close the given file
+ * descriptor. */
+
+ struct dazuko_file_struct *dfs = NULL;
+ int error = 0;
+ int check_error = 0;
+ struct event_properties event_p;
+ struct xp_daemon_id xp_id;
+
+ if (t == NULL)
+ {
+ xp_print("dazuko: warning: freebsd_dazuko_sys_close(NULL, ...)\n");
+ check_error = -1;
+ }
+ else
+ {
+ freebsd5_setupid(&xp_id, t);
+ check_error = dazuko_check_access(DAZUKO_ON_CLOSE, 1, &xp_id, NULL);
+ }
+
+ if (!check_error)
+ {
+ if (uap == NULL)
+ {
+ check_error = -1;
+ }
+ else if (t->td_proc == NULL)
+ {
+ check_error = -1;
+ }
+ else if (t->td_proc->p_ucred == NULL)
+ {
+ check_error = -1;
+ }
+ else
+ {
+ dazuko_bzero(&event_p, sizeof(event_p));
+
+ event_p.pid = freebsd_getpid(t);
+ event_p.set_pid = 1;
+ event_p.uid = t->td_proc->p_ucred->cr_ruid;
+ event_p.set_uid = 1;
+
+ dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+ if (dfs != NULL)
+ {
+ dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+ dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+ if (dfs->extra_data != NULL)
+ {
+ dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+ dfs->extra_data->fd = uap->fd;
+ dfs->extra_data->t = t;
+
+ check_error = xp_fill_file_struct(dfs);
+ }
+ else
+ {
+ xp_free(dfs);
+ dfs = NULL;
+ }
+ }
+ }
+ }
+
+ error = original_sys_close(t, uap);
+
+ if (dfs != NULL)
+ {
+ if (!check_error)
+ {
+ dazuko_process_access(DAZUKO_ON_CLOSE, dfs, &event_p, NULL);
+ }
+
+ dazuko_file_struct_cleanup(&dfs);
+ }
+
+ return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(close)
+#endif
+
+static inline int freebsd_dazuko_sys_generic(int event, struct thread *t, const char *user_filename, int daemon_is_allowed)
+{
+ struct dazuko_file_struct *dfs = NULL;
+ struct event_properties event_p;
+ struct xp_daemon_id xp_id;
+ int error = 0;
+ int check_error = 0;
+ struct slot_list *sl = NULL;
+
+ if (t == NULL)
+ return -1;
+
+ freebsd5_setupid(&xp_id, t);
+ check_error = dazuko_check_access(event, daemon_is_allowed, &xp_id, &sl);
+
+ if (check_error == 0)
+ {
+ if (user_filename == NULL)
+ {
+ xp_print("dazuko: warning: freebsd_dazuko_sys_generic(%d, t, %s)\n", event, user_filename ? "user_filename" : "NULL");
+ check_error = -1;
+ }
+ else if (t->td_proc == NULL)
+ {
+ xp_print("dazuko: warning: freebsd_dazuko_sys_generic.t->td_proc=NULL\n");
+ check_error = -1;
+ }
+ else if (t->td_proc->p_ucred == NULL)
+ {
+ xp_print("dazuko: warning: freebsd_dazuko_sys_generic.t->td_proc->p_ucred=NULL\n");
+ check_error = -1;
+ }
+ else
+ {
+ dazuko_bzero(&event_p, sizeof(event_p));
+ event_p.pid = freebsd_getpid(t);
+ event_p.set_pid = 1;
+ event_p.uid = t->td_proc->p_ucred->cr_ruid;
+ event_p.set_uid = 1;
+
+ dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+ if (dfs != NULL)
+ {
+ dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+ dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+ if (dfs->extra_data)
+ {
+ dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+ dfs->extra_data->user_filename = user_filename;
+ dfs->extra_data->t = t;
+
+ error = dazuko_process_access(event, dfs, &event_p, sl);
+
+ dazuko_file_struct_cleanup(&dfs);
+ }
+ else
+ {
+ xp_free(dfs);
+ dfs = NULL;
+ }
+ }
+ }
+ }
+
+ return error;
+}
+
+#ifdef ON_EXEC_SUPPORT
+static inline int freebsd_dazuko_sys_execve_inner(struct thread *t, struct execve_args *uap)
+{
+ int error;
+
+ error = freebsd_dazuko_sys_generic(DAZUKO_ON_EXEC, t, uap->fname, 0);
+
+ if (error)
+ return error;
+
+ return original_sys_execve(t, uap);
+}
+
+DAZUKO_SYSCALL_WRAPPER(execve)
+#endif
+
+#ifdef ON_UNLINK_SUPPORT
+static inline int freebsd_dazuko_sys_unlink_inner(struct thread *t, struct unlink_args *uap)
+{
+ int error;
+
+ error = freebsd_dazuko_sys_generic(DAZUKO_ON_UNLINK, t, uap->path, 1);
+
+ if (error)
+ return error;
+
+ return original_sys_unlink(t, uap);
+}
+
+DAZUKO_SYSCALL_WRAPPER(unlink)
+#endif
+
+#ifdef ON_RMDIR_SUPPORT
+static inline int freebsd_dazuko_sys_rmdir_inner(struct thread *t, struct rmdir_args *uap)
+{
+ int error;
+
+ error = freebsd_dazuko_sys_generic(DAZUKO_ON_RMDIR, t, uap->path, 1);
+
+ if (error)
+ return error;
+
+ return original_sys_rmdir(t, uap);
+}
+
+DAZUKO_SYSCALL_WRAPPER(rmdir)
+#endif
+
+
+/* system hook */
+
+#define DAZUKO_HOOK(syscall_func) do \
+{ \
+ if ((sysent[SYS_##syscall_func].sy_narg) != freebsd_dazuko_sys_##syscall_func##_sysent.sy_narg) \
+ { \
+ DPRINT(("dazuko: incompatible " #syscall_func " syscall narg\n")); \
+ } \
+ else \
+ { \
+ original_sys_##syscall_func = sysent[SYS_##syscall_func].sy_call; \
+ sysent[SYS_##syscall_func].sy_call = freebsd_dazuko_sys_##syscall_func##_sysent.sy_call; \
+ DPRINT(("dazuko: hooked sys_" #syscall_func "\n")); \
+ } \
+} \
+while (0)
+
+inline int xp_sys_hook()
+{
+ sdev = make_dev(&cdepts, 0, UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME);
+
+#if defined(ON_OPEN_SUPPORT)
+ DAZUKO_HOOK(open);
+ DAZUKO_HOOK(dup);
+#endif
+
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+ DAZUKO_HOOK(dup2);
+#endif
+
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+ DAZUKO_HOOK(close);
+#endif
+
+#ifdef ON_EXEC_SUPPORT
+ DAZUKO_HOOK(execve);
+#endif
+
+#ifdef ON_UNLINK_SUPPORT
+ DAZUKO_HOOK(unlink);
+#endif
+
+#ifdef ON_RMDIR_SUPPORT
+ DAZUKO_HOOK(rmdir);
+#endif
+
+ return 0;
+}
+
+#define DAZUKO_UNHOOK(syscall_func) do \
+{ \
+ if (original_sys_##syscall_func != NULL) \
+ { \
+ if (sysent[SYS_##syscall_func].sy_call != freebsd_dazuko_sys_##syscall_func##_sysent.sy_call) \
+ xp_print("dazuko: " #syscall_func " system call has been changed (system may be left in an unstable state!)\n"); \
+ sysent[SYS_##syscall_func].sy_call = (sy_call_t*)original_sys_##syscall_func; \
+ DPRINT(("dazuko: unhooked sys_" #syscall_func "\n")); \
+ } \
+} \
+while (0)
+
+inline int xp_sys_unhook()
+{
+#if defined(ON_OPEN_SUPPORT)
+ DAZUKO_UNHOOK(open);
+ DAZUKO_UNHOOK(dup);
+#endif
+
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+ DAZUKO_UNHOOK(dup2);
+#endif
+
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+ DAZUKO_UNHOOK(close);
+#endif
+
+#ifdef ON_EXEC_SUPPORT
+ DAZUKO_UNHOOK(execve);
+#endif
+
+#ifdef ON_UNLINK_SUPPORT
+ DAZUKO_UNHOOK(unlink);
+#endif
+
+#ifdef ON_RMDIR_SUPPORT
+ DAZUKO_UNHOOK(rmdir);
+#endif
+
+ while (syscall_in_use > 0)
+ {
+ DPRINT(("syscall still in use, yielding (%d)\n", syscall_in_use));
+ yield(curthread, NULL);
+ }
+
+ destroy_dev(sdev);
+
+ return 0;
+}
+
+
+/* output */
+
+int xp_print(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+
+ return 0;
+}
+
+
+/* device file operations */
+
+int freebsd_dazuko_device_open(struct cdev *dev, int oflags, int devtype, struct thread *t)
+{
+ DPRINT(("dazuko: freebsd_dazuko_device_open() [%d]\n", freebsd_getpid(t)));
+
+ return 0;
+}
+
+static int read_dev_major(struct uio *uio)
+{
+ size_t dev_major_len;
+ char tmp[32];
+
+ if (dev_major < 0)
+ return ENODEV;
+
+ if (uio->uio_offset != 0)
+ return 0;
+
+ /* print dev_major to a string
+ * and get length */
+ dazuko_bzero(tmp, sizeof(tmp));
+
+ dev_major_len = dazuko_snprintf(tmp, sizeof(tmp), "%d", dev_major);
+
+ if (tmp[sizeof(tmp)-1] != 0)
+ {
+ xp_print("dazuko: failing device_read, device number overflow for dameon %d (dev_major=%d)\n", freebsd_getpid(uio->uio_td), dev_major);
+ return EFAULT;
+ }
+
+ if (uio->uio_iov == NULL)
+ {
+ xp_print("dazuko: error: freebsd_dazuko_device_read.uio->uio_iov=NULL\n");
+ return EFAULT;
+ }
+
+ if (uio->uio_iov->iov_len < dev_major_len)
+ return EINVAL;
+
+ /* copy dev_major string to userspace */
+ if (uiomove(tmp, dev_major_len, uio) != 0)
+ return EFAULT;
+
+ return 0;
+}
+
+int freebsd_dazuko_device_read(struct cdev *dev, struct uio *uio, int ioflag)
+{
+ struct xp_daemon_id xp_id;
+
+ if (uio == NULL)
+ {
+ xp_print("dazuko: error: freebsd_dazuko_device_read(..., NULL, ...)\n");
+ return EFAULT;
+ }
+
+ if (uio->uio_td == NULL)
+ {
+ xp_print("dazuko: error: freebsd_dazuko_device_read.uio->uio_td=NULL\n");
+ return EFAULT;
+ }
+
+ if (uio->uio_td->td_proc->p_ucred == NULL)
+ {
+ xp_print("dazuko: error: freebsd_dazuko_device_read.uio->uio_td->td_proc->p_ucred=NULL\n");
+ return EFAULT;
+ }
+
+ DPRINT(("dazuko: freebsd_dazuko_device_read() [%d]\n", freebsd_getpid(uio->uio_td)));
+
+ freebsd5_setupid(&xp_id, uio->uio_td);
+
+ /* return dev_major if process is not registered */
+ if (!dazuko_is_our_daemon(&xp_id, NULL, NULL))
+ return read_dev_major(uio);
+
+ return 0;
+}
+
+int freebsd_dazuko_device_write(struct cdev *dev, struct uio *uio, int ioflag)
+{
+ struct xp_daemon_id xp_id;
+ char buffer[32];
+ int size;
+
+ if (uio == NULL)
+ {
+ xp_print("dazuko: error: freebsd_dazuko_device_write(..., NULL, ...)\n");
+ return EFAULT;
+ }
+
+ if (uio->uio_td == NULL)
+ {
+ xp_print("dazuko: error: freebsd_dazuko_device_write.uio->uio_td=NULL\n");
+ return EFAULT;
+ }
+
+ if (uio->uio_td->td_proc->p_ucred == NULL)
+ {
+ xp_print("dazuko: error: freebsd_dazuko_device_write.uio->uio_td->td_proc->p_ucred=NULL\n");
+ return EFAULT;
+ }
+
+ size = uio->uio_resid;
+ if (size >= sizeof(buffer))
+ size = sizeof(buffer) - 1;
+
+ /* copy request_pointer string to kernelspace */
+ if (uiomove(buffer, size, uio) != 0)
+ {
+ xp_print("dazuko: error: freebsd_dazuko_device_write.uiomove!=0\n");
+ return EFAULT;
+ }
+
+ buffer[size] = 0;
+
+ freebsd5_setupid(&xp_id, uio->uio_td);
+
+ if (dazuko_handle_user_request(buffer, &xp_id) == 0)
+ return uio->uio_resid;
+ else
+ return EINTR;
+}
+
+int freebsd_dazuko_device_close(struct cdev *dev, int fflag, int devtype, struct thread *t)
+{
+ struct xp_daemon_id xp_id;
+
+ DPRINT(("dazuko: dazuko_device_close() [%d]\n", freebsd_getpid(t)));
+
+ freebsd5_setupid(&xp_id, t);
+
+ /* note: This only works for compat1 mode.
+ * For 1.3, the daemon must properly unregister.
+ */
+
+ return dazuko_unregister_daemon(&xp_id);
+}
+
+
+/* init/exit */
+
+static int dazuko_loader(struct module *m, int what, void *arg)
+{
+ int err = 0;
+ struct nameidata nd;
+
+ switch (what)
+ {
+ case MOD_LOAD:
+ err = dazuko_init();
+
+ if (!err)
+ {
+ NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, "/", curthread);
+
+ if (namei(&nd) != 0)
+ {
+ xp_print("dazuko: warning: failed to get root mount\n");
+ }
+ else
+ {
+ orig_rootmnt = nd.ni_rootdir;
+ vref(orig_rootmnt);
+
+ /* deref looked up vnode */
+ NDFREE(&nd, 0);
+ }
+ }
+ break;
+
+ case MOD_UNLOAD:
+ if (dazuko_exit() != 0)
+ err = EPERM;
+
+ if (orig_rootmnt != NULL)
+ vrele(orig_rootmnt);
+
+ break;
+
+ default:
+ err = EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+DEV_MODULE(dazuko, dazuko_loader, NULL);
+
diff -Nru dazuko-2.3.6a/dazuko_platform.h dazuko-2.3.6b/dazuko_platform.h
--- dazuko-2.3.6a/dazuko_platform.h 2005-02-05 12:59:13.000000000 +0100
+++ dazuko-2.3.6b/dazuko_platform.h 2009-03-07 15:19:37.000000000 +0100
@@ -6,6 +6,8 @@
#include "dazuko_linux.h"
#elif defined(FREEBSD5_SUPPORT)
#include "dazuko_freebsd5.h"
+#elif defined(FREEBSD7_SUPPORT)
+ #include "dazuko_freebsd5.h"
#elif defined(__FreeBSD__)
#include "dazuko_freebsd.h"
#else
diff -Nru dazuko-2.3.6a/dazuko_transport.c dazuko-2.3.6b/dazuko_transport.c
--- dazuko-2.3.6a/dazuko_transport.c 2005-05-13 23:28:02.000000000 +0200
+++ dazuko-2.3.6b/dazuko_transport.c 2009-03-07 15:00:23.000000000 +0100
@@ -64,8 +64,12 @@
#include <linux/stddef.h>
#include <linux/types.h>
#elif defined __FreeBSD__
- #include <stdio.h>
- #include <sys/types.h>
+ #if defined FREEBSD7_SUPPORT
+ #include <sys/stddef.h>
+ #else
+ #include <stdio.h>
+ #endif
+ #include <sys/types.h>
#elif defined __sun__
#include <stdio.h>
#include <sys/types.h>
_______________________________________________
Dazuko-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/dazuko-devel