/daten/src/linux-2.4.27-rsbac-v1.2.3/rsbac/adf/daz/dazuko_rsbac.c

Go to the documentation of this file.
00001 /* Dazuko RSBAC. Allow RSBAC Linux file access control for 3rd-party applications. 00002 Copyright (c) 2004 H+BEDV Datentechnik GmbH 00003 Written by John Ogness <jogness@antivir.de> 00004 00005 This program is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU General Public License 00007 as published by the Free Software Foundation; either version 2 00008 of the License, or (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include "dazuko_rsbac.h" 00021 #include "dazuko_xp.h" 00022 #include "dazukoio.h" 00023 00024 #include <linux/init.h> 00025 #include <linux/unistd.h> 00026 #include <linux/fs.h> 00027 #include <linux/slab.h> 00028 #include <asm/uaccess.h> 00029 #include <linux/random.h> 00030 00031 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00032 #include <linux/vermagic.h> 00033 #endif 00034 00035 #include <rsbac/types.h> 00036 #include <rsbac/reg.h> 00037 #include <rsbac/adf.h> 00038 #include <rsbac/aci.h> 00039 #include <rsbac/getname.h> 00040 #include <rsbac/error.h> 00041 #include <rsbac/proc_fs.h> 00042 #include <rsbac/debug.h> 00043 00044 00045 #if defined(DEVFS_SUPPORT) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00046 #include <linux/devfs_fs_kernel.h> 00047 #endif 00048 00049 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) 00050 int linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos); 00051 int linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos); 00052 #else 00053 ssize_t linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos); 00054 ssize_t linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos); 00055 #endif 00056 int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param); 00057 int linux_dazuko_device_open(struct inode *inode, struct file *file); 00058 int linux_dazuko_device_release(struct inode *inode, struct file *file); 00059 00060 extern struct xp_atomic active; 00061 00062 static int dev_major = -1; 00063 static rsbac_reg_handle_t handle = -1; 00064 00065 static struct file_operations fops = { 00066 read: linux_dazuko_device_read, /* read */ 00067 write: linux_dazuko_device_write, /* write */ 00068 ioctl: linux_dazuko_device_ioctl, /* ioctl */ 00069 open: linux_dazuko_device_open, /* open */ 00070 release: linux_dazuko_device_release, /* release */ 00071 }; 00072 00073 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) 00074 00075 /* The following code is taken directly from Linux in the file: 00076 include/linux/sched.h */ 00077 00078 #ifndef __wait_event_interruptible 00079 #define __wait_event_interruptible(wq, condition, ret) \ 00080 do { \ 00081 struct wait_queue __wait; \ 00082 \ 00083 __wait.task = current; \ 00084 add_wait_queue(&wq, &__wait); \ 00085 for (;;) { \ 00086 current->state = TASK_INTERRUPTIBLE; \ 00087 mb(); \ 00088 if (condition) \ 00089 break; \ 00090 if (!signal_pending(current)) { \ 00091 schedule(); \ 00092 continue; \ 00093 } \ 00094 ret = -ERESTARTSYS; \ 00095 break; \ 00096 } \ 00097 current->state = TASK_RUNNING; \ 00098 remove_wait_queue(&wq, &__wait); \ 00099 } while (0) 00100 #endif 00101 00102 #ifndef wait_event_interruptible 00103 #define wait_event_interruptible(wq, condition) \ 00104 ({ \ 00105 int __ret = 0; \ 00106 if (!(condition)) \ 00107 __wait_event_interruptible(wq, condition, __ret);\ 00108 __ret; \ 00109 }) 00110 #define wait_event(wq, condition) \ 00111 ({ \ 00112 int __ret = 0; \ 00113 if (!(condition)) \ 00114 __wait_event_interruptible(wq, condition, __ret);\ 00115 __ret; \ 00116 }) 00117 #endif 00118 00119 #endif 00120 00121 00122 /* mutex */ 00123 00124 inline int xp_init_mutex(struct xp_mutex *mutex) 00125 { 00126 #ifdef init_MUTEX 00127 init_MUTEX(&(mutex->mutex)); 00128 #else 00129 sema_init(&(mutex->mutex), 1); 00130 #endif 00131 00132 return 0; 00133 } 00134 00135 inline int xp_down(struct xp_mutex *mutex) 00136 { 00137 down(&(mutex->mutex)); 00138 return 0; 00139 } 00140 00141 inline int xp_up(struct xp_mutex *mutex) 00142 { 00143 up(&(mutex->mutex)); 00144 return 0; 00145 } 00146 00147 inline int xp_destroy_mutex(struct xp_mutex *mutex) 00148 { 00149 return 0; 00150 } 00151 00152 00153 /* read-write lock */ 00154 00155 inline int xp_init_rwlock(struct xp_rwlock *rwlock) 00156 { 00157 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) 00158 rwlock_init(&(rwlock->rwlock)); 00159 #else 00160 rwlock->rwlock = RW_LOCK_UNLOCKED; 00161 #endif 00162 return 0; 00163 } 00164 00165 inline int xp_write_lock(struct xp_rwlock *rwlock) 00166 { 00167 write_lock(&(rwlock->rwlock)); 00168 return 0; 00169 } 00170 00171 inline int xp_write_unlock(struct xp_rwlock *rwlock) 00172 { 00173 write_unlock(&(rwlock->rwlock)); 00174 return 0; 00175 } 00176 00177 inline int xp_read_lock(struct xp_rwlock *rlock) 00178 { 00179 read_lock(&(rlock->rwlock)); 00180 return 0; 00181 } 00182 00183 inline int xp_read_unlock(struct xp_rwlock *rlock) 00184 { 00185 read_unlock(&(rlock->rwlock)); 00186 return 0; 00187 } 00188 00189 inline int xp_destroy_rwlock(struct xp_rwlock *rwlock) 00190 { 00191 return 0; 00192 } 00193 00194 00195 /* wait-notify queue */ 00196 00197 inline int xp_init_queue(struct xp_queue *queue) 00198 { 00199 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) 00200 init_waitqueue_head(&(queue->queue)); 00201 #else 00202 queue = NULL; 00203 #endif 00204 00205 return 0; 00206 } 00207 00208 inline int xp_wait_until_condition(struct xp_queue *queue, int (*cfunction)(void *), void *cparam, int allow_interrupt) 00209 { 00210 /* wait until cfunction(cparam) != 0 (condition is true) */ 00211 00212 if (allow_interrupt) 00213 { 00214 return wait_event_interruptible(queue->queue, cfunction(cparam) != 0); 00215 } 00216 else 00217 { 00218 wait_event(queue->queue, cfunction(cparam) != 0); 00219 } 00220 00221 return 0; 00222 } 00223 00224 inline int xp_notify(struct xp_queue *queue) 00225 { 00226 wake_up(&(queue->queue)); 00227 return 0; 00228 } 00229 00230 inline int xp_destroy_queue(struct xp_queue *queue) 00231 { 00232 return 0; 00233 } 00234 00235 00236 /* memory */ 00237 00238 inline void* xp_malloc(size_t size) 00239 { 00240 return kmalloc(size, GFP_KERNEL); 00241 } 00242 00243 inline int xp_free(void *ptr) 00244 { 00245 kfree(ptr); 00246 return 0; 00247 } 00248 00249 inline int xp_copyin(const void *user_src, void *kernel_dest, size_t size) 00250 { 00251 return copy_from_user(kernel_dest, user_src, size); 00252 } 00253 00254 inline int xp_copyout(const void *kernel_src, void *user_dest, size_t size) 00255 { 00256 return copy_to_user(user_dest, kernel_src, size); 00257 } 00258 00259 inline int xp_verify_user_writable(const void *user_ptr, size_t size) 00260 { 00261 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) 00262 return verify_area(VERIFY_WRITE, user_ptr, size); 00263 #else 00264 return 0; 00265 #endif 00266 } 00267 00268 inline int xp_verify_user_readable(const void *user_ptr, size_t size) 00269 { 00270 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) 00271 return verify_area(VERIFY_READ, user_ptr, size); 00272 #else 00273 return 0; 00274 #endif 00275 } 00276 00277 00278 /* path attribute */ 00279 00280 inline int xp_is_absolute_path(const char *path) 00281 { 00282 return (path[0] == '/'); 00283 } 00284 00285 00286 /* atomic */ 00287 00288 inline int xp_atomic_set(struct xp_atomic *atomic, int value) 00289 { 00290 atomic_set(&(atomic->atomic), value); 00291 return 0; 00292 } 00293 00294 inline int xp_atomic_inc(struct xp_atomic *atomic) 00295 { 00296 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00297 #ifdef MODULE 00298 if (atomic == &active) 00299 MOD_INC_USE_COUNT; 00300 #endif 00301 #endif 00302 00303 atomic_inc(&(atomic->atomic)); 00304 return 0; 00305 } 00306 00307 inline int xp_atomic_dec(struct xp_atomic *atomic) 00308 { 00309 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00310 #ifdef MODULE 00311 if (atomic == &active) 00312 MOD_DEC_USE_COUNT; 00313 #endif 00314 #endif 00315 00316 atomic_dec(&(atomic->atomic)); 00317 return 0; 00318 } 00319 00320 inline int xp_atomic_read(struct xp_atomic *atomic) 00321 { 00322 return atomic_read(&(atomic->atomic)); 00323 } 00324 00325 00326 /* file descriptor */ 00327 00328 inline int xp_copy_file(struct xp_file *dest, struct xp_file *src) 00329 { 00330 return 0; 00331 } 00332 00333 inline int xp_compare_file(struct xp_file *file1, struct xp_file *file2) 00334 { 00335 return 0; 00336 } 00337 00338 inline int xp_file_struct_check(struct dazuko_file_struct *dfs) 00339 { 00340 int length; 00341 00342 /* make sure we have access to everything */ 00343 00344 if (dfs == NULL) 00345 return -1; 00346 00347 if (dfs->extra_data == NULL) 00348 return -1; 00349 00350 if (dfs->extra_data->dentry == NULL) 00351 return -1; 00352 00353 if (dfs->extra_data->dentry->d_inode == NULL) 00354 return -1; 00355 00356 /* ok, we have everything we need */ 00357 00358 length = rsbac_get_full_path_length(dfs->extra_data->dentry); 00359 if (length < 1) 00360 return -1; 00361 00362 dfs->extra_data->full_filename = xp_malloc(length + 1); 00363 if (dfs->extra_data->full_filename == NULL) 00364 return -1; 00365 00366 /* the full_filename will need to be deleted later */ 00367 dfs->extra_data->free_full_filename = 1; 00368 00369 if (rsbac_get_full_path(dfs->extra_data->dentry, dfs->extra_data->full_filename, length + 1) < 1) 00370 return -1; 00371 00372 /* find the actual value of the length */ 00373 dfs->extra_data->full_filename_length = dazuko_get_filename_length(dfs->extra_data->full_filename); 00374 00375 /* reference copy of full path */ 00376 dfs->filename = dfs->extra_data->full_filename; 00377 00378 dfs->filename_length = dfs->extra_data->full_filename_length; 00379 00380 dfs->file_p.size = dfs->extra_data->dentry->d_inode->i_size; 00381 dfs->file_p.set_size = 1; 00382 dfs->file_p.uid = dfs->extra_data->dentry->d_inode->i_uid; 00383 dfs->file_p.set_uid = 1; 00384 dfs->file_p.gid = dfs->extra_data->dentry->d_inode->i_gid; 00385 dfs->file_p.set_gid = 1; 00386 dfs->file_p.mode = dfs->extra_data->dentry->d_inode->i_mode; 00387 dfs->file_p.set_mode = 1; 00388 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00389 dfs->file_p.device_type = dfs->extra_data->dentry->d_inode->i_dev; 00390 #else 00391 dfs->file_p.device_type = dfs->extra_data->dentry->d_inode->i_rdev; 00392 #endif 00393 dfs->file_p.set_device_type = 1; 00394 00395 return 0; 00396 } 00397 00398 int xp_file_struct_check_cleanup(struct dazuko_file_struct *dfs) 00399 { 00400 return 0; 00401 } 00402 00403 static int dazuko_file_struct_cleanup(struct dazuko_file_struct **dfs) 00404 { 00405 if (dfs == NULL) 00406 return 0; 00407 00408 if (*dfs == NULL) 00409 return 0; 00410 00411 xp_file_struct_check_cleanup(*dfs); 00412 00413 if ((*dfs)->extra_data != NULL) 00414 { 00415 if ((*dfs)->extra_data->free_full_filename) 00416 xp_free((*dfs)->extra_data->full_filename); 00417 00418 xp_free((*dfs)->extra_data); 00419 } 00420 00421 xp_free(*dfs); 00422 00423 *dfs = NULL; 00424 00425 return 0; 00426 } 00427 00428 00429 /* daemon id */ 00430 00431 int xp_id_compare(struct xp_daemon_id *id1, struct xp_daemon_id *id2) 00432 { 00433 if (id1 == NULL || id2 == NULL) 00434 return -1; 00435 00436 /* if file's are available and they match, 00437 * then we say that the id's match */ 00438 if (id1->file != NULL && id1->file == id2->file) 00439 return 0; 00440 00441 if (id1->pid == id2->pid) 00442 return 0; 00443 00444 return 1; 00445 } 00446 00447 int xp_id_free(struct xp_daemon_id *id) 00448 { 00449 xp_free(id); 00450 00451 return 0; 00452 } 00453 00454 struct xp_daemon_id* xp_id_copy(struct xp_daemon_id *id) 00455 { 00456 struct xp_daemon_id *ptr; 00457 00458 if (id == NULL) 00459 return NULL; 00460 00461 ptr = (struct xp_daemon_id *)xp_malloc(sizeof(struct xp_daemon_id)); 00462 00463 if (ptr != NULL) 00464 { 00465 ptr->pid = id->pid; 00466 ptr->file = id->file; 00467 } 00468 00469 return ptr; 00470 } 00471 00472 00473 /* system calls */ 00474 00475 static inline int dazuko_rsbac_process(enum rsbac_adf_request_t request, /* open, close, exec, etc */ 00476 enum rsbac_target_t target, /* file, dir, etc */ 00477 union rsbac_target_id_t tid, /* dentry (for files) */ 00478 int is_pre) 00479 { 00480 struct dazuko_file_struct *dfs = NULL; 00481 struct xp_daemon_id xp_id; 00482 int error = 0; 00483 int check_error = 0; 00484 struct event_properties event_p; 00485 int event; 00486 int daemon_allowed; 00487 00488 switch (request) 00489 { 00490 case R_DELETE: 00491 if (target == T_FILE) 00492 { 00493 event = DAZUKO_ON_UNLINK; 00494 daemon_allowed = 1; 00495 } 00496 else if (target == T_DIR) 00497 { 00498 event = DAZUKO_ON_RMDIR; 00499 daemon_allowed = 1; 00500 } 00501 else 00502 { 00503 goto dazuko_rsbac_process_quickout; 00504 } 00505 break; 00506 00507 case R_CLOSE: 00508 if (target == T_FILE) 00509 { 00510 event = DAZUKO_ON_CLOSE; 00511 daemon_allowed = 1; 00512 } 00513 else 00514 { 00515 goto dazuko_rsbac_process_quickout; 00516 } 00517 break; 00518 00519 case R_EXECUTE: 00520 if (target == T_FILE) 00521 { 00522 event = DAZUKO_ON_EXEC; 00523 daemon_allowed = 0; 00524 } 00525 else 00526 { 00527 goto dazuko_rsbac_process_quickout; 00528 } 00529 break; 00530 00531 case R_APPEND_OPEN: 00532 case R_READ_WRITE_OPEN: 00533 case R_READ_OPEN: 00534 case R_WRITE_OPEN: 00535 if (target == T_FILE) 00536 { 00537 event = DAZUKO_ON_OPEN; 00538 daemon_allowed = 1; 00539 } 00540 else 00541 { 00542 goto dazuko_rsbac_process_quickout; 00543 } 00544 break; 00545 00546 default: 00547 goto dazuko_rsbac_process_quickout; 00548 } 00549 00550 xp_id.pid = current->pid; 00551 xp_id.file = NULL; 00552 00553 check_error = dazuko_sys_check(event, daemon_allowed, &xp_id); 00554 00555 if (!check_error) 00556 { 00557 dazuko_bzero(&event_p, sizeof(event_p)); 00558 /* 00559 event_p.flags = flags; 00560 event_p.set_flags = 1; 00561 event_p.mode = mode; 00562 event_p.set_mode = 1; 00563 */ 00564 event_p.pid = current->pid; 00565 event_p.set_pid = 1; 00566 event_p.uid = current->uid; 00567 event_p.set_uid = 1; 00568 00569 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct)); 00570 if (dfs != NULL) 00571 { 00572 dazuko_bzero(dfs, sizeof(struct dazuko_file_struct)); 00573 00574 dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct)); 00575 if (dfs->extra_data != NULL) 00576 { 00577 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct)); 00578 00579 dfs->extra_data->dentry = tid.file.dentry_p; 00580 00581 if (is_pre) 00582 error = dazuko_sys_pre(event, dfs, &event_p); 00583 else 00584 dazuko_sys_post(event, dfs, NULL, &event_p); 00585 } 00586 else 00587 { 00588 xp_free(dfs); 00589 dfs = NULL; 00590 } 00591 00592 dazuko_file_struct_cleanup(&dfs); 00593 } 00594 } 00595 00596 if (!is_pre) 00597 return 0; 00598 00599 if (error) 00600 return NOT_GRANTED; 00601 00602 return GRANTED; 00603 00604 dazuko_rsbac_process_quickout: 00605 if (is_pre) 00606 return DO_NOT_CARE; 00607 00608 return 0; 00609 } 00610 00611 static inline int dazuko_rsbac_pre(enum rsbac_adf_request_t request, /* open, close, exec, etc */ 00612 rsbac_pid_t owner_pid, /* some PID */ 00613 enum rsbac_target_t target, /* file, dir, etc */ 00614 union rsbac_target_id_t tid, /* dentry (for files) */ 00615 enum rsbac_attribute_t attr, /* keine ahnung */ 00616 union rsbac_attribute_value_t attr_val, /* tons of rsbac attribs */ 00617 rsbac_uid_t owner) /* some UID */ 00618 { 00619 return dazuko_rsbac_process(request, target, tid, 1); 00620 } 00621 00622 00623 static int dazuko_rsbac_post(enum rsbac_adf_request_t request, 00624 rsbac_pid_t owner_pid, 00625 enum rsbac_target_t target, 00626 union rsbac_target_id_t tid, 00627 enum rsbac_target_t new_target, 00628 union rsbac_target_id_t new_tid, 00629 enum rsbac_attribute_t attr, 00630 union rsbac_attribute_value_t attr_val, 00631 rsbac_uid_t owner) 00632 { 00633 return dazuko_rsbac_process(request, target, tid, 0); 00634 } 00635 00636 00637 /* system hook */ 00638 00639 inline int xp_sys_hook() 00640 { 00641 #define RSBAC_REG_REGISTER_RETRIES 1024 00642 /* Called insmod when inserting the module. */ 00643 00644 int retries; 00645 00646 /* register with rsbac */ 00647 00648 struct rsbac_reg_entry_t entry; 00649 00650 /* clearing registration entries */ 00651 memset(&entry, 0, sizeof(entry)); 00652 00653 strcpy(entry.name, "Dazuko"); 00654 entry.request_func = dazuko_rsbac_pre; 00655 entry.set_attr_func = dazuko_rsbac_post; 00656 entry.switch_on = TRUE; 00657 00658 for (retries=0 ; retries<RSBAC_REG_REGISTER_RETRIES ; retries++) 00659 { 00660 /* get a random handle */ 00661 get_random_bytes(&handle, sizeof(handle)); 00662 00663 /* the handle needs to be positive */ 00664 if (handle < 0) 00665 handle *= -1; 00666 00667 entry.handle = handle; 00668 00669 handle = rsbac_reg_register(RSBAC_REG_VERSION, entry); 00670 00671 if (handle != -RSBAC_EEXISTS) 00672 { 00673 /* there wasn't a problem with the handle value */ 00674 break; 00675 } 00676 } 00677 00678 if (handle < 0) 00679 { 00680 xp_print("dazuko: failed to register with RSBAC\n"); 00681 return -ENOEXEC; 00682 } 00683 00684 /* register the dazuko device */ 00685 #ifdef DEVFS_SUPPORT 00686 dev_major = devfs_register_chrdev(0, DEVICE_NAME, &fops); 00687 devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, 00688 dev_major, 0, S_IFCHR | S_IRUSR | S_IWUSR, 00689 &fops, NULL); 00690 #else 00691 dev_major = register_chrdev(0, DEVICE_NAME, &fops); 00692 #endif 00693 if (dev_major < 0) 00694 { 00695 xp_print("dazuko: unable to register device chrdev, err=%d\n", dev_major); 00696 return dev_major; 00697 } 00698 00699 /* initialization complete */ 00700 00701 return 0; 00702 } 00703 00704 inline int xp_sys_unhook() 00705 { 00706 /* Called by rmmod when removing the module. */ 00707 00708 int error; 00709 00710 #ifdef DEVFS_SUPPORT 00711 error = devfs_unregister_chrdev(dev_major, DEVICE_NAME); 00712 devfs_unregister(devfs_find_handle(NULL, DEVICE_NAME, dev_major, 0, DEVFS_SPECIAL_CHR, 0)); 00713 #else 00714 error = unregister_chrdev(dev_major, DEVICE_NAME); 00715 #endif 00716 if (error < 0) 00717 { 00718 xp_print("dazuko: error unregistering chrdev, err=%d\n", error); 00719 } 00720 00721 if (rsbac_reg_unregister(handle) != 0) 00722 { 00723 xp_print("dazuko: failed to unregister with RSBAC (system may be left in an unstable state!)\n"); 00724 } 00725 00726 return 0; 00727 } 00728 00729 00730 /* output */ 00731 00732 int xp_print(const char *fmt, ...) 00733 { 00734 va_list args; 00735 char *p; 00736 size_t size = 1024; 00737 00738 p = (char *)xp_malloc(size); 00739 if (!p) 00740 return -1; 00741 00742 va_start(args, fmt); 00743 dazuko_vsnprintf(p, size-1, fmt, args); 00744 va_end(args); 00745 00746 p[size-1] = 0; 00747 00748 printk(p); 00749 rsbac_printk(p); 00750 00751 xp_free(p); 00752 00753 return 0; 00754 } 00755 00756 00757 /* ioctl's */ 00758 00759 int linux_dazuko_device_open(struct inode *inode, struct file *file) 00760 { 00761 DPRINT(("dazuko: linux_dazuko_device_open() [%d]\n", current->pid)); 00762 00763 return 0; 00764 } 00765 00766 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) 00767 int linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos) 00768 #else 00769 ssize_t linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos) 00770 #endif 00771 { 00772 /* Reading from the dazuko device simply 00773 * returns the device number. This is to 00774 * help out the daemon. */ 00775 00776 char tmp[20]; 00777 size_t dev_major_len; 00778 00779 DPRINT(("dazuko: linux_dazuko_device_read() [%d]\n", current->pid)); 00780 00781 /* non-root daemons are ignored */ 00782 if (current->uid != 0) 00783 return 0; 00784 00785 /* only one read is allowed */ 00786 if (*pos != 0) 00787 return 0; 00788 00789 if (dev_major < 0) 00790 return -ENODEV; 00791 00792 /* print dev_major to a string 00793 * and get length (with terminator) */ 00794 dazuko_bzero(tmp, sizeof(tmp)); 00795 00796 dev_major_len = dazuko_snprintf(tmp, sizeof(tmp), "%d", dev_major) + 1; 00797 00798 if (tmp[sizeof(tmp)-1] != 0) 00799 { 00800 xp_print("dazuko: failing device_read, device number overflow for dameon %d (dev_major=%d)\n", current->pid, dev_major); 00801 return -EFAULT; 00802 } 00803 00804 if (length < dev_major_len) 00805 return -EINVAL; 00806 00807 /* copy dev_major string to userspace */ 00808 if (xp_copyout(tmp, buffer, dev_major_len) != 0) 00809 return -EFAULT; 00810 00811 *pos = dev_major_len; 00812 00813 return dev_major_len; 00814 } 00815 00816 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) 00817 int linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos) 00818 #else 00819 ssize_t linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos) 00820 #endif 00821 { 00822 struct dazuko_request *u_request; 00823 struct xp_daemon_id xp_id; 00824 char tmpbuffer[32]; 00825 char *value; 00826 int size; 00827 00828 /* non-root daemons are ignored */ 00829 if (current->uid != 0) 00830 return length; 00831 00832 size = length; 00833 if (length >= sizeof(tmpbuffer)) 00834 size = sizeof(tmpbuffer) -1; 00835 00836 /* copy request pointer string to kernelspace */ 00837 if (xp_copyin(buffer, tmpbuffer, size) != 0) 00838 return -EFAULT; 00839 00840 tmpbuffer[size] = 0; 00841 00842 if (dazuko_get_value("\nRA=", buffer, &value) != 0) 00843 { 00844 xp_print("dazuko: error: linux_dazuko_device_write.RA missing\n"); 00845 return -EFAULT; 00846 } 00847 00848 u_request = (struct dazuko_request *)simple_strtoul(value, NULL, 10); 00849 00850 xp_free(value); 00851 00852 xp_id.pid = current->pid; 00853 xp_id.file = file; 00854 00855 if (dazuko_handle_user_request(u_request, &xp_id) == 0) 00856 return length; 00857 else 00858 return -EINTR; 00859 } 00860 00861 int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param) 00862 { 00863 /* A daemon uses this function to interact with 00864 * the kernel. A daemon can set scanning parameters, 00865 * give scanning response, and get filenames to scan. */ 00866 00867 struct xp_daemon_id xp_id; 00868 int error = 0; 00869 00870 /* non-root daemons are ignored */ 00871 if (current->uid != 0) 00872 return 0; 00873 00874 if (param == 0) 00875 { 00876 xp_print("dazuko: error: linux_dazuko_device_ioctl(..., 0)\n"); 00877 return -EFAULT; 00878 } 00879 00880 xp_id.pid = current->pid; 00881 xp_id.file = file; 00882 00883 error = dazuko_handle_user_request_compat12((void *)param, _IOC_NR(cmd), &xp_id); 00884 00885 if (error != 0) 00886 { 00887 /* general error occurred */ 00888 00889 return -EPERM; 00890 } 00891 00892 return error; 00893 } 00894 00895 int linux_dazuko_device_release(struct inode *inode, struct file *file) 00896 { 00897 struct xp_daemon_id xp_id; 00898 00899 DPRINT(("dazuko: dazuko_device_release() [%d]\n", current->pid)); 00900 00901 /* non-root daemons are ignored */ 00902 if (current->uid != 0) 00903 return 0; 00904 00905 xp_id.pid = current->pid; 00906 xp_id.file = file; 00907 00908 return dazuko_unregister_daemon(&xp_id); 00909 } 00910 00911 00912 /* init/exit */ 00913 00914 int __init linux_dazuko_init(void) 00915 { 00916 return dazuko_init(); 00917 } 00918 00919 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) 00920 void __exit linux_dazuko_exit(void) 00921 #else 00922 void linux_dazuko_exit(void) 00923 #endif 00924 { 00925 dazuko_exit(); 00926 } 00927 00928 00929 #ifdef MODULE 00930 00931 int init_module(void) 00932 { 00933 return linux_dazuko_init(); 00934 } 00935 00936 void cleanup_module(void) 00937 { 00938 linux_dazuko_exit(); 00939 } 00940 00941 MODULE_AUTHOR("H+BEDV Datentechnik GmbH <linux_support@antivir.de>"); 00942 MODULE_DESCRIPTION("allow 3rd-party file access control"); 00943 #ifdef MODULE_LICENSE 00944 MODULE_LICENSE("GPL"); 00945 #else 00946 static const char __module_license[] __attribute__((section(".modinfo"))) = "license=GPL"; 00947 #endif 00948 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00949 MODULE_INFO(vermagic, VERMAGIC_STRING); 00950 #endif 00951 00952 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00953 EXPORT_NO_SYMBOLS; 00954 #endif 00955 00956 #else 00957 00958 module_init(linux_dazuko_init); 00959 module_exit(linux_dazuko_exit); 00960 /* module_init(int linux_dazuko_init(void)); */ 00961 /* module_exit(void linux_dazuko_exit(void)); */ 00962 00963 #endif 00964

Generated on Tue Aug 31 10:05:23 2004 for RSBAC by doxygen 1.3.8