00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "dazuko_linux26.h"
00021 #include "dazuko_core.h"
00022 #include "dazuko_linux26_device_def.h"
00023
00024 #include <linux/config.h>
00025 #include <linux/module.h>
00026 #include <linux/kernel.h>
00027 #include <linux/init.h>
00028 #include <linux/vermagic.h>
00029 #include <linux/security.h>
00030 #include <linux/namei.h>
00031 #include <linux/dcache.h>
00032 #include <linux/mount.h>
00033 #include <linux/devfs_fs_kernel.h>
00034 #include <linux/device.h>
00035 #if !defined(USE_TRYTOFREEZEVOID) && !defined(USE_SUSPEND2)
00036 #include <linux/suspend.h>
00037 #endif
00038 #include <asm/uaccess.h>
00039
00040
00041 #ifndef DAZUKO_DM
00042 #define DAZUKO_DM 0
00043 #endif
00044
00045
00046 #define CHROOT_EVENT_STRING "chroot:"
00047 #define CHROOT_EVENT_LENGTH 7
00048
00049
00050 #ifndef WITH_LOCAL_DPATH
00051 extern char * __d_path(struct dentry *, struct vfsmount *, struct dentry *, struct vfsmount *, char *, int);
00052 #endif
00053
00054 ssize_t linux_dazuko_device_read(struct file *, char __user *, size_t, loff_t *);
00055 ssize_t linux_dazuko_device_write(struct file *, const char __user *, size_t, loff_t *);
00056 int linux_dazuko_device_open(struct inode *, struct file *);
00057 int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param);
00058 int linux_dazuko_device_release(struct inode *, struct file *);
00059
00060 #ifdef USE_CLASS
00061 static struct class *dazuko_class = NULL;
00062 #else
00063 static struct class_simple *dazuko_class = NULL;
00064 #endif
00065
00066 static struct vfsmount *orig_rootmnt = NULL;
00067 static struct dentry *orig_root = NULL;
00068 static int dev_major = -1;
00069
00070 #ifndef DAZUKO_FIST
00071 #ifdef NO_STACKING_SUPPORT
00072 struct security_operations dazuko_security_ops;
00073 #else
00074 extern struct security_operations dazuko_security_ops;
00075 extern struct security_operations dazuko_register_security_ops;
00076 static struct security_operations dazuko_security_default_ops;
00077 #endif
00078
00079 static int secondary_register = 0;
00080
00081 static inline int dazuko_sys_generic(struct inode *inode, int mask, struct nameidata *nd);
00082
00083 #ifndef NO_STACKING_SUPPORT
00084 int dazuko_register_security(const char *name, struct security_operations *ops);
00085 int dazuko_unregister_security(const char *name, struct security_operations *ops);
00086 #endif
00087 #endif
00088
00089 #ifdef NO_CAPABILITIES
00090 int lsm_capability_compare(struct security_operations *ops1, struct security_operations *ops2);
00091 #endif
00092
00093 static struct file_operations fops = {
00094 .owner = THIS_MODULE,
00095 .read = linux_dazuko_device_read,
00096 .write = linux_dazuko_device_write,
00097 .ioctl = linux_dazuko_device_ioctl,
00098 .open = linux_dazuko_device_open,
00099 .release = linux_dazuko_device_release,
00100 };
00101
00102
00103
00104
00105 inline void xp_init_mutex(struct xp_mutex *mutex)
00106 {
00107 init_MUTEX(&(mutex->mutex));
00108 }
00109
00110 inline void xp_down(struct xp_mutex *mutex)
00111 {
00112 down(&(mutex->mutex));
00113 }
00114
00115 inline void xp_up(struct xp_mutex *mutex)
00116 {
00117 up(&(mutex->mutex));
00118 }
00119
00120 inline void xp_destroy_mutex(struct xp_mutex *mutex)
00121 {
00122 }
00123
00124
00125
00126
00127 inline void xp_init_rwlock(struct xp_rwlock *rwlock)
00128 {
00129 rwlock_init(&(rwlock->rwlock));
00130 }
00131
00132 inline void xp_write_lock(struct xp_rwlock *rwlock)
00133 {
00134 write_lock(&(rwlock->rwlock));
00135 }
00136
00137 inline void xp_write_unlock(struct xp_rwlock *rwlock)
00138 {
00139 write_unlock(&(rwlock->rwlock));
00140 }
00141
00142 inline void xp_read_lock(struct xp_rwlock *rlock)
00143 {
00144 read_lock(&(rlock->rwlock));
00145 }
00146
00147 inline void xp_read_unlock(struct xp_rwlock *rlock)
00148 {
00149 read_unlock(&(rlock->rwlock));
00150 }
00151
00152 inline void xp_destroy_rwlock(struct xp_rwlock *rwlock)
00153 {
00154 }
00155
00156
00157
00158
00159 inline int xp_init_queue(struct xp_queue *queue)
00160 {
00161 init_waitqueue_head(&(queue->queue));
00162 return 0;
00163 }
00164
00165 inline int xp_wait_until_condition(struct xp_queue *queue, int (*cfunction)(void *), void *cparam, int allow_interrupt)
00166 {
00167
00168 int ret = 0;
00169
00170 if (allow_interrupt)
00171 {
00172 while (1)
00173 {
00174 ret = wait_event_interruptible(queue->queue, cfunction(cparam) != 0);
00175
00176 #ifdef USE_SUSPEND2
00177 if (try_todo_list() == 0)
00178 break;
00179 #elif defined (USE_TRYTOFREEZEVOID)
00180 if (try_to_freeze() == 0)
00181 break;
00182 #else
00183 if (current->flags & PF_FREEZE)
00184 {
00185 refrigerator(PF_FREEZE);
00186 }
00187 else
00188 {
00189 break;
00190 }
00191 #endif
00192 }
00193 }
00194 else
00195 {
00196 wait_event(queue->queue, cfunction(cparam) != 0);
00197 }
00198
00199 return ret;
00200 }
00201
00202 inline int xp_notify(struct xp_queue *queue)
00203 {
00204 wake_up(&(queue->queue));
00205 return 0;
00206 }
00207
00208 inline int xp_destroy_queue(struct xp_queue *queue)
00209 {
00210 return 0;
00211 }
00212
00213
00214
00215
00216 inline void* xp_malloc(size_t size)
00217 {
00218 return kmalloc(size, GFP_ATOMIC);
00219 }
00220
00221 inline int xp_free(void *ptr)
00222 {
00223 kfree(ptr);
00224 return 0;
00225 }
00226
00227 inline int xp_copyin(const void *user_src, void *kernel_dest, size_t size)
00228 {
00229 return copy_from_user(kernel_dest, user_src, size);
00230 }
00231
00232 inline int xp_copyout(const void *kernel_src, void *user_dest, size_t size)
00233 {
00234 return copy_to_user(user_dest, kernel_src, size);
00235 }
00236
00237 inline int xp_verify_user_writable(const void *user_ptr, size_t size)
00238 {
00239 return 0;
00240 }
00241
00242 inline int xp_verify_user_readable(const void *user_ptr, size_t size)
00243 {
00244 return 0;
00245 }
00246
00247
00248
00249
00250 inline int xp_is_absolute_path(const char *path)
00251 {
00252 if (path[0] == '/')
00253 return 1;
00254
00255 #ifdef USE_CHROOT
00256 if (dazuko_get_filename_length(path) >= CHROOT_EVENT_LENGTH)
00257 {
00258 if (memcmp(CHROOT_EVENT_STRING, path, CHROOT_EVENT_LENGTH) == 0)
00259 return 1;
00260 }
00261 #endif
00262
00263 return 0;
00264 }
00265
00266
00267
00268
00269 inline int xp_atomic_set(struct xp_atomic *atomic, int value)
00270 {
00271 atomic_set(&(atomic->atomic), value);
00272 return 0;
00273 }
00274
00275 inline int xp_atomic_inc(struct xp_atomic *atomic)
00276 {
00277 atomic_inc(&(atomic->atomic));
00278 return 0;
00279 }
00280
00281 inline int xp_atomic_dec(struct xp_atomic *atomic)
00282 {
00283 atomic_dec(&(atomic->atomic));
00284 return 0;
00285 }
00286
00287 inline int xp_atomic_read(struct xp_atomic *atomic)
00288 {
00289 return atomic_read(&(atomic->atomic));
00290 }
00291
00292
00293
00294
00295 #ifdef WITH_LOCAL_DPATH
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
00317 struct dentry *root, struct vfsmount *rootmnt,
00318 char *buffer, int buflen)
00319 {
00320 char * end = buffer+buflen;
00321 char * retval;
00322 int namelen;
00323
00324 *--end = '\0';
00325 buflen--;
00326 if (!IS_ROOT(dentry) && d_unhashed(dentry)) {
00327 buflen -= 10;
00328 end -= 10;
00329 if (buflen < 0)
00330 goto Elong;
00331 memcpy(end, " (deleted)", 10);
00332 }
00333
00334 if (buflen < 1)
00335 goto Elong;
00336
00337 retval = end-1;
00338 *retval = '/';
00339
00340 for (;;) {
00341 struct dentry * parent;
00342
00343 if (dentry == root && vfsmnt == rootmnt)
00344 break;
00345 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
00346
00347 if (vfsmnt->mnt_parent == vfsmnt)
00348 goto global_root;
00349 dentry = vfsmnt->mnt_mountpoint;
00350 vfsmnt = vfsmnt->mnt_parent;
00351 continue;
00352 }
00353 parent = dentry->d_parent;
00354 prefetch(parent);
00355 namelen = dentry->d_name.len;
00356 buflen -= namelen + 1;
00357 if (buflen < 0)
00358 goto Elong;
00359 end -= namelen;
00360 memcpy(end, dentry->d_name.name, namelen);
00361 *--end = '/';
00362 retval = end;
00363 dentry = parent;
00364 }
00365
00366 return retval;
00367
00368 global_root:
00369 namelen = dentry->d_name.len;
00370 buflen -= namelen;
00371 if (buflen < 0)
00372 goto Elong;
00373 retval -= namelen-1;
00374 memcpy(retval, dentry->d_name.name, namelen);
00375 return retval;
00376 Elong:
00377 return ERR_PTR(-ENAMETOOLONG);
00378 }
00379 #endif
00380
00381 static int dazuko_get_full_filename(struct xp_file_struct *xfs)
00382 {
00383 struct vfsmount *rootmnt;
00384 struct dentry *root;
00385 char *temp;
00386 #ifdef USE_CHROOT
00387 int chrooted = 0;
00388 #endif
00389
00390 if (xfs == NULL)
00391 return 0;
00392
00393 if (xfs->inode == NULL)
00394 return 0;
00395
00396 #ifndef DAZUKO_FIST
00397 if (S_ISDIR(xfs->inode->i_mode))
00398 return 0;
00399 #endif
00400
00401 if (xfs->nd == NULL || xfs->free_full_filename)
00402 return 0;
00403
00404 if (xfs->nd->mnt == NULL || xfs->nd->dentry == NULL)
00405 return 0;
00406
00407
00408 if (!xfs->free_page_buffer)
00409 {
00410
00411 xfs->buffer = (char *)__get_free_page(GFP_USER);
00412
00413
00414 if (xfs->buffer == NULL)
00415 return 0;
00416
00417
00418 xfs->free_page_buffer = 1;
00419 }
00420
00421
00422 if (!xfs->mntput_vfsmount)
00423 {
00424 xfs->vfsmount = mntget(xfs->nd->mnt);
00425
00426
00427 xfs->mntput_vfsmount = 1;
00428 }
00429
00430
00431 if (!xfs->dput_dentry)
00432 {
00433 xfs->dentry = dget(xfs->nd->dentry);
00434
00435
00436 xfs->dput_dentry = 1;
00437 }
00438
00439 rootmnt = mntget(orig_rootmnt);
00440 root = dget(orig_root);
00441
00442 #ifdef USE_CHROOT
00443 temp = d_path(xfs->dentry, xfs->vfsmount, xfs->buffer, PAGE_SIZE);
00444
00445 if (orig_root != current->fs->root)
00446 chrooted = 1;
00447 #else
00448 spin_lock(&dcache_lock);
00449 temp = __d_path(xfs->dentry, xfs->vfsmount, root, rootmnt, xfs->buffer, PAGE_SIZE);
00450 spin_unlock(&dcache_lock);
00451 #endif
00452
00453 dput(root);
00454 mntput(rootmnt);
00455
00456
00457 if (temp == NULL)
00458 return 0;
00459
00460 xfs->full_filename_length = dazuko_get_filename_length(temp);
00461
00462 #ifdef USE_CHROOT
00463 if (chrooted)
00464 xfs->full_filename_length += CHROOT_EVENT_LENGTH;
00465 #endif
00466 xfs->full_filename = (char *)xp_malloc(xfs->full_filename_length + 1);
00467 if (xfs->full_filename == NULL)
00468 return 0;
00469
00470
00471 xfs->free_full_filename = 1;
00472
00473 #ifdef USE_CHROOT
00474 if (chrooted)
00475 {
00476 memcpy(xfs->full_filename, CHROOT_EVENT_STRING, CHROOT_EVENT_LENGTH + 1);
00477 memcpy(xfs->full_filename + CHROOT_EVENT_LENGTH, temp, xfs->full_filename_length - CHROOT_EVENT_LENGTH + 1);
00478 }
00479 else
00480 #endif
00481 memcpy(xfs->full_filename, temp, xfs->full_filename_length + 1);
00482
00483
00484
00485 return 1;
00486 }
00487
00488 static int dazuko_fill_file_struct_cleanup(struct dazuko_file_struct *dfs)
00489 {
00490 if (dfs == NULL)
00491 return 0;
00492
00493 if (dfs->extra_data == NULL)
00494 return 0;
00495
00496 if (dfs->extra_data->free_page_buffer)
00497 {
00498 free_page((unsigned long)dfs->extra_data->buffer);
00499 dfs->extra_data->free_page_buffer = 0;
00500 }
00501
00502 if (dfs->extra_data->dput_dentry)
00503 {
00504 dput(dfs->extra_data->dentry);
00505 dfs->extra_data->dput_dentry = 0;
00506 }
00507
00508 if (dfs->extra_data->mntput_vfsmount)
00509 {
00510 mntput(dfs->extra_data->vfsmount);
00511 dfs->extra_data->mntput_vfsmount = 0;
00512 }
00513
00514 return 0;
00515 }
00516
00517 int xp_fill_file_struct(struct dazuko_file_struct *dfs)
00518 {
00519 int error = -1;
00520
00521 if (dfs == NULL)
00522 return error;
00523
00524
00525 if (dfs->filename != NULL)
00526 return 0;
00527
00528
00529 if (dazuko_get_full_filename(dfs->extra_data))
00530 {
00531
00532 dfs->filename = dfs->extra_data->full_filename;
00533
00534 dfs->filename_length = dfs->extra_data->full_filename_length;
00535
00536 dfs->file_p.size = dfs->extra_data->inode->i_size;
00537 dfs->file_p.set_size = 1;
00538 dfs->file_p.uid = dfs->extra_data->inode->i_uid;
00539 dfs->file_p.set_uid = 1;
00540 dfs->file_p.gid = dfs->extra_data->inode->i_gid;
00541 dfs->file_p.set_gid = 1;
00542 dfs->file_p.mode = dfs->extra_data->inode->i_mode;
00543 dfs->file_p.set_mode = 1;
00544 dfs->file_p.device_type = dfs->extra_data->inode->i_rdev;
00545 dfs->file_p.set_device_type = 1;
00546
00547 error = 0;
00548 }
00549
00550 dazuko_fill_file_struct_cleanup(dfs);
00551
00552 return error;
00553 }
00554
00555 static int dazuko_file_struct_cleanup(struct dazuko_file_struct **dfs)
00556 {
00557 if (dfs == NULL)
00558 return 0;
00559
00560 if (*dfs == NULL)
00561 return 0;
00562
00563 if ((*dfs)->extra_data)
00564 {
00565 if ((*dfs)->extra_data->free_full_filename)
00566 xp_free((*dfs)->extra_data->full_filename);
00567
00568 xp_free((*dfs)->extra_data);
00569 }
00570
00571 xp_free(*dfs);
00572
00573 *dfs = NULL;
00574
00575 return 0;
00576 }
00577
00578
00579
00580
00581 static inline int check_parent(struct task_struct *parent, struct task_struct *child)
00582 {
00583 struct task_struct *ts = child;
00584
00585 if (parent == NULL || child == NULL)
00586 return -1;
00587
00588 while (1)
00589 {
00590 if (ts == parent)
00591 return 0;
00592
00593 if (ts->parent == NULL)
00594 break;
00595
00596 if (ts == ts->parent)
00597 break;
00598
00599 ts = ts->parent;
00600 }
00601
00602 return -1;
00603 }
00604
00605 inline int xp_id_compare(struct xp_daemon_id *id1, struct xp_daemon_id *id2, int check_related)
00606 {
00607 if (id1 == NULL || id2 == NULL)
00608 return DAZUKO_DIFFERENT;
00609
00610
00611
00612
00613
00614
00615 if (id1->file != NULL && id1->file == id2->file)
00616 return DAZUKO_SAME;
00617
00618 if (id1->pid == id2->pid && id1->current_p == id2->current_p && id1->files == id2->files)
00619 return DAZUKO_SAME;
00620
00621 if (check_related)
00622 {
00623 if (check_parent(id1->current_p, id2->current_p) == 0)
00624 {
00625 return DAZUKO_CHILD;
00626 }
00627 else if (id1->pid == id2->pid || id1->current_p == id2->current_p || id1->files == id2->files)
00628 {
00629 return DAZUKO_SUSPICIOUS;
00630 }
00631 }
00632
00633 return DAZUKO_DIFFERENT;
00634 }
00635
00636 inline int xp_id_free(struct xp_daemon_id *id)
00637 {
00638 xp_free(id);
00639
00640 return 0;
00641 }
00642
00643 inline struct xp_daemon_id* xp_id_copy(struct xp_daemon_id *id)
00644 {
00645 struct xp_daemon_id *ptr;
00646
00647 if (id == NULL)
00648 return NULL;
00649
00650 ptr = (struct xp_daemon_id *)xp_malloc(sizeof(struct xp_daemon_id));
00651
00652 if (ptr != NULL)
00653 {
00654 ptr->pid = id->pid;
00655 ptr->file = id->file;
00656 ptr->current_p = id->current_p;
00657 ptr->files = id->files;
00658 }
00659
00660 return ptr;
00661 }
00662
00663
00664
00665
00666 int xp_set_event_properties(struct event_properties *event_p, struct xp_daemon_id *xp_id)
00667 {
00668 event_p->pid = xp_id->pid;
00669 event_p->set_pid = 1;
00670
00671 return 0;
00672 }
00673
00674
00675
00676
00677 int xp_init_cache(unsigned long ttl)
00678 {
00679 return -1;
00680 }
00681
00682
00683
00684
00685 #ifndef DAZUKO_FIST
00686 #ifndef NO_STACKING_SUPPORT
00687 int dazuko_register_security(const char *name, struct security_operations *ops)
00688 {
00689 char *daz_p;
00690 char *ext_p;
00691 char *def_p;
00692 char *end_p;
00693 void **ext_func_p;
00694 void **def_func_p;
00695 void **daz_func_p;
00696 void *ext_func;
00697 void *def_func;
00698 void *daz_func;
00699 int error = 0;
00700
00701 if (name == NULL || ops == NULL)
00702 return XP_ERROR_PERMISSION;
00703
00704
00705
00706
00707 if (sizeof(struct security_operations) % sizeof(void *) != 0)
00708 return XP_ERROR_FAULT;
00709
00710
00711
00712
00713
00714
00715
00716 #ifdef NO_CAPABILITIES
00717
00718
00719
00720
00721 if (lsm_capability_compare(ops, &dazuko_security_default_ops) != 0)
00722 return XP_ERROR_PERMISSION;
00723 #endif
00724
00725 ext_p = (char *)ops;
00726 def_p = (char *)&dazuko_security_default_ops;
00727 daz_p = (char *)&dazuko_security_ops;
00728 end_p = daz_p + sizeof(dazuko_security_ops);
00729
00730 while (daz_p < end_p)
00731 {
00732 daz_func_p = (void **)daz_p;
00733 ext_func_p = (void **)ext_p;
00734 def_func_p = (void **)def_p;
00735
00736 daz_func = *daz_func_p;
00737 ext_func = *ext_func_p;
00738 def_func = *def_func_p;
00739
00740 if (ext_func != def_func && daz_func != NULL)
00741 {
00742 error = 1;
00743 break;
00744 }
00745
00746 daz_p += sizeof(void *);
00747 ext_p += sizeof(void *);
00748 def_p += sizeof(void *);
00749 }
00750
00751 if (error)
00752 {
00753
00754
00755 return XP_ERROR_PERMISSION;
00756 }
00757
00758
00759
00760 ext_p = (char *)ops;
00761 def_p = (char *)&dazuko_security_default_ops;
00762 daz_p = (char *)&dazuko_security_ops;
00763 end_p = daz_p + sizeof(dazuko_security_ops);
00764
00765 while (daz_p < end_p)
00766 {
00767 daz_func_p = (void **)daz_p;
00768 ext_func_p = (void **)ext_p;
00769 def_func_p = (void **)def_p;
00770
00771 daz_func = *daz_func_p;
00772 ext_func = *ext_func_p;
00773 def_func = *def_func_p;
00774
00775 if (ext_func != def_func && daz_func == NULL)
00776 {
00777 *daz_func_p = ext_func;
00778 }
00779
00780 daz_p += sizeof(void *);
00781 ext_p += sizeof(void *);
00782 def_p += sizeof(void *);
00783 }
00784
00785 return 0;
00786 }
00787
00788 int dazuko_unregister_security(const char *name, struct security_operations *ops)
00789 {
00790 char *daz_p;
00791 char *ext_p;
00792 char *def_p;
00793 char *end_p;
00794 void **ext_func_p;
00795 void **def_func_p;
00796 void **daz_func_p;
00797 void *ext_func;
00798 void *def_func;
00799 void *daz_func;
00800
00801 if (name == NULL || ops == NULL)
00802 return XP_ERROR_PERMISSION;
00803
00804
00805
00806
00807 if (sizeof(struct security_operations) % sizeof(void *) != 0)
00808 return XP_ERROR_FAULT;
00809
00810
00811
00812 ext_p = (char *)ops;
00813 def_p = (char *)&dazuko_security_default_ops;
00814 daz_p = (char *)&dazuko_security_ops;
00815 end_p = daz_p + sizeof(dazuko_security_ops);
00816
00817 while (daz_p < end_p)
00818 {
00819 daz_func_p = (void **)daz_p;
00820 ext_func_p = (void **)ext_p;
00821 def_func_p = (void **)def_p;
00822
00823 daz_func = *daz_func_p;
00824 ext_func = *ext_func_p;
00825 def_func = *def_func_p;
00826
00827 if (ext_func != def_func && daz_func == ext_func)
00828 {
00829 *daz_func_p = NULL;
00830 }
00831
00832 daz_p += sizeof(void *);
00833 ext_p += sizeof(void *);
00834 def_p += sizeof(void *);
00835 }
00836
00837 return 0;
00838 }
00839 #endif
00840 #endif
00841
00842
00843 #ifdef DAZUKO_FIST
00844 int dazuko_sys_generic(int event, struct inode *inode, struct nameidata *nd, int daemon_is_allowed)
00845 #else
00846 static inline int dazuko_sys_generic(struct inode *inode, int mask, struct nameidata *nd)
00847 #endif
00848 {
00849 struct dazuko_file_struct *dfs = NULL;
00850 int error = 0;
00851 int check_error = 0;
00852 struct event_properties event_p;
00853 struct xp_daemon_id xp_id;
00854 struct slot_list *sl = NULL;
00855 #ifndef DAZUKO_FIST
00856 int event = DAZUKO_ON_OPEN;
00857 int daemon_is_allowed = 1;
00858 #endif
00859
00860 dazuko_bzero(&event_p, sizeof(event_p));
00861
00862 #ifdef DAZUKO_FIST
00863 if (inode == NULL || nd == NULL)
00864 return XP_ERROR_PERMISSION;
00865 #else
00866 if ((mask & MAY_EXEC) != 0)
00867 {
00868 event = DAZUKO_ON_EXEC;
00869 daemon_is_allowed = 0;
00870 }
00871 else
00872 {
00873
00874 if (mask == 0 || (mask & (MAY_WRITE|MAY_APPEND)) != 0)
00875 {
00876 if ((mask & MAY_READ) != 0)
00877 {
00878 event_p.flags = O_RDWR;
00879 }
00880 else
00881 {
00882 event_p.flags = O_WRONLY;
00883 }
00884
00885 event_p.set_flags = 1;
00886 }
00887 else if ((mask & MAY_READ) != 0)
00888 {
00889 event_p.flags = O_RDONLY;
00890 event_p.set_flags = 1;
00891 }
00892 }
00893 #endif
00894
00895 xp_id.pid = current->pid;
00896 xp_id.file = NULL;
00897 xp_id.current_p = current;
00898 xp_id.files = current->files;
00899
00900 check_error = dazuko_check_access(event, daemon_is_allowed, &xp_id, &sl);
00901
00902 if (!check_error)
00903 {
00904 event_p.mode = inode->i_mode;
00905 event_p.set_mode = 1;
00906 event_p.pid = current->pid;
00907 event_p.set_pid = 1;
00908 event_p.uid = current->uid;
00909 event_p.set_uid = 1;
00910
00911 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
00912 if (dfs != NULL)
00913 {
00914 dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
00915
00916 dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
00917 if (dfs->extra_data != NULL)
00918 {
00919 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
00920
00921 dfs->extra_data->nd = nd;
00922 dfs->extra_data->inode = inode;
00923
00924 error = dazuko_process_access(event, dfs, &event_p, sl);
00925 }
00926 else
00927 {
00928 xp_free(dfs);
00929 dfs = NULL;
00930 }
00931
00932 dazuko_file_struct_cleanup(&dfs);
00933 }
00934 }
00935
00936 if (error)
00937 return XP_ERROR_PERMISSION;
00938
00939 return 0;
00940 }
00941
00942 inline int xp_sys_hook()
00943 {
00944 #ifndef DAZUKO_FIST
00945 #ifndef NO_STACKING_SUPPORT
00946 struct security_operations dummy_ops;
00947 int got_dummy = 0;
00948 #endif
00949
00950
00951
00952 if (current == NULL)
00953 {
00954 xp_print("dazuko: panic (current == NULL)\n");
00955 return -1;
00956 }
00957 if (current->fs == NULL)
00958 {
00959 xp_print("dazuko: panic (current->fs == NULL)\n");
00960 return -1;
00961 }
00962 if (current->fs->root == NULL)
00963 {
00964 xp_print("dazuko: panic (current->fs->root == NULL)\n");
00965 return -1;
00966 }
00967 if (current->fs->rootmnt == NULL)
00968 {
00969 xp_print("dazuko: panic (current->fs->rootmnt == NULL)\n");
00970 return -1;
00971 }
00972
00973
00974 #ifdef USE_CHROOT
00975 xp_print("dazuko: info: using chroot events for chroot'd processes\n");
00976 #endif
00977 #if defined(CONFIG_SMP) && defined(WITH_LOCAL_DPATH)
00978 xp_print("dazuko: warning: using local __dpath() dangerous for SMP kernels\n");
00979 #endif
00980 #endif
00981
00982
00983
00984
00985
00986 read_lock(¤t->fs->lock);
00987 orig_rootmnt = current->fs->rootmnt;
00988 orig_root = current->fs->root;
00989 read_unlock(¤t->fs->lock);
00990
00991 #ifndef DAZUKO_FIST
00992 #ifdef NO_STACKING_SUPPORT
00993 memset(&dazuko_security_ops, 0, sizeof(dazuko_security_ops));
00994 dazuko_security_ops.inode_permission = dazuko_sys_generic;
00995
00996 if (register_security(&dazuko_security_ops) != 0)
00997 {
00998 if (mod_reg_security(DEVICE_NAME, &dazuko_security_ops) != 0)
00999 {
01000 xp_print("dazuko: failed to register\n");
01001 return XP_ERROR_INVALID;
01002 }
01003
01004 secondary_register = 1;
01005 xp_print("dazuko: warning: registered as secondary module\n");
01006 }
01007 #else
01008
01009
01010 memset(&dazuko_security_default_ops, 0, sizeof(dazuko_security_default_ops));
01011
01012 memset(&dummy_ops, 0, sizeof(dummy_ops));
01013 if (register_security(&dummy_ops) == 0)
01014 {
01015 memcpy(&dazuko_security_default_ops, &dummy_ops, sizeof(dazuko_security_default_ops));
01016 unregister_security(&dummy_ops);
01017
01018 got_dummy = 1;
01019 }
01020
01021
01022
01023 memset(&dazuko_security_ops, 0, sizeof(dazuko_security_ops));
01024 dazuko_security_ops.inode_permission = dazuko_sys_generic;
01025
01026 if (!got_dummy || register_security(&dazuko_register_security_ops) != 0)
01027 {
01028
01029 if (mod_reg_security(DEVICE_NAME, &dazuko_security_ops) != 0)
01030 {
01031 xp_print("dazuko: failed to register\n");
01032 return XP_ERROR_INVALID;
01033 }
01034
01035 secondary_register = 1;
01036 xp_print("dazuko: warning: registered as secondary module\n");
01037 }
01038 #endif
01039 #endif
01040
01041 dev_major = register_chrdev(DAZUKO_DM, DEVICE_NAME, &fops);
01042 if (dev_major < 0)
01043 {
01044 xp_print("dazuko: unable to register device, err=%d\n", dev_major);
01045 return dev_major;
01046 }
01047
01048 devfs_mk_cdev(MKDEV(dev_major, 0), S_IFCHR | S_IRUSR | S_IWUSR, DEVICE_NAME);
01049
01050 #ifdef USE_CLASS
01051 dazuko_class = class_create(THIS_MODULE, "dazuko");
01052 #ifdef CLASS_class_device_create_2_6_15
01053 class_device_create(dazuko_class, NULL, MKDEV(dev_major, 0), NULL, "dazuko");
01054 #else
01055 class_device_create(dazuko_class, MKDEV(dev_major, 0), NULL, "dazuko");
01056 #endif
01057 #else
01058 dazuko_class = class_simple_create(THIS_MODULE, "dazuko");
01059 class_simple_device_add(dazuko_class, MKDEV(dev_major, 0), NULL, "dazuko");
01060 #endif
01061
01062 return 0;
01063 }
01064
01065 inline int xp_sys_unhook()
01066 {
01067 unregister_chrdev(dev_major, DEVICE_NAME);
01068
01069 devfs_remove(DEVICE_NAME);
01070
01071 #ifdef USE_CLASS
01072 class_device_destroy(dazuko_class, MKDEV(dev_major, 0));
01073 class_destroy(dazuko_class);
01074 #else
01075 class_simple_device_remove(MKDEV(dev_major, 0));
01076 class_simple_destroy(dazuko_class);
01077 #endif
01078
01079 #ifndef DAZUKO_FIST
01080 #ifdef NO_STACKING_SUPPORT
01081 if (secondary_register)
01082 mod_unreg_security(DEVICE_NAME, &dazuko_security_ops);
01083 else
01084 unregister_security(&dazuko_security_ops);
01085 #else
01086 if (secondary_register)
01087 mod_unreg_security(DEVICE_NAME, &dazuko_security_ops);
01088 else
01089 unregister_security(&dazuko_register_security_ops);
01090 #endif
01091 #endif
01092
01093 return 0;
01094 }
01095
01096
01097
01098
01099 int xp_print(const char *fmt, ...)
01100 {
01101 va_list args;
01102 char *p;
01103 size_t size = 1024;
01104 int length;
01105
01106 p = (char *)xp_malloc(size);
01107 if (p == NULL)
01108 return -1;
01109
01110 length = dazuko_get_filename_length(KERN_INFO);
01111
01112 memcpy(p, KERN_INFO, length);
01113
01114 va_start(args, fmt);
01115 vsnprintf(p + length, size - length, fmt, args);
01116 va_end(args);
01117
01118 p[size-1] = 0;
01119
01120 printk(p);
01121
01122 xp_free(p);
01123
01124 return 0;
01125 }
01126
01127
01128
01129
01130 int linux_dazuko_device_open(struct inode *inode, struct file *file)
01131 {
01132 DPRINT(("dazuko: linux_dazuko_device_open() [%d]\n", current->pid));
01133
01134 return 0;
01135 }
01136
01137 ssize_t linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos)
01138 {
01139
01140
01141
01142
01143 char tmp[20];
01144 size_t dev_major_len;
01145
01146 DPRINT(("dazuko: linux_dazuko_device_read() [%d]\n", current->pid));
01147
01148 if (*pos != 0)
01149 return 0;
01150
01151 if (dev_major < 0)
01152 return XP_ERROR_NODEVICE;
01153
01154
01155
01156 dazuko_bzero(tmp, sizeof(tmp));
01157
01158 dev_major_len = dazuko_snprintf(tmp, sizeof(tmp), "%d", dev_major) + 1;
01159
01160 if (tmp[sizeof(tmp)-1] != 0)
01161 {
01162 xp_print("dazuko: failing device_read, device number overflow for dameon %d (dev_major=%d)\n", current->pid, dev_major);
01163 return XP_ERROR_FAULT;
01164 }
01165
01166 if (length < dev_major_len)
01167 return XP_ERROR_INVALID;
01168
01169
01170 if (xp_copyout(tmp, buffer, dev_major_len) != 0)
01171 return XP_ERROR_FAULT;
01172
01173 *pos += dev_major_len;
01174
01175 return dev_major_len;
01176 }
01177
01178 ssize_t linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos)
01179 {
01180 struct xp_daemon_id xp_id;
01181 char tmpbuffer[32];
01182 int size;
01183
01184 size = length;
01185 if (length >= sizeof(tmpbuffer))
01186 size = sizeof(tmpbuffer) -1;
01187
01188
01189 if (xp_copyin(buffer, tmpbuffer, size) != 0)
01190 return XP_ERROR_FAULT;
01191
01192 tmpbuffer[size] = 0;
01193
01194 xp_id.pid = current->pid;
01195 xp_id.file = file;
01196 xp_id.current_p = current;
01197 xp_id.files = current->files;
01198
01199 if (dazuko_handle_user_request(tmpbuffer, &xp_id) == 0)
01200 return size;
01201
01202 return XP_ERROR_INTERRUPT;
01203 }
01204
01205 int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param)
01206 {
01207
01208
01209
01210
01211 struct xp_daemon_id xp_id;
01212 int error = 0;
01213
01214 if (param == 0)
01215 {
01216 xp_print("dazuko: error: linux_dazuko_device_ioctl(..., 0)\n");
01217 return XP_ERROR_INVALID;
01218 }
01219
01220 xp_id.pid = current->pid;
01221 xp_id.file = file;
01222 xp_id.current_p = current;
01223 xp_id.files = current->files;
01224
01225 error = dazuko_handle_user_request_compat1((void *)param, _IOC_NR(cmd), &xp_id);
01226
01227 if (error != 0)
01228 {
01229
01230
01231 return XP_ERROR_PERMISSION;
01232 }
01233
01234 return error;
01235 }
01236
01237 int linux_dazuko_device_release(struct inode *inode, struct file *file)
01238 {
01239 struct xp_daemon_id xp_id;
01240
01241 DPRINT(("dazuko: dazuko_device_release() [%d]\n", current->pid));
01242
01243 xp_id.pid = current->pid;
01244 xp_id.file = file;
01245 xp_id.current_p = current;
01246 xp_id.files = current->files;
01247
01248 return dazuko_unregister_daemon(&xp_id);
01249 }
01250
01251
01252
01253
01254 static int __init linux_dazuko_init(void)
01255 {
01256 return dazuko_init();
01257 }
01258
01259 static void __exit linux_dazuko_exit(void)
01260 {
01261 dazuko_exit();
01262 }
01263
01264
01265 MODULE_AUTHOR("H+BEDV Datentechnik GmbH <linux_support@antivir.de>");
01266 MODULE_DESCRIPTION("allow 3rd-party file access control");
01267 MODULE_LICENSE("GPL");
01268 MODULE_INFO(vermagic, VERMAGIC_STRING);
01269
01270 #ifdef DAZUKO_FIST
01271 EXPORT_SYMBOL(dazuko_sys_generic);
01272 #endif
01273
01274 security_initcall(linux_dazuko_init);
01275 module_exit(linux_dazuko_exit);