00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "dazuko_linux.h"
00028 #include "dazuko_core.h"
00029
00030 #ifdef DEVFS_SUPPORT
00031 #include <linux/devfs_fs_kernel.h>
00032 #endif
00033
00034 #ifndef DAZUKO_DM
00035 #define DAZUKO_DM 0
00036 #endif
00037
00038 #ifdef HIDDEN_SCT
00039 void **sys_call_table;
00040 extern asmlinkage long sys_exit(int error_code);
00041 #else
00042 extern void *sys_call_table[];
00043 #endif
00044
00045 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
00046 int linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos);
00047 int linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos);
00048 #else
00049 ssize_t linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos);
00050 ssize_t linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos);
00051 #endif
00052 int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param);
00053 int linux_dazuko_device_open(struct inode *inode, struct file *file);
00054 int linux_dazuko_device_release(struct inode *inode, struct file *file);
00055
00056 extern struct xp_atomic active;
00057
00058 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00059 static struct vfsmount *orig_rootmnt = NULL;
00060 #endif
00061
00062 static struct dentry *orig_root = NULL;
00063 static int dev_major = -1;
00064
00065 #if defined(ON_OPEN_SUPPORT)
00066 static asmlinkage long (*original_sys_open)(const char *filename, int flags, int mode);
00067 static asmlinkage long (*original_sys_dup)(unsigned int filedes);
00068 #endif
00069 #if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
00070 static asmlinkage long (*original_sys_dup2)(unsigned int oldfd, unsigned int newfd);
00071 #endif
00072 #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
00073 static asmlinkage long (*original_sys_close)(unsigned int fd);
00074 #endif
00075 #ifdef ON_EXEC_SUPPORT
00076 static asmlinkage int (*original_sys_execve)(struct pt_regs regs);
00077 #endif
00078 #ifdef ON_UNLINK_SUPPORT
00079 static asmlinkage long (*original_sys_unlink)(const char *pathname);
00080 #endif
00081 #ifdef ON_RMDIR_SUPPORT
00082 static asmlinkage long (*original_sys_rmdir)(const char *pathname);
00083 #endif
00084
00085 static struct file_operations fops = {
00086 read: linux_dazuko_device_read,
00087 write: linux_dazuko_device_write,
00088 ioctl: linux_dazuko_device_ioctl,
00089 open: linux_dazuko_device_open,
00090 release: linux_dazuko_device_release,
00091 };
00092
00093 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
00094
00095
00096
00097
00098 #ifndef __wait_event_interruptible
00099 #define __wait_event_interruptible(wq, condition, ret) \
00100 do { \
00101 struct wait_queue __wait; \
00102 \
00103 __wait.task = current; \
00104 add_wait_queue(&wq, &__wait); \
00105 for (;;) { \
00106 current->state = TASK_INTERRUPTIBLE; \
00107 mb(); \
00108 if (condition) \
00109 break; \
00110 if (!signal_pending(current)) { \
00111 schedule(); \
00112 continue; \
00113 } \
00114 ret = -ERESTARTSYS; \
00115 break; \
00116 } \
00117 current->state = TASK_RUNNING; \
00118 remove_wait_queue(&wq, &__wait); \
00119 } while (0)
00120 #endif
00121
00122 #ifndef wait_event_interruptible
00123 #define wait_event_interruptible(wq, condition) \
00124 ({ \
00125 int __ret = 0; \
00126 if (!(condition)) \
00127 __wait_event_interruptible(wq, condition, __ret);\
00128 __ret; \
00129 })
00130 #define wait_event(wq, condition) \
00131 ({ \
00132 int __ret = 0; \
00133 if (!(condition)) \
00134 __wait_event_interruptible(wq, condition, __ret);\
00135 __ret; \
00136 })
00137 #endif
00138
00139 #endif
00140
00141
00142
00143
00144 inline void xp_init_mutex(struct xp_mutex *mutex)
00145 {
00146 #ifdef init_MUTEX
00147 init_MUTEX(&(mutex->mutex));
00148 #else
00149 sema_init(&(mutex->mutex), 1);
00150 #endif
00151 }
00152
00153 inline void xp_down(struct xp_mutex *mutex)
00154 {
00155 down(&(mutex->mutex));
00156 }
00157
00158 inline void xp_up(struct xp_mutex *mutex)
00159 {
00160 up(&(mutex->mutex));
00161 }
00162
00163 inline void xp_destroy_mutex(struct xp_mutex *mutex)
00164 {
00165 }
00166
00167
00168
00169
00170 inline void xp_init_rwlock(struct xp_rwlock *rwlock)
00171 {
00172 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00173 rwlock_init(&(rwlock->rwlock));
00174 #else
00175 rwlock->rwlock = RW_LOCK_UNLOCKED;
00176 #endif
00177 }
00178
00179 inline void xp_write_lock(struct xp_rwlock *rwlock)
00180 {
00181 write_lock(&(rwlock->rwlock));
00182 }
00183
00184 inline void xp_write_unlock(struct xp_rwlock *rwlock)
00185 {
00186 write_unlock(&(rwlock->rwlock));
00187 }
00188
00189 inline void xp_read_lock(struct xp_rwlock *rlock)
00190 {
00191 read_lock(&(rlock->rwlock));
00192 }
00193
00194 inline void xp_read_unlock(struct xp_rwlock *rlock)
00195 {
00196 read_unlock(&(rlock->rwlock));
00197 }
00198
00199 inline void xp_destroy_rwlock(struct xp_rwlock *rwlock)
00200 {
00201 }
00202
00203
00204
00205
00206 inline int xp_init_queue(struct xp_queue *queue)
00207 {
00208 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00209 init_waitqueue_head(&(queue->queue));
00210 #else
00211 queue = NULL;
00212 #endif
00213
00214 return 0;
00215 }
00216
00217 inline int xp_wait_until_condition(struct xp_queue *queue, int (*cfunction)(void *), void *cparam, int allow_interrupt)
00218 {
00219
00220
00221 if (allow_interrupt)
00222 {
00223 return wait_event_interruptible(queue->queue, cfunction(cparam) != 0);
00224 }
00225 else
00226 {
00227 wait_event(queue->queue, cfunction(cparam) != 0);
00228 }
00229
00230 return 0;
00231 }
00232
00233 inline int xp_notify(struct xp_queue *queue)
00234 {
00235 wake_up(&(queue->queue));
00236 return 0;
00237 }
00238
00239 inline int xp_destroy_queue(struct xp_queue *queue)
00240 {
00241 return 0;
00242 }
00243
00244
00245
00246
00247 inline void* xp_malloc(size_t size)
00248 {
00249 return kmalloc(size, GFP_KERNEL);
00250 }
00251
00252 inline int xp_free(void *ptr)
00253 {
00254 kfree(ptr);
00255 return 0;
00256 }
00257
00258 inline int xp_copyin(const void *user_src, void *kernel_dest, size_t size)
00259 {
00260 return copy_from_user(kernel_dest, user_src, size);
00261 }
00262
00263 inline int xp_copyout(const void *kernel_src, void *user_dest, size_t size)
00264 {
00265 return copy_to_user(user_dest, kernel_src, size);
00266 }
00267
00268 inline int xp_verify_user_writable(const void *user_ptr, size_t size)
00269 {
00270 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
00271 return verify_area(VERIFY_WRITE, user_ptr, size);
00272 #else
00273 return 0;
00274 #endif
00275 }
00276
00277 inline int xp_verify_user_readable(const void *user_ptr, size_t size)
00278 {
00279 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
00280 return verify_area(VERIFY_READ, user_ptr, size);
00281 #else
00282 return 0;
00283 #endif
00284 }
00285
00286
00287
00288
00289 inline int xp_is_absolute_path(const char *path)
00290 {
00291 return (path[0] == '/');
00292 }
00293
00294
00295
00296
00297 inline int xp_atomic_set(struct xp_atomic *atomic, int value)
00298 {
00299 atomic_set(&(atomic->atomic), value);
00300 return 0;
00301 }
00302
00303 inline int xp_atomic_inc(struct xp_atomic *atomic)
00304 {
00305 #ifdef MODULE
00306 if (atomic == &active)
00307 MOD_INC_USE_COUNT;
00308 #endif
00309
00310 atomic_inc(&(atomic->atomic));
00311 return 0;
00312 }
00313
00314 inline int xp_atomic_dec(struct xp_atomic *atomic)
00315 {
00316 #ifdef MODULE
00317 if (atomic == &active)
00318 MOD_DEC_USE_COUNT;
00319 #endif
00320
00321 atomic_dec(&(atomic->atomic));
00322 return 0;
00323 }
00324
00325 inline int xp_atomic_read(struct xp_atomic *atomic)
00326 {
00327 return atomic_read(&(atomic->atomic));
00328 }
00329
00330
00331
00332
00333 static int dazuko_get_filename_dentry(struct xp_file_struct *xfs, int follow_symlinks, const char *local_filename, int user_ptr)
00334 {
00335
00336
00337
00338
00339 const char *filename = NULL;
00340 int putname_filename = 0;
00341 int filename_length = 0;
00342 int rc = 0;
00343
00344
00345 if (user_ptr)
00346 {
00347
00348 filename = (char *)getname(local_filename);
00349
00350
00351 if (IS_ERR(filename))
00352 {
00353 filename = NULL;
00354 return 0;
00355 }
00356
00357
00358 putname_filename = 1;
00359 }
00360 else
00361 {
00362 filename = local_filename;
00363 }
00364
00365 filename_length = dazuko_get_filename_length(filename);
00366
00367 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00368 {
00369 dazuko_bzero(&(xfs->nd), sizeof(struct nameidata));
00370
00371
00372 if (!path_init(filename, (follow_symlinks ? LOOKUP_FOLLOW : 0) | LOOKUP_POSITIVE, &(xfs->nd)))
00373 goto dentry_exit;
00374
00375 if (!xfs->path_release_nd)
00376 {
00377
00378 if (path_walk(filename, &(xfs->nd)))
00379 goto dentry_exit;
00380
00381
00382 xfs->path_release_nd = 1;
00383 }
00384
00385
00386
00387
00388
00389 if (!xfs->dput_dentry)
00390 {
00391 xfs->dentry = dget(xfs->nd.dentry);
00392
00393
00394 xfs->dput_dentry = 1;
00395 }
00396 }
00397 #else
00398 {
00399 if (!xfs->dput_dentry)
00400 {
00401 xfs->dentry = lookup_dentry(filename, NULL, (follow_symlinks ? LOOKUP_FOLLOW : 0));
00402 if (IS_ERR(xfs->dentry))
00403 {
00404 xfs->dentry = NULL;
00405 goto dentry_exit;
00406 }
00407
00408
00409 xfs->dput_dentry = 1;
00410 }
00411 }
00412 #endif
00413
00414
00415 if (xfs->dentry->d_inode == NULL)
00416 {
00417 goto dentry_exit;
00418 }
00419 else
00420 {
00421
00422 rc = 1;
00423 }
00424
00425 dentry_exit:
00426 if (putname_filename)
00427 putname(filename);
00428
00429 return rc;
00430 }
00431
00432 static int dazuko_get_fd_dentry(struct xp_file_struct *xfs)
00433 {
00434 if (current->files != NULL)
00435 {
00436 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00437 {
00438 read_lock(¤t->files->file_lock);
00439 }
00440 #endif
00441
00442 if (current->files->fd != NULL)
00443 {
00444 if (current->files->fd[xfs->fd] != NULL)
00445 {
00446 if (current->files->fd[xfs->fd]->f_dentry != NULL)
00447 {
00448 xfs->dentry = dget(current->files->fd[xfs->fd]->f_dentry);
00449 xfs->dput_dentry = 1;
00450
00451 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00452 {
00453 if (current->files->fd[xfs->fd]->f_vfsmnt != NULL)
00454 {
00455 xfs->vfsmount = mntget(current->files->fd[xfs->fd]->f_vfsmnt);
00456 xfs->mntput_vfsmount = 1;
00457 }
00458 else
00459 {
00460 dput(xfs->dentry);
00461 xfs->dentry = NULL;
00462 xfs->dput_dentry = 0;
00463 }
00464 }
00465 #endif
00466 }
00467 }
00468 }
00469
00470 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00471 {
00472 read_unlock(¤t->files->file_lock);
00473 }
00474 #endif
00475 }
00476
00477
00478 if (xfs->dentry == NULL)
00479 return 0;
00480
00481
00482 if (xfs->dentry->d_inode == NULL)
00483 return 0;
00484
00485 return 1;
00486 }
00487
00488 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
00489 static char * __d_path(struct dentry *dentry, struct dentry *root, char *buffer, int buflen)
00490 {
00491
00492
00493
00494 char * end = buffer+buflen;
00495 char * retval;
00496
00497 *--end = '\0';
00498 buflen--;
00499 if (dentry->d_parent != dentry && list_empty(&dentry->d_hash)) {
00500 buflen -= 10;
00501 end -= 10;
00502 memcpy(end, " (deleted)", 10);
00503 }
00504
00505
00506 retval = end-1;
00507 *retval = '/';
00508
00509 for (;;) {
00510 struct dentry * parent;
00511 int namelen;
00512
00513 if (dentry == root)
00514 break;
00515 dentry = dentry->d_covers;
00516 parent = dentry->d_parent;
00517 if (dentry == parent)
00518 break;
00519 namelen = dentry->d_name.len;
00520 buflen -= namelen + 1;
00521 if (buflen < 0)
00522 break;
00523 end -= namelen;
00524 memcpy(end, dentry->d_name.name, namelen);
00525 *--end = '/';
00526 retval = end;
00527 dentry = parent;
00528 }
00529 return retval;
00530 }
00531 #endif
00532
00533 static int dazuko_get_full_filename(struct xp_file_struct *xfs)
00534 {
00535
00536
00537
00538 char *temp;
00539 struct dentry *root;
00540
00541 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00542 struct vfsmount *rootmnt;
00543 #endif
00544
00545
00546 if (!xfs->free_page_buffer)
00547 {
00548
00549 xfs->buffer = (char *)__get_free_page(GFP_USER);
00550
00551
00552 xfs->free_page_buffer = 1;
00553 }
00554
00555 root = dget(orig_root);
00556
00557 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00558 {
00559
00560 if (!xfs->mntput_vfsmount)
00561 {
00562 xfs->vfsmount = mntget(xfs->nd.mnt);
00563
00564
00565 xfs->mntput_vfsmount = 1;
00566 }
00567
00568
00569
00570 rootmnt = mntget(orig_rootmnt);
00571
00572 spin_lock(&dcache_lock);
00573 temp = __d_path(xfs->dentry, xfs->vfsmount, root, rootmnt, xfs->buffer, PAGE_SIZE);
00574 spin_unlock(&dcache_lock);
00575
00576 mntput(rootmnt);
00577 }
00578 #else
00579 {
00580
00581
00582 temp = __d_path(xfs->dentry, root, xfs->buffer, PAGE_SIZE);
00583 }
00584 #endif
00585
00586 dput(root);
00587
00588
00589 if (temp == NULL)
00590 return 0;
00591
00592
00593 if (!xfs->free_full_filename)
00594 {
00595 xfs->full_filename_length = dazuko_get_filename_length(temp);
00596
00597 xfs->full_filename = (char *)xp_malloc(xfs->full_filename_length + 1);
00598 if (!xfs->full_filename)
00599 return 0;
00600
00601
00602 xfs->free_full_filename = 1;
00603
00604 memcpy(xfs->full_filename, temp, xfs->full_filename_length + 1);
00605 }
00606
00607
00608
00609 return 1;
00610 }
00611
00612 static inline int dazuko_fill_file_struct_cleanup(struct dazuko_file_struct *dfs)
00613 {
00614
00615
00616
00617
00618 if (dfs->extra_data == NULL)
00619 return 0;
00620
00621 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00622 {
00623 if (dfs->extra_data->mntput_vfsmount)
00624 {
00625 mntput(dfs->extra_data->vfsmount);
00626 dfs->extra_data->mntput_vfsmount = 0;
00627 }
00628 }
00629 #endif
00630
00631 if (dfs->extra_data->free_page_buffer)
00632 {
00633 free_page((unsigned long)dfs->extra_data->buffer);
00634 dfs->extra_data->free_page_buffer = 0;
00635 }
00636
00637 if (dfs->extra_data->dput_dentry)
00638 {
00639 dput(dfs->extra_data->dentry);
00640 dfs->extra_data->dput_dentry = 0;
00641 }
00642
00643 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
00644 {
00645 if (dfs->extra_data->path_release_nd)
00646 {
00647 path_release(&(dfs->extra_data->nd));
00648 dfs->extra_data->path_release_nd = 0;
00649 }
00650 }
00651 #endif
00652
00653 return 0;
00654 }
00655
00656 inline int xp_fill_file_struct(struct dazuko_file_struct *dfs)
00657 {
00658 struct dazuko_file_listnode *listnode;
00659 int follow_symlinks = 0;
00660 int error = -1;
00661 int loopcount = 0;
00662 char *freeparentpath = NULL;
00663 char *parentpath = NULL;
00664 char *rawfilename = NULL;
00665 int i;
00666
00667 if (dfs == NULL)
00668 return error;
00669
00670
00671 if (dfs->aliases != NULL)
00672 return 0;
00673
00674 if (dfs->extra_data == NULL)
00675 return error;
00676
00677
00678 while (1)
00679 {
00680 loopcount++;
00681
00682 if (dfs->extra_data->user_filename != NULL)
00683 {
00684 if (!dazuko_get_filename_dentry(dfs->extra_data, follow_symlinks, dfs->extra_data->user_filename, 1))
00685 {
00686
00687
00688 freeparentpath = getname(dfs->extra_data->user_filename);
00689
00690 if (IS_ERR(freeparentpath))
00691 {
00692 freeparentpath = NULL;
00693 break;
00694 }
00695
00696 parentpath = freeparentpath;
00697
00698 i = dazuko_get_filename_length(parentpath);
00699 if (i == 0)
00700 break;
00701
00702 while (i > 0)
00703 {
00704 if (parentpath[i] == '/')
00705 {
00706 rawfilename = parentpath + i + 1;
00707 parentpath[i] = 0;
00708 break;
00709 }
00710
00711 i--;
00712 }
00713 if (i == 0)
00714 {
00715 if (parentpath[i] == '/')
00716 {
00717 rawfilename = parentpath + 1;
00718 parentpath = "/";
00719 }
00720 else
00721 {
00722 rawfilename = parentpath;
00723 parentpath = ".";
00724 }
00725 }
00726
00727 if (!dazuko_get_filename_dentry(dfs->extra_data, follow_symlinks, parentpath, 0))
00728 {
00729 putname(freeparentpath);
00730 freeparentpath = NULL;
00731 break;
00732 }
00733 }
00734 }
00735 else
00736 {
00737 if (!dazuko_get_fd_dentry(dfs->extra_data))
00738 {
00739 break;
00740 }
00741 else
00742 {
00743
00744 loopcount++;
00745 }
00746 }
00747
00748
00749 if (!dazuko_get_full_filename(dfs->extra_data))
00750 break;
00751
00752 if (freeparentpath != NULL)
00753 {
00754
00755
00756 parentpath = dfs->extra_data->full_filename;
00757 i = dazuko_get_filename_length(rawfilename);
00758
00759 dfs->extra_data->full_filename = (char *)xp_malloc(dfs->extra_data->full_filename_length + 1 + i + 1);
00760 if (dfs->extra_data->full_filename == NULL)
00761 {
00762
00763 dfs->extra_data->full_filename = parentpath;
00764 break;
00765 }
00766
00767
00768 memcpy(dfs->extra_data->full_filename, parentpath, dfs->extra_data->full_filename_length);
00769
00770
00771 if (dfs->extra_data->full_filename[dfs->extra_data->full_filename_length - 1] != '/')
00772 {
00773 dfs->extra_data->full_filename[dfs->extra_data->full_filename_length] = '/';
00774 dfs->extra_data->full_filename_length++;
00775 }
00776
00777
00778 memcpy(dfs->extra_data->full_filename + dfs->extra_data->full_filename_length, rawfilename, i + 1);
00779 dfs->extra_data->full_filename_length += i;
00780
00781
00782 xp_free(parentpath);
00783 }
00784 else
00785 {
00786 dfs->file_p.size = dfs->extra_data->dentry->d_inode->i_size;
00787 dfs->file_p.set_size = 1;
00788 dfs->file_p.uid = dfs->extra_data->dentry->d_inode->i_uid;
00789 dfs->file_p.set_uid = 1;
00790 dfs->file_p.gid = dfs->extra_data->dentry->d_inode->i_gid;
00791 dfs->file_p.set_gid = 1;
00792 dfs->file_p.mode = dfs->extra_data->dentry->d_inode->i_mode;
00793 dfs->file_p.set_mode = 1;
00794 dfs->file_p.device_type = dfs->extra_data->dentry->d_inode->i_dev;
00795 dfs->file_p.set_device_type = 1;
00796 }
00797
00798 if (S_ISREG(dfs->extra_data->dentry->d_inode->i_mode))
00799 {
00800 dfs->file_p.type = DAZUKO_REGULAR;
00801 dfs->file_p.set_type = 1;
00802 }
00803 else if (S_ISLNK(dfs->extra_data->dentry->d_inode->i_mode))
00804 {
00805 dfs->file_p.type = DAZUKO_LINK;
00806 dfs->file_p.set_type = 1;
00807 }
00808 else if (S_ISDIR(dfs->extra_data->dentry->d_inode->i_mode))
00809 {
00810 dfs->file_p.type = DAZUKO_DIRECTORY;
00811 dfs->file_p.set_type = 1;
00812 }
00813
00814 listnode = (struct dazuko_file_listnode *)xp_malloc(sizeof(struct dazuko_file_listnode));
00815 if (listnode == NULL)
00816 break;
00817
00818 dazuko_bzero(listnode, sizeof(struct dazuko_file_listnode));
00819
00820 listnode->filename = dfs->extra_data->full_filename;
00821 listnode->filename_length = dfs->extra_data->full_filename_length;
00822
00823 dfs->extra_data->free_full_filename = 0;
00824 dfs->extra_data->full_filename = NULL;
00825 dfs->extra_data->full_filename_length = 0;
00826
00827 if (dfs->aliases == NULL)
00828 {
00829 listnode->next = dfs->aliases;
00830 dfs->aliases = listnode;
00831 }
00832 else
00833 {
00834 listnode->next = dfs->aliases->next;
00835 dfs->aliases->next = listnode;
00836 }
00837
00838
00839 error = 0;
00840
00841 if (!follow_symlinks && dfs->file_p.set_type && dfs->file_p.type == DAZUKO_LINK && loopcount < 2)
00842 {
00843
00844
00845 follow_symlinks = 1;
00846
00847
00848 dazuko_fill_file_struct_cleanup(dfs);
00849 }
00850 else
00851 {
00852
00853
00854 break;
00855 }
00856 }
00857
00858 if (freeparentpath != NULL)
00859 putname(freeparentpath);
00860
00861 dazuko_fill_file_struct_cleanup(dfs);
00862
00863 return error;
00864 }
00865
00866 static int dazuko_file_struct_cleanup(struct dazuko_file_struct **dfs)
00867 {
00868 struct dazuko_file_listnode *cur;
00869
00870 if (dfs == NULL)
00871 return 0;
00872
00873 if (*dfs == NULL)
00874 return 0;
00875
00876 while ((*dfs)->aliases != NULL)
00877 {
00878 cur = (*dfs)->aliases;
00879 (*dfs)->aliases = cur->next;
00880
00881 if (cur->filename != NULL)
00882 xp_free(cur->filename);
00883
00884 xp_free(cur);
00885 }
00886
00887 if ((*dfs)->extra_data != NULL)
00888 xp_free((*dfs)->extra_data);
00889
00890 xp_free(*dfs);
00891
00892 *dfs = NULL;
00893
00894 return 0;
00895 }
00896
00897
00898
00899
00900 static inline int check_parent(struct task_struct *parent, struct task_struct *child)
00901 {
00902 struct task_struct *ts = child;
00903
00904 if (parent == NULL || child == NULL)
00905 return -1;
00906
00907 while (1)
00908 {
00909 if (ts == parent)
00910 return 0;
00911
00912 #ifdef TASKSTRUCT_USES_PARENT
00913 if (ts->parent == NULL)
00914 break;
00915
00916 if (ts == ts->parent)
00917 break;
00918
00919 ts = ts->parent;
00920 #else
00921 if (ts->p_pptr == NULL)
00922 break;
00923
00924 if (ts == ts->p_pptr)
00925 break;
00926
00927 ts = ts->p_pptr;
00928 #endif
00929 }
00930
00931 return -1;
00932 }
00933
00934 inline int xp_id_compare(struct xp_daemon_id *id1, struct xp_daemon_id *id2, int check_related)
00935 {
00936 if (id1 == NULL || id2 == NULL)
00937 return DAZUKO_DIFFERENT;
00938
00939
00940
00941
00942
00943
00944 if (id1->file != NULL && id1->file == id2->file)
00945 return DAZUKO_SAME;
00946
00947 if (id1->pid == id2->pid && id1->current_p == id2->current_p && id1->files == id2->files)
00948 return DAZUKO_SAME;
00949
00950 if (check_related)
00951 {
00952 if (check_parent(id1->current_p, id2->current_p) == 0)
00953 {
00954 return DAZUKO_CHILD;
00955 }
00956 else if (id1->pid == id2->pid || id1->current_p == id2->current_p || id1->files == id2->files)
00957 {
00958 return DAZUKO_SUSPICIOUS;
00959 }
00960 }
00961
00962 return DAZUKO_DIFFERENT;
00963 }
00964
00965 inline int xp_id_free(struct xp_daemon_id *id)
00966 {
00967 xp_free(id);
00968
00969 return 0;
00970 }
00971
00972 inline struct xp_daemon_id* xp_id_copy(struct xp_daemon_id *id)
00973 {
00974 struct xp_daemon_id *ptr;
00975
00976 if (id == NULL)
00977 return NULL;
00978
00979 ptr = (struct xp_daemon_id *)xp_malloc(sizeof(struct xp_daemon_id));
00980
00981 if (ptr != NULL)
00982 {
00983 ptr->pid = id->pid;
00984 ptr->file = id->file;
00985 ptr->current_p = id->current_p;
00986 ptr->files = id->files;
00987 }
00988
00989 return ptr;
00990 }
00991
00992
00993
00994
00995 int xp_set_event_properties(struct event_properties *event_p, struct xp_daemon_id *xp_id)
00996 {
00997 event_p->pid = xp_id->pid;
00998 event_p->set_pid = 1;
00999
01000 return 0;
01001 }
01002
01003
01004
01005
01006 int xp_init_cache(unsigned long ttl)
01007 {
01008 return -1;
01009 }
01010
01011
01012
01013
01014 #if defined(ON_OPEN_SUPPORT)
01015 asmlinkage long linux_dazuko_sys_open(const char *filename, int flags, int mode)
01016 {
01017
01018
01019
01020
01021
01022
01023 struct dazuko_file_struct *dfs = NULL;
01024 int error = 0;
01025 int fd;
01026 int check_error = 0;
01027 struct event_properties event_p;
01028 struct xp_daemon_id xp_id;
01029
01030 xp_id.pid = current->pid;
01031 xp_id.file = NULL;
01032 xp_id.current_p = current;
01033 xp_id.files = current->files;
01034
01035 check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL);
01036
01037 if (!check_error)
01038 {
01039 dazuko_bzero(&event_p, sizeof(event_p));
01040 event_p.flags = flags;
01041 event_p.set_flags = 1;
01042 event_p.mode = mode;
01043 event_p.set_mode = 1;
01044 event_p.pid = current->pid;
01045 event_p.set_pid = 1;
01046 event_p.uid = current->uid;
01047 event_p.set_uid = 1;
01048
01049 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
01050 if (dfs != NULL)
01051 {
01052 dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
01053
01054 dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
01055 if (dfs->extra_data != NULL)
01056 {
01057 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
01058
01059 dfs->extra_data->user_filename = filename;
01060
01061 error = dazuko_process_access(DAZUKO_ON_OPEN, dfs, &event_p, NULL);
01062
01063 dazuko_file_struct_cleanup(&dfs);
01064 }
01065 else
01066 {
01067 xp_free(dfs);
01068 dfs = NULL;
01069 }
01070 }
01071 }
01072
01073 if (error)
01074 {
01075
01076
01077 fd = -1;
01078 }
01079 else
01080 {
01081
01082 fd = original_sys_open(filename, flags, mode);
01083 }
01084
01085 return fd;
01086 }
01087
01088 asmlinkage long linux_dazuko_sys_dup(unsigned int filedes)
01089 {
01090 struct dazuko_file_struct *dfs = NULL;
01091 struct event_properties event_p;
01092 struct xp_daemon_id xp_id;
01093 int error = 0;
01094 int check_error = 0;
01095
01096 xp_id.pid = current->pid;
01097 xp_id.file = NULL;
01098 xp_id.current_p = current;
01099 xp_id.files = current->files;
01100
01101 check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL);
01102
01103 if (!check_error)
01104 {
01105 dazuko_bzero(&event_p, sizeof(event_p));
01106
01107 if (filedes >= 0 && filedes < current->files->max_fds)
01108 {
01109 event_p.pid = current->pid;
01110 event_p.set_pid = 1;
01111 event_p.uid = current->uid;
01112 event_p.set_uid = 1;
01113
01114 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
01115 if (dfs != NULL)
01116 {
01117 dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
01118
01119 dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
01120 if (dfs->extra_data != NULL)
01121 {
01122 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
01123
01124 dfs->extra_data->fd = filedes;
01125
01126 error = dazuko_process_access(DAZUKO_ON_OPEN, dfs, &event_p, NULL);
01127
01128 dazuko_file_struct_cleanup(&dfs);
01129 }
01130 else
01131 {
01132 xp_free(dfs);
01133 dfs = NULL;
01134 }
01135 }
01136 }
01137 else
01138 {
01139 check_error = -1;
01140 }
01141 }
01142
01143 if (error)
01144 {
01145
01146
01147 error = -EPERM;
01148 }
01149 else
01150 {
01151
01152 error = original_sys_dup(filedes);
01153 }
01154
01155 return error;
01156 }
01157 #endif
01158
01159 #if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
01160 asmlinkage long linux_dazuko_sys_dup2(unsigned int oldfd, unsigned int newfd)
01161 {
01162 struct dazuko_file_struct *dfs = NULL;
01163 struct event_properties open_event_p;
01164 struct xp_daemon_id xp_id;
01165 int error = 0;
01166 int check_error = 0;
01167 #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
01168 struct event_properties close_event_p;
01169 int will_close_newfd = 0;
01170 #endif
01171
01172 xp_id.pid = current->pid;
01173 xp_id.file = NULL;
01174 xp_id.current_p = current;
01175 xp_id.files = current->files;
01176
01177 check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL);
01178
01179 if (!check_error)
01180 {
01181 dazuko_bzero(&open_event_p, sizeof(open_event_p));
01182
01183 if (oldfd != newfd && oldfd >= 0 && oldfd < current->files->max_fds)
01184 {
01185 open_event_p.pid = current->pid;
01186 open_event_p.set_pid = 1;
01187 open_event_p.uid = current->uid;
01188 open_event_p.set_uid = 1;
01189
01190 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
01191 if (dfs != NULL)
01192 {
01193 dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
01194
01195 dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
01196 if (dfs->extra_data != NULL)
01197 {
01198 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
01199
01200 dfs->extra_data->fd = oldfd;
01201
01202 error = dazuko_process_access(DAZUKO_ON_OPEN, dfs, &open_event_p, NULL);
01203
01204 dazuko_file_struct_cleanup(&dfs);
01205 }
01206 else
01207 {
01208 xp_free(dfs);
01209 dfs = NULL;
01210 }
01211 }
01212 }
01213 else
01214 {
01215 check_error = -1;
01216 }
01217 }
01218
01219 if (error)
01220 {
01221
01222
01223 error = -EPERM;
01224 }
01225 else
01226 {
01227 #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
01228 if (newfd >= 0 && newfd < current->files->max_fds)
01229 {
01230 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
01231 {
01232 read_lock(¤t->files->file_lock);
01233 }
01234 #endif
01235
01236 if (current->files->fd[newfd] != NULL)
01237 {
01238 will_close_newfd = 1;
01239 }
01240
01241 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
01242 {
01243 read_unlock(¤t->files->file_lock);
01244 }
01245 #endif
01246 }
01247 #endif
01248
01249
01250 error = original_sys_dup2(oldfd, newfd);
01251
01252 #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
01253 {
01254 if (!check_error)
01255 {
01256 if (error >= 0 && will_close_newfd)
01257 {
01258 dazuko_bzero(&close_event_p, sizeof(close_event_p));
01259
01260 close_event_p.pid = current->pid;
01261 close_event_p.set_pid = 1;
01262 close_event_p.uid = current->uid;
01263 close_event_p.set_uid = 1;
01264
01265 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
01266 if (dfs != NULL)
01267 {
01268 dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
01269
01270 dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
01271 if (dfs->extra_data != NULL)
01272 {
01273 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
01274
01275 dfs->extra_data->fd = newfd;
01276
01277 dazuko_process_access(DAZUKO_ON_CLOSE, dfs, &close_event_p, NULL);
01278
01279 dazuko_file_struct_cleanup(&dfs);
01280 }
01281 else
01282 {
01283 xp_free(dfs);
01284 dfs = NULL;
01285 }
01286 }
01287 }
01288 }
01289 }
01290 #endif
01291 }
01292
01293 return error;
01294 }
01295 #endif
01296
01297 #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
01298 asmlinkage long linux_dazuko_sys_close(unsigned int fd)
01299 {
01300
01301
01302
01303 struct dazuko_file_struct *dfs = NULL;
01304 int error = 0;
01305 int check_error = 0;
01306 struct event_properties event_p;
01307 struct xp_daemon_id xp_id;
01308
01309 xp_id.pid = current->pid;
01310 xp_id.file = NULL;
01311 xp_id.current_p = current;
01312 xp_id.files = current->files;
01313
01314 check_error = dazuko_check_access(DAZUKO_ON_CLOSE, 1, &xp_id, NULL);
01315
01316 if (!check_error && fd >= 0 && fd < current->files->max_fds)
01317 {
01318 dazuko_bzero(&event_p, sizeof(event_p));
01319
01320 event_p.pid = current->pid;
01321 event_p.set_pid = 1;
01322 event_p.uid = current->uid;
01323 event_p.set_uid = 1;
01324
01325 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
01326 if (dfs != NULL)
01327 {
01328 dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
01329
01330 dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
01331 if (dfs->extra_data != NULL)
01332 {
01333 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
01334
01335 dfs->extra_data->fd = fd;
01336
01337 check_error = xp_fill_file_struct(dfs);
01338 }
01339 else
01340 {
01341 xp_free(dfs);
01342 dfs = NULL;
01343 }
01344 }
01345 }
01346
01347 error = original_sys_close(fd);
01348
01349 if (dfs != NULL)
01350 {
01351 if (!check_error)
01352 {
01353 dazuko_process_access(DAZUKO_ON_CLOSE, dfs, &event_p, NULL);
01354 }
01355
01356 dazuko_file_struct_cleanup(&dfs);
01357 }
01358
01359 return error;
01360 }
01361 #endif
01362
01363 #ifdef ON_EXEC_SUPPORT
01364 asmlinkage int linux_dazuko_sys_execve(struct pt_regs regs)
01365 {
01366
01367
01368
01369
01370
01371
01372
01373 struct dazuko_file_struct *dfs = NULL;
01374 char *filename;
01375 int error = 0;
01376 int check_error = 0;
01377 struct event_properties event_p;
01378 struct xp_daemon_id xp_id;
01379 struct slot_list *sl = NULL;
01380
01381 xp_id.pid = current->pid;
01382 xp_id.file = NULL;
01383 xp_id.current_p = current;
01384 xp_id.files = current->files;
01385
01386 check_error = dazuko_check_access(DAZUKO_ON_EXEC, 0, &xp_id, &sl);
01387
01388 if (!check_error)
01389 {
01390 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
01391 if (dfs)
01392 {
01393 dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
01394
01395 dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
01396 if (dfs->extra_data != NULL)
01397 {
01398 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
01399
01400 dfs->extra_data->user_filename = (char *)regs.ebx;
01401
01402 dazuko_bzero(&event_p, sizeof(event_p));
01403 event_p.pid = current->pid;
01404 event_p.set_pid = 1;
01405 event_p.uid = current->uid;
01406 event_p.set_uid = 1;
01407
01408 error = dazuko_process_access(DAZUKO_ON_EXEC, dfs, &event_p, sl);
01409
01410 dazuko_file_struct_cleanup(&dfs);
01411 }
01412 else
01413 {
01414 xp_free(dfs);
01415 dfs = NULL;
01416 }
01417 }
01418 }
01419
01420 if (error)
01421 {
01422 return error;
01423 }
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
01437 {
01438 filename = getname((char *) regs.ebx);
01439 error = PTR_ERR(filename);
01440 if (IS_ERR(filename))
01441 {
01442 filename = NULL;
01443 goto out;
01444 }
01445 error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, ®s);
01446 if (error == 0)
01447 current->ptrace &= ~PT_DTRACE;
01448 putname(filename);
01449 out:
01450 return error;
01451 }
01452 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,20)
01453 {
01454 #ifdef __SMP__
01455 lock_kernel();
01456 #endif
01457 filename = getname((char *) regs.ebx);
01458 error = PTR_ERR(filename);
01459 if (IS_ERR(filename))
01460 {
01461 filename = NULL;
01462 goto out;
01463 }
01464 error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, ®s);
01465 if (error == 0)
01466 current->ptrace &= ~PT_DTRACE;
01467 putname(filename);
01468 out:
01469 #ifdef __SMP__
01470 unlock_kernel();
01471 #endif
01472 return error;
01473 }
01474 #else
01475 {
01476 #ifdef __SMP__
01477 lock_kernel();
01478 #endif
01479 filename = getname((char *) regs.ebx);
01480 error = PTR_ERR(filename);
01481 if (IS_ERR(filename))
01482 {
01483 filename = NULL;
01484 goto out;
01485 }
01486 error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, ®s);
01487 if (error == 0)
01488 current->flags &= ~PF_DTRACE;
01489 putname(filename);
01490 out:
01491 #ifdef __SMP__
01492 unlock_kernel();
01493 #endif
01494 return error;
01495 }
01496 #endif
01497 }
01498 #endif
01499
01500 static inline int linux_dazuko_sys_generic(int event, const char *user_pathname, int daemon_is_allowed)
01501 {
01502 struct dazuko_file_struct *dfs = NULL;
01503 int error = 0;
01504 int check_error = 0;
01505 struct event_properties event_p;
01506 struct xp_daemon_id xp_id;
01507 struct slot_list *sl = NULL;
01508
01509 xp_id.pid = current->pid;
01510 xp_id.file = NULL;
01511 xp_id.current_p = current;
01512 xp_id.files = current->files;
01513
01514 check_error = dazuko_check_access(event, daemon_is_allowed, &xp_id, &sl);
01515
01516 if (!check_error)
01517 {
01518 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
01519 if (dfs)
01520 {
01521 dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
01522
01523 dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
01524 if (dfs->extra_data != NULL)
01525 {
01526 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
01527
01528 dfs->extra_data->user_filename = user_pathname;
01529
01530 dazuko_bzero(&event_p, sizeof(event_p));
01531 event_p.pid = current->pid;
01532 event_p.set_pid = 1;
01533 event_p.uid = current->uid;
01534 event_p.set_uid = 1;
01535
01536 error = dazuko_process_access(event, dfs, &event_p, sl);
01537
01538 dazuko_file_struct_cleanup(&dfs);
01539 }
01540 else
01541 {
01542 xp_free(dfs);
01543 dfs = NULL;
01544 }
01545 }
01546 }
01547
01548 return error;
01549 }
01550
01551 #ifdef ON_UNLINK_SUPPORT
01552 asmlinkage long linux_dazuko_sys_unlink(const char *pathname)
01553 {
01554 int error;
01555
01556 error = linux_dazuko_sys_generic(DAZUKO_ON_UNLINK, pathname, 1);
01557
01558 if (error)
01559 return error;
01560
01561 return original_sys_unlink(pathname);
01562 }
01563 #endif
01564
01565 #ifdef ON_RMDIR_SUPPORT
01566 asmlinkage long linux_dazuko_sys_rmdir(const char *pathname)
01567 {
01568 int error;
01569
01570 error = linux_dazuko_sys_generic(DAZUKO_ON_RMDIR, pathname, 1);
01571
01572 if (error)
01573 return error;
01574
01575 return original_sys_rmdir(pathname);
01576 }
01577 #endif
01578
01579
01580
01581
01582 #ifdef HIDDEN_SCT
01583 static void** dazuko_get_sct()
01584 {
01585 unsigned long ptr;
01586 extern int loops_per_jiffy;
01587 unsigned long *p;
01588
01589 for (ptr=(unsigned long)&loops_per_jiffy ; ptr<(unsigned long)&boot_cpu_data ; ptr+=sizeof(void *))
01590 {
01591 p = (unsigned long *)ptr;
01592 if (p[6] == (unsigned long)sys_close)
01593 {
01594 return (void **)p;
01595 }
01596 }
01597
01598 return NULL;
01599 }
01600 #endif
01601
01602 #define DAZUKO_HOOK(syscall_func) do \
01603 { \
01604 original_sys_##syscall_func = sys_call_table[__NR_##syscall_func]; \
01605 sys_call_table[__NR_##syscall_func] = linux_dazuko_sys_##syscall_func; \
01606 DPRINT(("dazuko: hooked sys_" #syscall_func "\n")); \
01607 } \
01608 while (0)
01609
01610 inline int xp_sys_hook()
01611 {
01612
01613
01614 #ifdef HIDDEN_SCT
01615 sys_call_table = dazuko_get_sct();
01616 if (sys_call_table == NULL)
01617 {
01618 xp_print("dazuko: panic (sys_call_table == NULL)\n");
01619 return -1;
01620 }
01621 #endif
01622
01623
01624
01625 if (current == NULL)
01626 {
01627 xp_print("dazuko: panic (current == NULL)\n");
01628 return -1;
01629 }
01630 if (current->fs == NULL)
01631 {
01632 xp_print("dazuko: panic (current->fs == NULL)\n");
01633 return -1;
01634 }
01635 if (current->fs->root == NULL)
01636 {
01637 xp_print("dazuko: panic (current->fs->root == NULL)\n");
01638 return -1;
01639 }
01640 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
01641 {
01642 if (current->fs->rootmnt == NULL)
01643 {
01644 xp_print("dazuko: panic (current->fs->rootmnt == NULL)\n");
01645 return -1;
01646 }
01647 }
01648 #endif
01649
01650
01651 #ifdef DEVFS_SUPPORT
01652 dev_major = devfs_register_chrdev(0, DEVICE_NAME, &fops);
01653 devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT,
01654 dev_major, 0, S_IFCHR | S_IRUSR | S_IWUSR,
01655 &fops, NULL);
01656 #else
01657 dev_major = register_chrdev(DAZUKO_DM, DEVICE_NAME, &fops);
01658 #endif
01659 if (dev_major < 0)
01660 {
01661 xp_print("dazuko: unable to register device chrdev, err=%d\n", dev_major);
01662 return dev_major;
01663 }
01664
01665
01666
01667
01668
01669 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
01670 {
01671 read_lock(¤t->fs->lock);
01672 orig_rootmnt = current->fs->rootmnt;
01673 }
01674 #endif
01675
01676 orig_root = current->fs->root;
01677
01678 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
01679 read_unlock(¤t->fs->lock);
01680 #endif
01681
01682
01683 #ifdef __SMP__
01684 lock_kernel();
01685 #endif
01686
01687 fsync_dev(0);
01688
01689 #if defined(ON_OPEN_SUPPORT)
01690 DAZUKO_HOOK(open);
01691 DAZUKO_HOOK(dup);
01692 #endif
01693 #if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
01694 DAZUKO_HOOK(dup2);
01695 #endif
01696
01697 #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
01698 DAZUKO_HOOK(close);
01699 #endif
01700
01701 #ifdef ON_EXEC_SUPPORT
01702 DAZUKO_HOOK(execve);
01703 #endif
01704
01705 #ifdef ON_UNLINK_SUPPORT
01706 DAZUKO_HOOK(unlink);
01707 #endif
01708
01709 #ifdef ON_RMDIR_SUPPORT
01710 DAZUKO_HOOK(rmdir);
01711 #endif
01712
01713 #ifdef __SMP__
01714 unlock_kernel();
01715 #endif
01716
01717
01718
01719
01720 return 0;
01721 }
01722
01723 #define DAZUKO_UNHOOK(syscall_func) do \
01724 { \
01725 if (sys_call_table[__NR_##syscall_func] != linux_dazuko_sys_##syscall_func) \
01726 xp_print("dazuko: " #syscall_func " system call has been changed (system may be left in an unstable state!)\n"); \
01727 sys_call_table[__NR_##syscall_func] = original_sys_##syscall_func; \
01728 DPRINT(("dazuko: unhooked sys_" #syscall_func "\n")); \
01729 } \
01730 while (0)
01731
01732 inline int xp_sys_unhook()
01733 {
01734
01735
01736 int error;
01737
01738
01739 #ifdef __SMP__
01740 lock_kernel();
01741 #endif
01742
01743 fsync_dev(0);
01744
01745 #if defined(ON_OPEN_SUPPORT)
01746 DAZUKO_UNHOOK(open);
01747 DAZUKO_UNHOOK(dup);
01748 #endif
01749 #if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
01750 DAZUKO_UNHOOK(dup2);
01751 #endif
01752
01753 #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
01754 DAZUKO_UNHOOK(close);
01755 #endif
01756
01757 #ifdef ON_EXEC_SUPPORT
01758 DAZUKO_UNHOOK(execve);
01759 #endif
01760
01761 #ifdef ON_UNLINK_SUPPORT
01762 DAZUKO_UNHOOK(unlink);
01763 #endif
01764
01765 #ifdef ON_RMDIR_SUPPORT
01766 DAZUKO_UNHOOK(rmdir);
01767 #endif
01768
01769 #ifdef __SMP__
01770 unlock_kernel();
01771 #endif
01772
01773
01774 #ifdef DEVFS_SUPPORT
01775 error = devfs_unregister_chrdev(dev_major, DEVICE_NAME);
01776 devfs_unregister(devfs_find_handle(NULL, DEVICE_NAME, dev_major, 0, DEVFS_SPECIAL_CHR, 0));
01777 #else
01778 error = unregister_chrdev(dev_major, DEVICE_NAME);
01779 #endif
01780 if (error < 0)
01781 {
01782 xp_print("dazuko: error unregistering chrdev, err=%d\n", error);
01783 }
01784
01785 return 0;
01786 }
01787
01788
01789
01790
01791 int xp_print(const char *fmt, ...)
01792 {
01793 va_list args;
01794 char *p;
01795 size_t size = 1024;
01796
01797 p = (char *)xp_malloc(size);
01798 if (!p)
01799 return -1;
01800
01801 va_start(args, fmt);
01802 dazuko_vsnprintf(p, size-1, fmt, args);
01803 va_end(args);
01804
01805 p[size-1] = 0;
01806
01807 printk(p);
01808
01809 xp_free(p);
01810
01811 return 0;
01812 }
01813
01814
01815
01816
01817 int linux_dazuko_device_open(struct inode *inode, struct file *file)
01818 {
01819 DPRINT(("dazuko: linux_dazuko_device_open() [%d]\n", current->pid));
01820
01821 return 0;
01822 }
01823
01824 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
01825 int linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos)
01826 #else
01827 ssize_t linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos)
01828 #endif
01829 {
01830
01831
01832
01833
01834 char tmp[20];
01835 size_t dev_major_len;
01836
01837 DPRINT(("dazuko: linux_dazuko_device_read() [%d]\n", current->pid));
01838
01839
01840 if (*pos != 0)
01841 return 0;
01842
01843 if (dev_major < 0)
01844 return -ENODEV;
01845
01846
01847
01848 dazuko_bzero(tmp, sizeof(tmp));
01849
01850 dev_major_len = dazuko_snprintf(tmp, sizeof(tmp), "%d", dev_major) + 1;
01851
01852 if (tmp[sizeof(tmp)-1] != 0)
01853 {
01854 xp_print("dazuko: failing device_read, device number overflow for dameon %d (dev_major=%d)\n", current->pid, dev_major);
01855 return -EFAULT;
01856 }
01857
01858 if (length < dev_major_len)
01859 return -EINVAL;
01860
01861
01862 if (xp_copyout(tmp, buffer, dev_major_len) != 0)
01863 return -EFAULT;
01864
01865 *pos = dev_major_len;
01866
01867 return dev_major_len;
01868 }
01869
01870 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
01871 int linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos)
01872 {
01873
01874
01875
01876 return length;
01877 }
01878 #else
01879 ssize_t linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos)
01880 {
01881 struct xp_daemon_id xp_id;
01882 char tmpbuffer[32];
01883 int size;
01884
01885 size = length;
01886 if (length >= sizeof(tmpbuffer))
01887 size = sizeof(tmpbuffer) -1;
01888
01889
01890 if (xp_copyin(buffer, tmpbuffer, size) != 0)
01891 return -EFAULT;
01892
01893 tmpbuffer[size] = 0;
01894
01895 xp_id.pid = current->pid;
01896 xp_id.file = file;
01897 xp_id.current_p = current;
01898 xp_id.files = current->files;
01899
01900 if (dazuko_handle_user_request(tmpbuffer, &xp_id) == 0)
01901 return length;
01902 else
01903 return -EINTR;
01904 }
01905 #endif
01906
01907 int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param)
01908 {
01909
01910
01911
01912
01913 struct xp_daemon_id xp_id;
01914 int error = 0;
01915
01916 if (param == 0)
01917 {
01918 xp_print("dazuko: error: linux_dazuko_device_ioctl(..., 0)\n");
01919 return -EFAULT;
01920 }
01921
01922 xp_id.pid = current->pid;
01923 xp_id.file = file;
01924 xp_id.current_p = current;
01925 xp_id.files = current->files;
01926
01927 error = dazuko_handle_user_request_compat1((void *)param, _IOC_NR(cmd), &xp_id);
01928
01929 if (error != 0)
01930 {
01931
01932
01933 return -EPERM;
01934 }
01935
01936 return error;
01937 }
01938
01939 int linux_dazuko_device_release(struct inode *inode, struct file *file)
01940 {
01941 struct xp_daemon_id xp_id;
01942
01943 DPRINT(("dazuko: dazuko_device_release() [%d]\n", current->pid));
01944
01945 xp_id.pid = current->pid;
01946 xp_id.file = file;
01947 xp_id.current_p = current;
01948 xp_id.files = current->files;
01949
01950 return dazuko_unregister_daemon(&xp_id);
01951 }
01952
01953
01954
01955
01956 int __init linux_dazuko_init(void)
01957 {
01958 return dazuko_init();
01959 }
01960
01961 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
01962 void __exit linux_dazuko_exit(void)
01963 #else
01964 void linux_dazuko_exit(void)
01965 #endif
01966 {
01967 dazuko_exit();
01968 }
01969
01970
01971 #ifdef MODULE
01972
01973 MODULE_AUTHOR("H+BEDV Datentechnik GmbH <linux_support@antivir.de>");
01974 MODULE_DESCRIPTION("allow 3rd-party file access control");
01975 #ifdef MODULE_LICENSE
01976 MODULE_LICENSE("GPL");
01977 #else
01978 static const char __module_license[] __attribute__((section(".modinfo"))) = "license=GPL";
01979 #endif
01980
01981 int init_module(void)
01982 {
01983 return linux_dazuko_init();
01984 }
01985
01986 void cleanup_module(void)
01987 {
01988 linux_dazuko_exit();
01989 }
01990
01991 EXPORT_NO_SYMBOLS;
01992
01993 #else
01994
01995 module_init(linux_dazuko_init);
01996 module_exit(linux_dazuko_exit);
01997
01998
01999
02000 #endif