Index: configure =================================================================== RCS file: /cvsroot/dazuko/dazuko/configure,v retrieving revision 1.84 diff -u -r1.84 configure --- configure 28 Jun 2006 15:01:14 -0000 1.84 +++ configure 29 Jun 2006 15:28:12 -0000 @@ -48,6 +48,7 @@ echo "override auto-detection values" echo " --kernelsrcdir=DIR kernel source files in DIR (Linux only)" echo " --devicemajor=MAJ use MAJ for device major number" + echo " --mapfile=MAP use MAP as System.map file (linux26+syscalls only)" echo " --system=SYS configure for system SYS (linux22,linux24,linux26," echo " freebsd4,freebsd5" echo " freebsd6,dummyos)" @@ -68,6 +69,7 @@ echo " --disable-local-dpath disable local __d_path() (Linux 2.6 only)" echo " --disable-compat1 disable 1.x compatibility (IO/Linux only)" echo " --enable-debug print extra debug information" + echo " --enable-syscalls hook syscalls, not LSM (Linux 2.6 only)" echo "" echo "optional packages" echo " --with-PACKAGE use PACKAGE" @@ -356,66 +358,155 @@ fi } -do_linux26() +check_use_parent() { - echo -n "checking if security module support is enabled... " - if [ $CONFIG_SECURITY -eq 0 ] - then - echo "no" - echo "error: security module support must be enabled in your kernel" - exit 1 - else - echo "yes" - fi + echo -n "inspecting task_struct structure... " + + SRC_PATH_END="/include/linux/sched.h" + get_src_path - echo -n "verifying capabilities are not built-in... " - if [ $CONFIG_SECURITY_CAPABILITIES -ne 0 ] + if [ ! -f "$SRC_PATH" ] then - echo "built-in :(" - echo "error: capabilities are built-in to the kernel:" - echo " you will need to recompile a kernel with capabilities" - echo " as a kernel module" - exit 1 + echo "not found (assuming standard)" else - echo "ok" + grep p_pptr "$SRC_PATH" > /dev/null 2>&1 + if [ $? -ne 0 ] + then + LINUX_USE_PARENT=1 + echo "ok (using parent)" + else + echo "ok" + fi fi +} - if [ $CONFIG_SECURITY_CAPABILITIES_MODULE -eq 0 ] +do_linux26() +{ + if [ $LINUX26_USE_SYSCALLS -eq 0 ] then - NO_CAPABILITIES=1 - fi + echo -n "checking if security module support is enabled... " + if [ $CONFIG_SECURITY -eq 0 ] + then + echo "no" + echo "error: security module support must be enabled in your kernel" + exit 1 + else + echo "yes" + fi - echo -n "locating LSM API header... " + echo -n "verifying capabilities are not built-in... " + if [ $CONFIG_SECURITY_CAPABILITIES -ne 0 ] + then + echo "built-in :(" + echo "error: capabilities are built-in to the kernel:" + echo " you will need to recompile a kernel with capabilities" + echo " as a kernel module" + exit 1 + else + echo "ok" + fi - SRC_PATH_END="/include/linux/security.h" - get_src_path + if [ $CONFIG_SECURITY_CAPABILITIES_MODULE -eq 0 ] + then + NO_CAPABILITIES=1 + fi + + echo -n "locating LSM API header... " + + SRC_PATH_END="/include/linux/security.h" + get_src_path + + if [ ! -f "$SRC_PATH" ] + then + echo "failed" + echo "error: unable to locate security.h" + exit 1 + else + echo "ok" + fi + + echo -n "identifying LSM API... " + if [ ! -x "linux_lsm_conf" ] + then + echo "failed" + echo "error: linux_lsm_conf missing in Dazuko distribution" + exit 1 + fi + + ./linux_lsm_conf $SRC_PATH + if [ $? -ne 0 ] + then + echo "failed" + echo "error: could not analyze security.h" + exit 1 + fi - if [ ! -f "$SRC_PATH" ] - then - echo "failed" - echo "error: unable to locate security.h" - exit 1 - else echo "ok" - fi + else + NO_CAPABILITIES=1 - echo -n "identifying LSM API... " - if [ ! -x "linux_lsm_conf" ] - then - echo "failed" - echo "error: linux_lsm_conf missing in Dazuko distribution" - exit 1 - fi + LINUX26_SYSCALL_CFLAGS="$LINUX26_SYSCALL_CFLAGS -DHIDDEN_SCT -DUSE_SYSCALLS -DNO_LINUX24_MODVERSIONS" - ./linux_lsm_conf $SRC_PATH - if [ $? -ne 0 ] - then - echo "failed" - echo "error: could not analyze security.h" - exit 1 - fi + echo -n "checking for System.map file... " + if [ -z "$MAPFILE" ] + then + echo "failed" + echo "error: no System.map file specified," + echo " please use --mapfile" + exit 1 + fi - echo "ok" + if [ -f "$MAPFILE" ] + then + echo "ok ($MAPFILE)" + else + echo "failed" + echo "error: $MAPFILE not found" + exit 1 + fi + + echo -n "locating sys_call_table... " + + ADDRESS=`awk '$3 == "sys_call_table" { print $1 }' $MAPFILE` + if [ -z "$ADDRESS" ] + then + echo "failed" + echo "error: unable to locate kernel symbol 'sys_call_table'" + echo " unable to support syscall hooking" + exit 1 + fi + + echo "ok (0x$ADDRESS)" + LINUX26_SYSCALL_CFLAGS="$LINUX26_SYSCALL_CFLAGS -DSYS_CALL_TABLE_ADDR=0x$ADDRESS" + + echo -n "checking sys_call_table status... " + + ADDRESS_STATUS=`awk '$3 == "sys_call_table" { print $2 }' $MAPFILE` + if [ "$ADDRESS_STATUS" = "R" ] + then + echo "read-only" + LINUX26_SYSCALL_CFLAGS="$LINUX26_SYSCALL_CFLAGS -DSYSCALL_TABLE_READONLY" + else + echo "read-write" + fi + + if [ ${ON_EXEC} -eq 1 ] + then + echo -n "locating do_execve... " + + ADDRESS=`awk '$3 == "do_execve" { print $1 }' $MAPFILE` + if [ -z "$ADDRESS" ] + then + echo "failed" + echo "error: unable to locate kernel symbol 'do_execve'" + echo " unable to support exec events" + exit 1 + fi + + echo "ok (0x$ADDRESS)" + LINUX26_SYSCALL_CFLAGS="$LINUX26_SYSCALL_CFLAGS -DDO_EXECVE_ADDR=0x$ADDRESS" + fi + fi SRC_PATH_END="/include/linux/device.h" get_src_path @@ -505,35 +596,42 @@ fi fi - if [ $ON_CLOSE -ne 0 ] + check_use_parent + + if [ $ON_CLOSE -ne 0 -a $LINUX26_USE_SYSCALLS -eq 0 ] then - echo "disabling ON_CLOSE events (not available for Linux 2.6)" + echo "disabling ON_CLOSE events (not available for Linux 2.6 LSM)" ON_CLOSE=0 fi - if [ ${ON_UNLINK} -ne 0 ] + if [ ${ON_UNLINK} -ne 0 -a $LINUX26_USE_SYSCALLS -eq 0 ] then - echo "disabling ON_UNLINK events (not available for Linux 2.6)" + echo "disabling ON_UNLINK events (not available for Linux 2.6 LSM)" ON_UNLINK=0 fi - if [ ${ON_RMDIR} -ne 0 ] + if [ ${ON_RMDIR} -ne 0 -a $LINUX26_USE_SYSCALLS -eq 0 ] then - echo "disabling ON_RMDIR events (not available for Linux 2.6)" + echo "disabling ON_RMDIR events (not available for Linux 2.6 LSM)" ON_RMDIR=0 fi - if [ ${ON_CLOSE_MODIFIED} -ne 0 ] + if [ ${ON_CLOSE_MODIFIED} -ne 0 -a $LINUX26_USE_SYSCALLS -eq 0 ] then - echo "disabling ON_CLOSE_MODIFIED events (not available for Linux 2.6)" + echo "disabling ON_CLOSE_MODIFIED events (not available for Linux 2.6 LSM)" ON_CLOSE_MODIFIED=0 fi - LINUX26_OBJS="dazuko_linux26.o" - echo "configure: creating Makefile" - echo "EXTRA_CFLAGS += -Wall -DLINUX26_SUPPORT" > Makefile + if [ ${LINUX26_USE_SYSCALLS} -eq 0 ] + then + LINUX26_OBJS="dazuko_linux26.o" + echo "EXTRA_CFLAGS += -Wall -DLINUX26_SUPPORT" > Makefile + else + LINUX26_OBJS="dazuko_linux.o" + echo "EXTRA_CFLAGS += -Wall -DLINUX" > Makefile + fi if [ ${LSM_STACKING} -eq 1 ] then @@ -572,6 +670,11 @@ echo "EXTRA_CFLAGS += -DUSE_CHROOT" >> Makefile fi + if [ ${LINUX_USE_PARENT} -eq 1 ] + then + echo "EXTRA_CFLAGS += -DTASKSTRUCT_USES_PARENT" >> Makefile + fi + if [ ${DEBUG} -eq 1 ] then echo "EXTRA_CFLAGS += -DDEBUG" >> Makefile @@ -587,6 +690,31 @@ echo "EXTRA_CFLAGS += -DON_OPEN_SUPPORT" >> Makefile fi + if [ ${ON_EXEC} -eq 1 ] + then + echo "EXTRA_CFLAGS += -DON_EXEC_SUPPORT" >> Makefile + fi + + if [ ${ON_CLOSE} -eq 1 ] + then + echo "EXTRA_CFLAGS += -DON_CLOSE_SUPPORT" >> Makefile + fi + + if [ ${ON_CLOSE_MODIFIED} -eq 1 ] + then + echo "EXTRA_CFLAGS += -DON_CLOSE_MODIFIED_SUPPORT" >> Makefile + fi + + if [ ${ON_UNLINK} -eq 1 ] + then + echo "EXTRA_CFLAGS += -DON_UNLINK_SUPPORT" >> Makefile + fi + + if [ ${ON_RMDIR} -eq 1 ] + then + echo "EXTRA_CFLAGS += -DON_RMDIR_SUPPORT" >> Makefile + fi + if [ ${TRUSTED} -eq 1 ] then echo "EXTRA_CFLAGS += -DTRUSTED_APPLICATION_SUPPORT" >> Makefile @@ -597,6 +725,11 @@ echo "EXTRA_CFLAGS += -DDAZUKO_DM=$DEVICEMAJOR" >> Makefile fi + for item in $LINUX26_SYSCALL_CFLAGS + do + echo "EXTRA_CFLAGS += $item" >> Makefile + done + echo "RM ?= rm -f" >> Makefile echo "obj-m += dazuko.o" >> Makefile @@ -695,24 +828,7 @@ fi fi - echo -n "inspecting task_struct structure... " - - SRC_PATH_END="/include/linux/sched.h" - get_src_path - - if [ ! -f "$SRC_PATH" ] - then - echo "not found (assuming standard)" - else - grep p_pptr "$SRC_PATH" > /dev/null 2>&1 - if [ $? -ne 0 ] - then - LINUX24_USE_PARENT=1 - echo "ok (using parent)" - else - echo "ok" - fi - fi + check_use_parent echo "configure: creating Makefile" @@ -787,7 +903,7 @@ echo "KFLAGS += -DDAZUKO_DM=$DEVICEMAJOR" >> Makefile fi - if [ ${LINUX24_USE_PARENT} -eq 1 ] + if [ ${LINUX_USE_PARENT} -eq 1 ] then echo "KFLAGS += -DTASKSTRUCT_USES_PARENT" >> Makefile fi @@ -1103,12 +1219,17 @@ if echo $LINUX_VERSION | grep -q ^2\.6\. then - echo -n "stacking support = " - if [ ${LSM_STACKING} -eq 1 ] + if [ $LINUX26_USE_SYSCALLS -eq 0 ] then - echo "yes" + echo -n "stacking support = " + if [ ${LSM_STACKING} -eq 1 ] + then + echo "yes" + else + echo "no" + fi else - echo "no" + echo "hooking via syscalls = yes" fi echo -n "local __d_path() = " @@ -1197,10 +1318,12 @@ WITH_EXAMPLE_JAVA=0 WITH_EXAMPLE_PERL=0 WITH_EXAMPLE_PYTHON=0 -LINUX24_USE_PARENT=0 +LINUX_USE_PARENT=0 LINUX26_USE_SUSPEND=0 LINUX26_USE_CLASS=0 LINUX26_USE_CHROOT=0 +LINUX26_USE_SYSCALLS=0 +LINUX26_SYSCALL_CFLAGS="" NO_CAPABILITIES=0 SMP=0 HIDDEN_SCT=0 @@ -1210,6 +1333,7 @@ LINUX_SRC="" DEVICEMAJOR="" SYSTEM="" +MAPFILE="" LINUX_VERSION=0 FREEBSD_VERSION=0 UNAME=`uname` @@ -1274,6 +1398,17 @@ ;; --enable-stacking) LSM_STACKING=1 + LINUX26_USE_SYSCALLS=0 + ;; + --disable-stacking) + LSM_STACKING=0 + ;; + --enable-syscalls) + LINUX26_USE_SYSCALLS=1 + LSM_STACKING=0 + ;; + --disable-syscalls) + LINUX26_USE_SYSCALLS=0 ;; --disable-stacking) LSM_STACKING=0 @@ -1359,6 +1494,9 @@ --system=*) SYSTEM=`echo $option | sed -e s/^--system=//` ;; + --mapfile=*) + MAPFILE=`echo $option | sed -e s/^--mapfile=//` + ;; --help|-h) print_help exit 0 Index: dazuko_linux.c =================================================================== RCS file: /cvsroot/dazuko/dazuko/dazuko_linux.c,v retrieving revision 1.79 diff -u -r1.79 dazuko_linux.c --- dazuko_linux.c 28 Jun 2006 14:19:14 -0000 1.79 +++ dazuko_linux.c 29 Jun 2006 15:28:13 -0000 @@ -21,23 +21,58 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* -TODO: -sys calls (cleanup compile warnings) -validate code -*/ - #include "dazuko_linux.h" #include "dazuko_core.h" +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#include "dazuko_linux26_device_def.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(USE_TRYTOFREEZEVOID) && !defined(USE_SUSPEND2) +#include +#endif +#include +#include +#include +#include +#ifdef SYSCALL_TABLE_READONLY +#include +#include +#endif + +#else + #ifdef DEVFS_SUPPORT #include #endif +#endif + + #ifndef DAZUKO_DM #define DAZUKO_DM 0 #endif + +#define CHROOT_EVENT_STRING "chroot:" +#define CHROOT_EVENT_LENGTH 7 + + +#ifndef WITH_LOCAL_DPATH +extern char * __d_path(struct dentry *, struct vfsmount *, struct dentry *, struct vfsmount *, char *, int); +#endif + + #ifdef HIDDEN_SCT void **sys_call_table; extern asmlinkage long sys_exit(int error_code); @@ -45,6 +80,24 @@ extern void *sys_call_table[]; #endif + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + +ssize_t linux_dazuko_device_read(struct file *, char __user *, size_t, loff_t *); +ssize_t linux_dazuko_device_write(struct file *, const char __user *, size_t, loff_t *); +int linux_dazuko_device_open(struct inode *, struct file *); +int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param); +int linux_dazuko_device_release(struct inode *, struct file *); + +#ifdef USE_CLASS +static struct class *dazuko_class = NULL; +#else +static struct class_simple *dazuko_class = NULL; +#endif + +#else + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) int linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos); int linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos); @@ -56,42 +109,75 @@ int linux_dazuko_device_open(struct inode *inode, struct file *file); int linux_dazuko_device_release(struct inode *inode, struct file *file); +#endif + + extern struct xp_atomic active; + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) static struct vfsmount *orig_rootmnt = NULL; #endif - + static struct dentry *orig_root = NULL; static int dev_major = -1; + #if defined(ON_OPEN_SUPPORT) -static asmlinkage long (*original_sys_open)(const char *filename, int flags, int mode); -static asmlinkage long (*original_sys_dup)(unsigned int filedes); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + static asmlinkage long (*original_sys_open)(const char __user *filename, int flags, int mode); + #else + static asmlinkage long (*original_sys_open)(const char *filename, int flags, int mode); + #endif + static asmlinkage long (*original_sys_dup)(unsigned int filedes); #endif + #if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) -static asmlinkage long (*original_sys_dup2)(unsigned int oldfd, unsigned int newfd); + static asmlinkage long (*original_sys_dup2)(unsigned int oldfd, unsigned int newfd); #endif + #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) -static asmlinkage long (*original_sys_close)(unsigned int fd); + static asmlinkage long (*original_sys_close)(unsigned int fd); #endif + #ifdef ON_EXEC_SUPPORT -static asmlinkage int (*original_sys_execve)(struct pt_regs regs); + static asmlinkage int (*original_sys_execve)(struct pt_regs regs); #endif + #ifdef ON_UNLINK_SUPPORT -static asmlinkage long (*original_sys_unlink)(const char *pathname); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + static asmlinkage long (*original_sys_unlink)(const char __user *pathname); + #else + static asmlinkage long (*original_sys_unlink)(const char *pathname); + #endif #endif + #ifdef ON_RMDIR_SUPPORT -static asmlinkage long (*original_sys_rmdir)(const char *pathname); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + static asmlinkage long (*original_sys_rmdir)(const char __user *pathname); + #else + static asmlinkage long (*original_sys_rmdir)(const char *pathname); + #endif #endif + static struct file_operations fops = { - read: linux_dazuko_device_read, /* read */ - write: linux_dazuko_device_write, /* write */ - ioctl: linux_dazuko_device_ioctl, /* ioctl */ - open: linux_dazuko_device_open, /* open */ - release: linux_dazuko_device_release, /* release */ - }; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + .owner = THIS_MODULE, + .read = linux_dazuko_device_read, + .write = linux_dazuko_device_write, + .ioctl = linux_dazuko_device_ioctl, + .open = linux_dazuko_device_open, + .release = linux_dazuko_device_release, +#else + read: linux_dazuko_device_read, /* read */ + write: linux_dazuko_device_write, /* write */ + ioctl: linux_dazuko_device_ioctl, /* ioctl */ + open: linux_dazuko_device_open, /* open */ + release: linux_dazuko_device_release, /* release */ +#endif + }; + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) @@ -220,17 +306,42 @@ inline int xp_wait_until_condition(struct xp_queue *queue, int (*cfunction)(void *), void *cparam, int allow_interrupt) { /* wait until cfunction(cparam) != 0 (condition is true) */ + int ret = 0; if (allow_interrupt) { - return wait_event_interruptible(queue->queue, cfunction(cparam) != 0); + while (1) + { + ret = wait_event_interruptible(queue->queue, cfunction(cparam) != 0); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + #ifdef USE_SUSPEND2 + if (try_todo_list() == 0) + break; + #elif defined (USE_TRYTOFREEZEVOID) + if (try_to_freeze() == 0) + break; + #else + if (current->flags & PF_FREEZE) + { + refrigerator(PF_FREEZE); + } + else + { + break; + } + #endif +#else + break; +#endif + } } else { wait_event(queue->queue, cfunction(cparam) != 0); } - return 0; + return ret; } inline int xp_notify(struct xp_queue *queue) @@ -249,7 +360,11 @@ inline void* xp_malloc(size_t size) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + return kmalloc(size, GFP_ATOMIC); +#else return kmalloc(size, GFP_KERNEL); +#endif } inline int xp_free(void *ptr) @@ -291,7 +406,18 @@ inline int xp_is_absolute_path(const char *path) { - return (path[0] == '/'); + if (path[0] == '/') + return 1; + +#ifdef USE_CHROOT + if (dazuko_strlen(path) >= CHROOT_EVENT_LENGTH) + { + if (memcmp(CHROOT_EVENT_STRING, path, CHROOT_EVENT_LENGTH) == 0) + return 1; + } +#endif + + return 0; } @@ -305,10 +431,12 @@ inline int xp_atomic_inc(struct xp_atomic *atomic) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) #ifdef MODULE if (atomic == &active) MOD_INC_USE_COUNT; #endif +#endif atomic_inc(&(atomic->atomic)); return 0; @@ -316,10 +444,12 @@ inline int xp_atomic_dec(struct xp_atomic *atomic) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) #ifdef MODULE if (atomic == &active) MOD_DEC_USE_COUNT; #endif +#endif atomic_dec(&(atomic->atomic)); return 0; @@ -333,6 +463,118 @@ /* file structure */ +#ifdef WITH_LOCAL_DPATH +/* This code is taken directy from: + linux-2.6.0/fs/dcache.c + because __d_path is no longer exported. + */ +/** + * d_path - return the path of a dentry + * @dentry: dentry to report + * @vfsmnt: vfsmnt to which the dentry belongs + * @root: root dentry + * @rootmnt: vfsmnt to which the root dentry belongs + * @buffer: buffer to return value in + * @buflen: buffer length + * + * Convert a dentry into an ASCII path name. If the entry has been deleted + * the string " (deleted)" is appended. Note that this is ambiguous. + * + * Returns the buffer or an error code if the path was too long. + * + * "buflen" should be positive. Caller holds the dcache_lock. + */ +static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt, + struct dentry *root, struct vfsmount *rootmnt, + char *buffer, int buflen) +{ + char * end = buffer+buflen; + char * retval; + int namelen; + + *--end = '\0'; + buflen--; + if (!IS_ROOT(dentry) && d_unhashed(dentry)) { + buflen -= 10; + end -= 10; + if (buflen < 0) + goto Elong; + memcpy(end, " (deleted)", 10); + } + + if (buflen < 1) + goto Elong; + /* Get '/' right */ + retval = end-1; + *retval = '/'; + + for (;;) { + struct dentry * parent; + + if (dentry == root && vfsmnt == rootmnt) + break; + if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { + /* Global root? */ + if (vfsmnt->mnt_parent == vfsmnt) + goto global_root; + dentry = vfsmnt->mnt_mountpoint; + vfsmnt = vfsmnt->mnt_parent; + continue; + } + parent = dentry->d_parent; + prefetch(parent); + namelen = dentry->d_name.len; + buflen -= namelen + 1; + if (buflen < 0) + goto Elong; + end -= namelen; + memcpy(end, dentry->d_name.name, namelen); + *--end = '/'; + retval = end; + dentry = parent; + } + + return retval; + +global_root: + namelen = dentry->d_name.len; + buflen -= namelen; + if (buflen < 0) + goto Elong; + retval -= namelen-1; /* hit the slash */ + memcpy(retval, dentry->d_name.name, namelen); + return retval; +Elong: + return ERR_PTR(-ENAMETOOLONG); +} +#endif + +/* Copied 1:1 from Linux kernel source kernel/exit.c */ +/* Why is this not exported? put_files_struct is exported! */ +static inline struct files_struct *dazuko_get_files_struct(struct task_struct *task) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct files_struct *files; + + task_lock(task); + files = task->files; + if (files != NULL) + atomic_inc(&files->count); + task_unlock(task); + + return files; +#else + return task->files; +#endif +} + +static inline void dazuko_put_files_struct(struct files_struct *fs) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + put_files_struct(fs); +#endif +} + static int dazuko_get_filename_dentry(struct xp_file_struct *xfs, int follow_symlinks, const char *local_filename, int user_ptr) { /* We get the appropriate structures in order @@ -353,6 +595,7 @@ /* make sure it is a valid name */ if (IS_ERR(filename)) { + DPRINT(("dazuko: dazuko_get_filename_dentry: getname failed\n")); filename = NULL; return 0; } @@ -371,6 +614,16 @@ { dazuko_bzero(&(xfs->nd), sizeof(struct nameidata)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (path_lookup(filename, follow_symlinks ? LOOKUP_FOLLOW : 0, &(xfs->nd))) + { + DPRINT(("dazuko: dazuko_get_filename_dentry: path_lookup failed\n")); + goto dentry_exit; + } + + /* the nameidata will need to be released */ + xfs->path_release_nd = 1; +#else /* initialize nameidata structure for finding file data */ if (!path_init(filename, (follow_symlinks ? LOOKUP_FOLLOW : 0) | LOOKUP_POSITIVE, &(xfs->nd))) goto dentry_exit; @@ -384,6 +637,7 @@ /* the nameidata will need to be released */ xfs->path_release_nd = 1; } +#endif /* get a local copy of the dentry to make kernel version * compatibility code eaiser to read */ @@ -417,6 +671,7 @@ /* check if this file has no inode */ if (xfs->dentry->d_inode == NULL) { + DPRINT(("dazuko: dazuko_get_filename_dentry: inode is NULL\n")); goto dentry_exit; } else @@ -429,52 +684,96 @@ if (putname_filename) putname(filename); + DPRINT(("dazuko: dazuko_get_filename_dentry returning %d\n", rc)); return rc; } +/* inspired by include/linux/file.h (Linux 2.6) */ +static inline struct file * dazuko_fcheck_files(struct files_struct *files, unsigned int fd, int lock) +{ + struct file *file = NULL; + + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + { + if (lock) + read_lock(&files->file_lock); + } + #endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) + struct fdtable *fdt = files_fdtable(files); + + if (fdt->fd != NULL) + { + if (fd < fdt->max_fds) + file = rcu_dereference(fdt->fd[fd]); + } +#else + if (files->fd != NULL) + { + if (fd < files->max_fds) + file = files->fd[fd]; + } +#endif + + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + { + if (lock) + read_unlock(&files->file_lock); + } + #endif + + return file; +} + static int dazuko_get_fd_dentry(struct xp_file_struct *xfs) { - if (current->files != NULL) + struct files_struct *files = NULL; + struct file *file = NULL; + + files = dazuko_get_files_struct(current); + + if (files != NULL) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) { - read_lock(¤t->files->file_lock); + read_lock(&files->file_lock); } #endif - if (current->files->fd != NULL) + file = dazuko_fcheck_files(files, xfs->fd, 0); + if (file != NULL) { - if (current->files->fd[xfs->fd] != NULL) + if (file->f_dentry != NULL) { - if (current->files->fd[xfs->fd]->f_dentry != NULL) - { - xfs->dentry = dget(current->files->fd[xfs->fd]->f_dentry); - xfs->dput_dentry = 1; + xfs->dentry = dget(file->f_dentry); + xfs->dput_dentry = 1; - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + { + if (file->f_vfsmnt != NULL) { - if (current->files->fd[xfs->fd]->f_vfsmnt != NULL) - { - xfs->vfsmount = mntget(current->files->fd[xfs->fd]->f_vfsmnt); - xfs->mntput_vfsmount = 1; - } - else - { - dput(xfs->dentry); - xfs->dentry = NULL; - xfs->dput_dentry = 0; - } + xfs->vfsmount = mntget(file->f_vfsmnt); + xfs->mntput_vfsmount = 1; + } + else + { + dput(xfs->dentry); + xfs->dentry = NULL; + xfs->dput_dentry = 0; } - #endif } + #endif } } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) { - read_unlock(¤t->files->file_lock); + read_unlock(&files->file_lock); } #endif + + dazuko_put_files_struct(files); } /* check if we got the dentry */ @@ -541,9 +840,13 @@ char *temp; struct dentry *root; - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - struct vfsmount *rootmnt; - #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + struct vfsmount *rootmnt; +#endif + +#ifdef USE_CHROOT + int chrooted = 0; +#endif /* check if we need to allocate a buffer */ if (!xfs->free_page_buffer) @@ -572,9 +875,17 @@ rootmnt = mntget(orig_rootmnt); +#ifdef USE_CHROOT + temp = d_path(xfs->dentry, xfs->vfsmount, xfs->buffer, PAGE_SIZE); + task_lock(current); + if (orig_root != current->fs->root) + chrooted = 1; + task_unlock(current); +#else spin_lock(&dcache_lock); temp = __d_path(xfs->dentry, xfs->vfsmount, root, rootmnt, xfs->buffer, PAGE_SIZE); spin_unlock(&dcache_lock); +#endif mntput(rootmnt); } @@ -597,6 +908,10 @@ { xfs->full_filename_length = dazuko_strlen(temp); +#ifdef USE_CHROOT + if (chrooted) + xfs->full_filename_length += CHROOT_EVENT_LENGTH; +#endif xfs->full_filename = (char *)xp_malloc(xfs->full_filename_length + 1); if (!xfs->full_filename) return 0; @@ -604,6 +919,14 @@ /* the char array will need to be freed */ xfs->free_full_filename = 1; +#ifdef USE_CHROOT + if (chrooted) + { + memcpy(xfs->full_filename, CHROOT_EVENT_STRING, CHROOT_EVENT_LENGTH + 1); + memcpy(xfs->full_filename + CHROOT_EVENT_LENGTH, temp, xfs->full_filename_length - CHROOT_EVENT_LENGTH + 1); + } + else +#endif memcpy(xfs->full_filename, temp, xfs->full_filename_length + 1); } @@ -693,6 +1016,7 @@ if (IS_ERR(freeparentpath)) { freeparentpath = NULL; + DPRINT(("dazuko: xp_fill_file_struct: getname failed\n")); break; } @@ -731,6 +1055,7 @@ { putname(freeparentpath); freeparentpath = NULL; + DPRINT(("dazuko: dazuko_get_filename_dentry failed for %s\n", parentpath)); break; } } @@ -739,6 +1064,7 @@ { if (!dazuko_get_fd_dentry(dfs->extra_data)) { + DPRINT(("dazuko: dazuko_get_fd_dentry failed\n")); break; } else @@ -749,13 +1075,18 @@ } /* make sure we can get the full path */ - if (!dazuko_get_full_filename(dfs->extra_data)) + if (!dazuko_get_full_filename(dfs->extra_data)) + { + DPRINT(("dazuko: dazuko_get_full_filename failed\n")); break; + } if (freeparentpath != NULL) { /* we are working with a "fake" name */ + DPRINT(("dazuko: building full path at loop=%d, we have %s\n", loopcount, dfs->extra_data->full_filename)); + parentpath = dfs->extra_data->full_filename; i = dazuko_strlen(rawfilename); @@ -781,6 +1112,8 @@ memcpy(dfs->extra_data->full_filename + dfs->extra_data->full_filename_length, rawfilename, i + 1); dfs->extra_data->full_filename_length += i; + DPRINT(("dazuko: constructed full filename: %s\n", dfs->extra_data->full_filename)); + /* free allocated parent path */ xp_free(parentpath); } @@ -794,22 +1127,32 @@ dfs->file_p.set_gid = 1; dfs->file_p.mode = dfs->extra_data->dentry->d_inode->i_mode; dfs->file_p.set_mode = 1; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + dfs->file_p.device_type = dfs->extra_data->dentry->d_inode->i_rdev; + dfs->file_p.set_device_type = 1; +#else dfs->file_p.device_type = dfs->extra_data->dentry->d_inode->i_dev; dfs->file_p.set_device_type = 1; +#endif } + DPRINT(("dazuko: we have full path at loop=%d, %s\n", loopcount, dfs->extra_data->full_filename)); + if (S_ISREG(dfs->extra_data->dentry->d_inode->i_mode)) { + DPRINT(("dazuko: inode is regular file\n")); dfs->file_p.type = DAZUKO_REGULAR; dfs->file_p.set_type = 1; } else if (S_ISLNK(dfs->extra_data->dentry->d_inode->i_mode)) { + DPRINT(("dazuko: inode is symlink\n")); dfs->file_p.type = DAZUKO_LINK; dfs->file_p.set_type = 1; } else if (S_ISDIR(dfs->extra_data->dentry->d_inode->i_mode)) { + DPRINT(("dazuko: inode is a directory\n")); dfs->file_p.type = DAZUKO_DIRECTORY; dfs->file_p.set_type = 1; } @@ -863,6 +1206,8 @@ dazuko_fill_file_struct_cleanup(dfs); + DPRINT(("dazuko: xp_fill_file_struct returning %d\n", error)); + return error; } @@ -1015,7 +1360,11 @@ /* system calls */ #if defined(ON_OPEN_SUPPORT) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +asmlinkage long linux_dazuko_sys_open(const char __user *filename, int flags, int mode) +#else asmlinkage long linux_dazuko_sys_open(const char *filename, int flags, int mode) +#endif { /* The kernel wants to open the given filename * with the given flags and mode. The dazuko_file_struct @@ -1033,10 +1382,13 @@ xp_id.pid = current->pid; xp_id.file = NULL; xp_id.current_p = current; - xp_id.files = current->files; + xp_id.files = dazuko_get_files_struct(current); check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL); + if (xp_id.files != NULL) + dazuko_put_files_struct(xp_id.files); + if (!check_error) { dazuko_bzero(&event_p, sizeof(event_p)); @@ -1099,7 +1451,7 @@ xp_id.pid = current->pid; xp_id.file = NULL; xp_id.current_p = current; - xp_id.files = current->files; + xp_id.files = dazuko_get_files_struct(current); check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL); @@ -1107,7 +1459,7 @@ { dazuko_bzero(&event_p, sizeof(event_p)); - if (filedes >= 0 && filedes < current->files->max_fds) + if (dazuko_fcheck_files(xp_id.files, filedes, 1) != NULL) { event_p.pid = current->pid; event_p.set_pid = 1; @@ -1143,6 +1495,9 @@ } } + if (xp_id.files != NULL) + dazuko_put_files_struct(xp_id.files); + if (error) { /* access should be blocked */ @@ -1175,7 +1530,7 @@ xp_id.pid = current->pid; xp_id.file = NULL; xp_id.current_p = current; - xp_id.files = current->files; + xp_id.files = dazuko_get_files_struct(current); check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL); @@ -1183,7 +1538,7 @@ { dazuko_bzero(&open_event_p, sizeof(open_event_p)); - if (oldfd != newfd && oldfd >= 0 && oldfd < current->files->max_fds) + if (oldfd != newfd && dazuko_fcheck_files(xp_id.files, oldfd, 1) != NULL) { open_event_p.pid = current->pid; open_event_p.set_pid = 1; @@ -1228,24 +1583,9 @@ else { #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) - if (newfd >= 0 && newfd < current->files->max_fds) + if (dazuko_fcheck_files(xp_id.files, newfd, 1) != NULL) { - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - { - read_lock(¤t->files->file_lock); - } - #endif - - if (current->files->fd[newfd] != NULL) - { - will_close_newfd = 1; - } - - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - { - read_unlock(¤t->files->file_lock); - } - #endif + will_close_newfd = 1; } #endif @@ -1293,6 +1633,9 @@ #endif } + if (xp_id.files != NULL) + dazuko_put_files_struct(xp_id.files); + return error; } #endif @@ -1312,11 +1655,11 @@ xp_id.pid = current->pid; xp_id.file = NULL; xp_id.current_p = current; - xp_id.files = current->files; + xp_id.files = dazuko_get_files_struct(current); check_error = dazuko_check_access(DAZUKO_ON_CLOSE, 1, &xp_id, NULL); - if (!check_error && fd >= 0 && fd < current->files->max_fds) + if (!check_error && dazuko_fcheck_files(xp_id.files, fd, 1) != NULL) { dazuko_bzero(&event_p, sizeof(event_p)); @@ -1347,6 +1690,9 @@ } } + if (xp_id.files != NULL) + dazuko_put_files_struct(xp_id.files); + error = original_sys_close(fd); if (dfs != NULL) @@ -1364,6 +1710,13 @@ #endif #ifdef ON_EXEC_SUPPORT + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +typedef int (*do_execve_call_t)(char *filename, char __user *__user *argv, char __user *__user *envp, struct pt_regs *regs); + +static do_execve_call_t XXX_do_execve = (do_execve_call_t) DO_EXECVE_ADDR; +#endif + asmlinkage int linux_dazuko_sys_execve(struct pt_regs regs) { /* The kernel wants to execute the given file. @@ -1384,10 +1737,13 @@ xp_id.pid = current->pid; xp_id.file = NULL; xp_id.current_p = current; - xp_id.files = current->files; + xp_id.files = dazuko_get_files_struct(current); check_error = dazuko_check_access(DAZUKO_ON_EXEC, 0, &xp_id, &sl); + if (xp_id.files != NULL) + dazuko_put_files_struct(xp_id.files); + if (!check_error) { dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct)); @@ -1436,7 +1792,26 @@ * It is directly copied from Linux in the file: * arch/i386/kernel/process.c */ - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + { + filename = getname((char __user *) regs.ebx); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + error = XXX_do_execve(filename, (char __user * __user *) regs.ecx, (char __user * __user *) regs.edx, ®s); + if (error == 0) + { + task_lock(current); + current->ptrace &= ~PT_DTRACE; + task_unlock(current); + /* Make sure we don't return using sysenter.. */ + set_thread_flag(TIF_IRET); + } + putname(filename); +out: + return error; + } + #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) { filename = getname((char *) regs.ebx); error = PTR_ERR(filename); @@ -1512,10 +1887,13 @@ xp_id.pid = current->pid; xp_id.file = NULL; xp_id.current_p = current; - xp_id.files = current->files; + xp_id.files = dazuko_get_files_struct(current); check_error = dazuko_check_access(event, daemon_is_allowed, &xp_id, &sl); + if (xp_id.files != NULL) + dazuko_put_files_struct(xp_id.files); + if (!check_error) { dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct)); @@ -1583,11 +1961,23 @@ /* system hook */ #ifdef HIDDEN_SCT -static void** dazuko_get_sct() +static void** dazuko_get_sct(void) { + unsigned long *p; + +#ifdef SYS_CALL_TABLE_ADDR + p = (unsigned long *)SYS_CALL_TABLE_ADDR; + + if (p != NULL) + { + if (p[6] == (unsigned long)sys_close) + { + return (void **)p; + } + } +#else unsigned long ptr; extern int loops_per_jiffy; - unsigned long *p; for (ptr=(unsigned long)&loops_per_jiffy ; ptr<(unsigned long)&boot_cpu_data ; ptr+=sizeof(void *)) { @@ -1597,11 +1987,26 @@ return (void **)p; } } +#endif return NULL; } #endif +static inline void dazuko_lock_current(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + task_lock(current); +#endif +} + +static inline void dazuko_unlock_current(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + task_unlock(current); +#endif +} + #define DAZUKO_HOOK(syscall_func) do \ { \ original_sys_##syscall_func = sys_call_table[__NR_##syscall_func]; \ @@ -1610,7 +2015,7 @@ } \ while (0) -inline int xp_sys_hook() +inline int xp_sys_hook(void) { /* Called insmod when inserting the module. */ @@ -1630,13 +2035,16 @@ xp_print("dazuko: panic (current == NULL)\n"); return -1; } + dazuko_lock_current(); if (current->fs == NULL) { + dazuko_unlock_current(); xp_print("dazuko: panic (current->fs == NULL)\n"); return -1; } if (current->fs->root == NULL) { + dazuko_unlock_current(); xp_print("dazuko: panic (current->fs->root == NULL)\n"); return -1; } @@ -1644,31 +2052,67 @@ { if (current->fs->rootmnt == NULL) { + dazuko_unlock_current(); xp_print("dazuko: panic (current->fs->rootmnt == NULL)\n"); return -1; } } #endif + dazuko_unlock_current(); + /* register the dazuko device */ -#ifdef DEVFS_SUPPORT - dev_major = devfs_register_chrdev(0, DEVICE_NAME, &fops); - devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, - dev_major, 0, S_IFCHR | S_IRUSR | S_IWUSR, - &fops, NULL); -#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) dev_major = register_chrdev(DAZUKO_DM, DEVICE_NAME, &fops); -#endif if (dev_major < 0) { + xp_print("dazuko: unable to register device, err=%d\n", dev_major); + return dev_major; + } + + devfs_mk_cdev(MKDEV(dev_major, 0), S_IFCHR | S_IRUSR | S_IWUSR, DEVICE_NAME); + + #ifdef USE_CLASS + dazuko_class = class_create(THIS_MODULE, "dazuko"); + #ifdef CLASS_class_device_create_2_6_15 + class_device_create(dazuko_class, NULL, MKDEV(dev_major, 0), NULL, "dazuko"); + #else + class_device_create(dazuko_class, MKDEV(dev_major, 0), NULL, "dazuko"); + #endif + #else + dazuko_class = class_simple_create(THIS_MODULE, "dazuko"); + class_simple_device_add(dazuko_class, MKDEV(dev_major, 0), NULL, "dazuko"); + #endif +#else + #ifdef DEVFS_SUPPORT + dev_major = devfs_register_chrdev(0, DEVICE_NAME, &fops); + devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, + dev_major, 0, S_IFCHR | S_IRUSR | S_IWUSR, + &fops, NULL); + #else + dev_major = register_chrdev(DAZUKO_DM, DEVICE_NAME, &fops); + #endif + if (dev_major < 0) + { + dazuko_unlock_current(); xp_print("dazuko: unable to register device chrdev, err=%d\n", dev_major); return dev_major; } +#endif + +#ifdef USE_CHROOT + xp_print("dazuko: info: using chroot events for chroot'd processes\n"); +#endif +#if defined(CONFIG_SMP) && defined(WITH_LOCAL_DPATH) + xp_print("dazuko: warning: using local __dpath() dangerous for SMP kernels\n"); +#endif /* Grab the current root. This is assumed to be the real. * If it is not the real root, we could have problems * looking up filenames. */ + dazuko_lock_current(); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) { read_lock(¤t->fs->lock); @@ -1682,12 +2126,21 @@ read_unlock(¤t->fs->lock); #endif + dazuko_unlock_current(); + /* do a file syncronization on all devices (IMPORTANT!) and replace system calls */ #ifdef __SMP__ lock_kernel(); #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) fsync_dev(0); +#endif + +#ifdef SYSCALL_TABLE_READONLY + /* unprotect the syscall table */ + change_page_attr(virt_to_page(sys_call_table),1,__pgprot(VM_READ|VM_WRITE)); +#endif #if defined(ON_OPEN_SUPPORT) DAZUKO_HOOK(open); @@ -1713,6 +2166,11 @@ DAZUKO_HOOK(rmdir); #endif +#ifdef SYSCALL_TABLE_READONLY + /* protect the syscall table */ + change_page_attr(virt_to_page(sys_call_table),1,__pgprot(VM_READ)); +#endif + #ifdef __SMP__ unlock_kernel(); #endif @@ -1732,7 +2190,7 @@ } \ while (0) -inline int xp_sys_unhook() +inline int xp_sys_unhook(void) { /* Called by rmmod when removing the module. */ @@ -1743,7 +2201,14 @@ lock_kernel(); #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) fsync_dev(0); +#endif + +#ifdef SYSCALL_TABLE_READONLY + /* unprotect the syscall table */ + change_page_attr(virt_to_page(sys_call_table),1,__pgprot(VM_READ|VM_WRITE)); +#endif #if defined(ON_OPEN_SUPPORT) DAZUKO_UNHOOK(open); @@ -1769,21 +2234,40 @@ DAZUKO_UNHOOK(rmdir); #endif +#ifdef SYSCALL_TABLE_READONLY + /* protect the syscall table */ + change_page_attr(virt_to_page(sys_call_table),1,__pgprot(VM_READ)); +#endif + #ifdef __SMP__ unlock_kernel(); #endif /* done syncing and replacing */ -#ifdef DEVFS_SUPPORT - error = devfs_unregister_chrdev(dev_major, DEVICE_NAME); - devfs_unregister(devfs_find_handle(NULL, DEVICE_NAME, dev_major, 0, DEVFS_SPECIAL_CHR, 0)); -#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) error = unregister_chrdev(dev_major, DEVICE_NAME); -#endif + + devfs_remove(DEVICE_NAME); + + #ifdef USE_CLASS + class_device_destroy(dazuko_class, MKDEV(dev_major, 0)); + class_destroy(dazuko_class); + #else + class_simple_device_remove(MKDEV(dev_major, 0)); + class_simple_destroy(dazuko_class); + #endif +#else + #ifdef DEVFS_SUPPORT + error = devfs_unregister_chrdev(dev_major, DEVICE_NAME); + devfs_unregister(devfs_find_handle(NULL, DEVICE_NAME, dev_major, 0, DEVFS_SPECIAL_CHR, 0)); + #else + error = unregister_chrdev(dev_major, DEVICE_NAME); + #endif if (error < 0) { xp_print("dazuko: error unregistering chrdev, err=%d\n", error); } +#endif return 0; } @@ -1796,13 +2280,18 @@ va_list args; char *p; size_t size = 1024; + int length; p = (char *)xp_malloc(size); - if (!p) + if (p == NULL) return -1; + length = dazuko_strlen(KERN_INFO); + + memcpy(p, KERN_INFO, length); + va_start(args, fmt); - dazuko_vsnprintf(p, size-1, fmt, args); + dazuko_vsnprintf(p + length, (size-1) - length, fmt, args); va_end(args); p[size-1] = 0; @@ -1840,11 +2329,12 @@ DPRINT(("dazuko: linux_dazuko_device_read() [%d]\n", current->pid)); /* only one read is allowed */ + if (*pos != 0) return 0; if (dev_major < 0) - return -ENODEV; + return XP_ERROR_NODEVICE; /* print dev_major to a string * and get length (with terminator) */ @@ -1855,17 +2345,17 @@ if (tmp[sizeof(tmp)-1] != 0) { xp_print("dazuko: failing device_read, device number overflow for dameon %d (dev_major=%d)\n", current->pid, dev_major); - return -EFAULT; + return XP_ERROR_FAULT; } if (length < dev_major_len) - return -EINVAL; + return XP_ERROR_INVALID; /* copy dev_major string to userspace */ if (xp_copyout(tmp, buffer, dev_major_len) != 0) - return -EFAULT; + return XP_ERROR_FAULT; - *pos = dev_major_len; + *pos += dev_major_len; return dev_major_len; } @@ -1884,26 +2374,37 @@ struct xp_daemon_id xp_id; char tmpbuffer[32]; int size; + ssize_t ret; size = length; if (length >= sizeof(tmpbuffer)) - size = sizeof(tmpbuffer) -1; + size = sizeof(tmpbuffer) - 1; /* copy request pointer string to kernelspace */ if (xp_copyin(buffer, tmpbuffer, size) != 0) - return -EFAULT; + return XP_ERROR_FAULT; tmpbuffer[size] = 0; xp_id.pid = current->pid; xp_id.file = file; xp_id.current_p = current; - xp_id.files = current->files; + xp_id.files = dazuko_get_files_struct(current); if (dazuko_handle_user_request(tmpbuffer, &xp_id) == 0) - return length; + { + /* we say the full length was written (even if it is not true) */ + ret = length; + } else - return -EINTR; + { + ret = XP_ERROR_INTERRUPT; + } + + if (xp_id.files != NULL) + dazuko_put_files_struct(xp_id.files); + + return ret; } #endif @@ -1919,21 +2420,24 @@ if (param == 0) { xp_print("dazuko: error: linux_dazuko_device_ioctl(..., 0)\n"); - return -EFAULT; + return XP_ERROR_INVALID; } xp_id.pid = current->pid; xp_id.file = file; xp_id.current_p = current; - xp_id.files = current->files; + xp_id.files = dazuko_get_files_struct(current); error = dazuko_handle_user_request_compat1((void *)param, _IOC_NR(cmd), &xp_id); + if (xp_id.files != NULL) + dazuko_put_files_struct(xp_id.files); + if (error != 0) { /* general error occurred */ - return -EPERM; + return XP_ERROR_PERMISSION; } return error; @@ -1942,27 +2446,33 @@ int linux_dazuko_device_release(struct inode *inode, struct file *file) { struct xp_daemon_id xp_id; + int ret; DPRINT(("dazuko: dazuko_device_release() [%d]\n", current->pid)); xp_id.pid = current->pid; xp_id.file = file; xp_id.current_p = current; - xp_id.files = current->files; + xp_id.files = dazuko_get_files_struct(current); + + ret = dazuko_unregister_daemon(&xp_id); - return dazuko_unregister_daemon(&xp_id); + if (xp_id.files != NULL) + dazuko_put_files_struct(xp_id.files); + + return ret; } /* init/exit */ -int __init linux_dazuko_init(void) +static int __init linux_dazuko_init(void) { return dazuko_init(); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -void __exit linux_dazuko_exit(void) +static void __exit linux_dazuko_exit(void) #else void linux_dazuko_exit(void) #endif @@ -1981,6 +2491,15 @@ static const char __module_license[] __attribute__((section(".modinfo"))) = "license=GPL"; #endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + +MODULE_INFO(vermagic, VERMAGIC_STRING); + +security_initcall(linux_dazuko_init); +module_exit(linux_dazuko_exit); +#else + int init_module(void) { return linux_dazuko_init(); @@ -1990,9 +2509,12 @@ { linux_dazuko_exit(); } - + EXPORT_NO_SYMBOLS; +#endif + + #else module_init(linux_dazuko_init); Index: dazuko_linux.h =================================================================== RCS file: /cvsroot/dazuko/dazuko/dazuko_linux.h,v retrieving revision 1.27 diff -u -r1.27 dazuko_linux.h --- dazuko_linux.h 20 Jan 2006 20:21:06 -0000 1.27 +++ dazuko_linux.h 29 Jun 2006 15:28:13 -0000 @@ -1,5 +1,6 @@ /* Dazuko Linux. Allow Linux file access control for 3rd-party applications. Copyright (c) 2002, 2003, 2004, 2005, 2006 H+BEDV Datentechnik GmbH + Copyright (c) 2006 Avira GmbH Written by Martin Ritter John Ogness @@ -21,10 +22,12 @@ #ifndef DAZUKO_LINUX_H #define DAZUKO_LINUX_H +#ifndef NO_LINUX24_MODVERSIONS #if CONFIG_MODVERSIONS==1 #define MODVERSIONS #include #endif +#endif #include #include @@ -37,6 +40,13 @@ #define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c)) #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + +#include +#include + +#else + #include #include @@ -56,6 +66,8 @@ #include #endif +#endif + #define DEVICE_NAME "dazuko" @@ -64,6 +76,7 @@ #define XP_ERROR_BUSY -EBUSY #define XP_ERROR_FAULT -EFAULT #define XP_ERROR_INVALID -EINVAL +#define XP_ERROR_NODEVICE -ENODEV struct xp_daemon_id