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

Go to the documentation of this file.
00001 /*************************************************** */ 00002 /* Rule Set Based Access Control */ 00003 /* Implementation of the Access Control Decision */ 00004 /* Facility (ADF) - Dazuko Malware Scan */ 00005 /* File: rsbac/adf/daz/daz_main.c */ 00006 /* */ 00007 /* Author and (c) 1999-2004: Amon Ott <ao@rsbac.org> */ 00008 /* Copyright (c) 2004 H+BEDV Datentechnik GmbH */ 00009 /* Written by John Ogness <jogness@antivir.de> */ 00010 /* */ 00011 /* Last modified: 04/May/2004 */ 00012 /*************************************************** */ 00013 00014 /* Dazuko RSBAC. Allow RSBAC Linux file access control for 3rd-party applications. 00015 00016 This program is free software; you can redistribute it and/or 00017 modify it under the terms of the GNU General Public License 00018 as published by the Free Software Foundation; either version 2 00019 of the License, or (at your option) any later version. 00020 00021 This program is distributed in the hope that it will be useful, 00022 but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00024 GNU General Public License for more details. 00025 00026 You should have received a copy of the GNU General Public License 00027 along with this program; if not, write to the Free Software 00028 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00029 */ 00030 00031 #include "dazuko_rsbac.h" 00032 #include "dazuko_xp.h" 00033 #include "dazukoio.h" 00034 00035 #include <linux/init.h> 00036 #include <linux/unistd.h> 00037 #include <linux/fs.h> 00038 #include <linux/slab.h> 00039 #include <linux/random.h> 00040 00041 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00042 #include <linux/vermagic.h> 00043 #endif 00044 00045 #include <linux/string.h> 00046 #include <linux/module.h> 00047 #include <linux/types.h> 00048 #include <linux/version.h> 00049 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00050 #include <linux/syscalls.h> 00051 #endif 00052 #include <asm/uaccess.h> 00053 #include <rsbac/types.h> 00054 #include <rsbac/aci.h> 00055 #include <rsbac/adf.h> 00056 #include <rsbac/adf_main.h> 00057 #include <rsbac/debug.h> 00058 #include <rsbac/error.h> 00059 #include <rsbac/helpers.h> 00060 #include <rsbac/getname.h> 00061 #include <rsbac/net_getname.h> 00062 #include <rsbac/rkmem.h> 00063 #include <rsbac/proc_fs.h> 00064 00065 /************************************************* */ 00066 /* Global Variables */ 00067 /************************************************* */ 00068 00069 #if defined(DEVFS_SUPPORT) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00070 #include <linux/devfs_fs_kernel.h> 00071 #endif 00072 00073 ssize_t linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos); 00074 ssize_t linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos); 00075 int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param); 00076 int linux_dazuko_device_open(struct inode *inode, struct file *file); 00077 int linux_dazuko_device_release(struct inode *inode, struct file *file); 00078 00079 extern struct xp_atomic active; 00080 00081 static int dev_major = -1; 00082 00083 static struct file_operations fops = { 00084 read: linux_dazuko_device_read, /* read */ 00085 write: linux_dazuko_device_write, /* write */ 00086 ioctl: linux_dazuko_device_ioctl, /* ioctl */ 00087 open: linux_dazuko_device_open, /* open */ 00088 release: linux_dazuko_device_release, /* release */ 00089 }; 00090 00091 /************************************************* */ 00092 /* Internal Help functions */ 00093 /************************************************* */ 00094 00095 #if defined(CONFIG_RSBAC_DAZ_CACHE) 00096 static int reset_scanned(struct rsbac_fs_file_t file) 00097 { 00098 union rsbac_attribute_value_t i_attr_val1; 00099 union rsbac_target_id_t i_tid; 00100 00101 /* reset scanned status for file */ 00102 i_tid.file=file; 00103 i_attr_val1.daz_scanned = DAZ_unscanned; 00104 if(rsbac_set_attr(DAZ, 00105 T_FILE, 00106 i_tid, 00107 A_daz_scanned, 00108 i_attr_val1)) 00109 { 00110 printk(KERN_WARNING "reset_scanned(): rsbac_set_attr() returned error!\n"); 00111 return(-RSBAC_EWRITEFAILED); 00112 } 00113 /* reset scanner flag for file */ 00114 i_attr_val1.daz_scanner = FALSE; 00115 if(rsbac_set_attr(DAZ, 00116 T_FILE, 00117 i_tid, 00118 A_daz_scanner, 00119 i_attr_val1)) 00120 { 00121 printk(KERN_WARNING "reset_scanned(): rsbac_set_attr() returned error!\n"); 00122 return(-RSBAC_EWRITEFAILED); 00123 } 00124 return(0); 00125 } 00126 #else 00127 static inline int reset_scanned(struct rsbac_fs_file_t file) 00128 { 00129 return 0; 00130 } 00131 #endif 00132 00133 00134 /* mutex */ 00135 00136 inline int xp_init_mutex(struct xp_mutex *mutex) 00137 { 00138 #ifdef init_MUTEX 00139 init_MUTEX(&(mutex->mutex)); 00140 #else 00141 sema_init(&(mutex->mutex), 1); 00142 #endif 00143 00144 return 0; 00145 } 00146 00147 inline int xp_down(struct xp_mutex *mutex) 00148 { 00149 down(&(mutex->mutex)); 00150 return 0; 00151 } 00152 00153 inline int xp_up(struct xp_mutex *mutex) 00154 { 00155 up(&(mutex->mutex)); 00156 return 0; 00157 } 00158 00159 inline int xp_destroy_mutex(struct xp_mutex *mutex) 00160 { 00161 return 0; 00162 } 00163 00164 00165 /* read-write lock */ 00166 00167 inline int xp_init_rwlock(struct xp_rwlock *rwlock) 00168 { 00169 rwlock_init(&(rwlock->rwlock)); 00170 return 0; 00171 } 00172 00173 inline int xp_write_lock(struct xp_rwlock *rwlock) 00174 { 00175 write_lock(&(rwlock->rwlock)); 00176 return 0; 00177 } 00178 00179 inline int xp_write_unlock(struct xp_rwlock *rwlock) 00180 { 00181 write_unlock(&(rwlock->rwlock)); 00182 return 0; 00183 } 00184 00185 inline int xp_read_lock(struct xp_rwlock *rlock) 00186 { 00187 read_lock(&(rlock->rwlock)); 00188 return 0; 00189 } 00190 00191 inline int xp_read_unlock(struct xp_rwlock *rlock) 00192 { 00193 read_unlock(&(rlock->rwlock)); 00194 return 0; 00195 } 00196 00197 inline int xp_destroy_rwlock(struct xp_rwlock *rwlock) 00198 { 00199 return 0; 00200 } 00201 00202 00203 /* wait-notify queue */ 00204 00205 inline int xp_init_queue(struct xp_queue *queue) 00206 { 00207 init_waitqueue_head(&(queue->queue)); 00208 return 0; 00209 } 00210 00211 inline int xp_wait_until_condition(struct xp_queue *queue, int (*cfunction)(void *), void *cparam, int allow_interrupt) 00212 { 00213 /* wait until cfunction(cparam) != 0 (condition is true) */ 00214 00215 if (allow_interrupt) 00216 { 00217 return wait_event_interruptible(queue->queue, cfunction(cparam) != 0); 00218 } 00219 else 00220 { 00221 wait_event(queue->queue, cfunction(cparam) != 0); 00222 } 00223 00224 return 0; 00225 } 00226 00227 inline int xp_notify(struct xp_queue *queue) 00228 { 00229 wake_up(&(queue->queue)); 00230 return 0; 00231 } 00232 00233 inline int xp_destroy_queue(struct xp_queue *queue) 00234 { 00235 return 0; 00236 } 00237 00238 00239 /* memory */ 00240 00241 inline void* xp_malloc(size_t size) 00242 { 00243 return kmalloc(size, GFP_KERNEL); 00244 } 00245 00246 inline int xp_free(void *ptr) 00247 { 00248 kfree(ptr); 00249 return 0; 00250 } 00251 00252 inline int xp_copyin(const void *user_src, void *kernel_dest, size_t size) 00253 { 00254 return copy_from_user(kernel_dest, user_src, size); 00255 } 00256 00257 inline int xp_copyout(const void *kernel_src, void *user_dest, size_t size) 00258 { 00259 return copy_to_user(user_dest, kernel_src, size); 00260 } 00261 00262 inline int xp_verify_user_writable(const void *user_ptr, size_t size) 00263 { 00264 return 0; 00265 } 00266 00267 inline int xp_verify_user_readable(const void *user_ptr, size_t size) 00268 { 00269 return 0; 00270 } 00271 00272 00273 /* path attribute */ 00274 00275 inline int xp_is_absolute_path(const char *path) 00276 { 00277 return (path[0] == '/'); 00278 } 00279 00280 00281 /* atomic */ 00282 00283 inline int xp_atomic_set(struct xp_atomic *atomic, int value) 00284 { 00285 atomic_set(&(atomic->atomic), value); 00286 return 0; 00287 } 00288 00289 inline int xp_atomic_inc(struct xp_atomic *atomic) 00290 { 00291 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00292 #ifdef MODULE 00293 if (atomic == &active) 00294 MOD_INC_USE_COUNT; 00295 #endif 00296 #endif 00297 00298 atomic_inc(&(atomic->atomic)); 00299 return 0; 00300 } 00301 00302 inline int xp_atomic_dec(struct xp_atomic *atomic) 00303 { 00304 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00305 #ifdef MODULE 00306 if (atomic == &active) 00307 MOD_DEC_USE_COUNT; 00308 #endif 00309 #endif 00310 00311 atomic_dec(&(atomic->atomic)); 00312 return 0; 00313 } 00314 00315 inline int xp_atomic_read(struct xp_atomic *atomic) 00316 { 00317 return atomic_read(&(atomic->atomic)); 00318 } 00319 00320 00321 /* file descriptor */ 00322 00323 inline int xp_copy_file(struct xp_file *dest, struct xp_file *src) 00324 { 00325 return 0; 00326 } 00327 00328 inline int xp_compare_file(struct xp_file *file1, struct xp_file *file2) 00329 { 00330 return 0; 00331 } 00332 00333 inline int xp_file_struct_check(struct dazuko_file_struct *dfs) 00334 { 00335 int length; 00336 00337 /* make sure we have access to everything */ 00338 00339 if (dfs == NULL) 00340 return -1; 00341 00342 if (dfs->extra_data == NULL) 00343 return -1; 00344 00345 if (dfs->extra_data->dentry == NULL) 00346 return -1; 00347 00348 if (dfs->extra_data->dentry->d_inode == NULL) 00349 return -1; 00350 00351 /* ok, we have everything we need */ 00352 00353 length = rsbac_get_full_path_length(dfs->extra_data->dentry); 00354 if (length < 1) 00355 return -1; 00356 00357 dfs->extra_data->full_filename = xp_malloc(length + 1); 00358 if (dfs->extra_data->full_filename == NULL) 00359 return -1; 00360 00361 /* the full_filename will need to be deleted later */ 00362 dfs->extra_data->free_full_filename = 1; 00363 00364 if (rsbac_get_full_path(dfs->extra_data->dentry, dfs->extra_data->full_filename, length + 1) < 1) 00365 return -1; 00366 00367 /* find the actual value of the length */ 00368 dfs->extra_data->full_filename_length = dazuko_get_filename_length(dfs->extra_data->full_filename); 00369 00370 /* reference copy of full path */ 00371 dfs->filename = dfs->extra_data->full_filename; 00372 00373 dfs->filename_length = dfs->extra_data->full_filename_length; 00374 00375 dfs->file_p.size = dfs->extra_data->dentry->d_inode->i_size; 00376 dfs->file_p.set_size = 1; 00377 dfs->file_p.uid = dfs->extra_data->dentry->d_inode->i_uid; 00378 dfs->file_p.set_uid = 1; 00379 dfs->file_p.gid = dfs->extra_data->dentry->d_inode->i_gid; 00380 dfs->file_p.set_gid = 1; 00381 dfs->file_p.mode = dfs->extra_data->dentry->d_inode->i_mode; 00382 dfs->file_p.set_mode = 1; 00383 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00384 dfs->file_p.device_type = dfs->extra_data->dentry->d_inode->i_dev; 00385 #else 00386 dfs->file_p.device_type = dfs->extra_data->dentry->d_inode->i_rdev; 00387 #endif 00388 dfs->file_p.set_device_type = 1; 00389 00390 return 0; 00391 } 00392 00393 int xp_file_struct_check_cleanup(struct dazuko_file_struct *dfs) 00394 { 00395 return 0; 00396 } 00397 00398 static int dazuko_file_struct_cleanup(struct dazuko_file_struct **dfs) 00399 { 00400 if (dfs == NULL) 00401 return 0; 00402 00403 if (*dfs == NULL) 00404 return 0; 00405 00406 xp_file_struct_check_cleanup(*dfs); 00407 00408 if ((*dfs)->extra_data != NULL) 00409 { 00410 if ((*dfs)->extra_data->free_full_filename) 00411 xp_free((*dfs)->extra_data->full_filename); 00412 00413 xp_free((*dfs)->extra_data); 00414 } 00415 00416 xp_free(*dfs); 00417 00418 *dfs = NULL; 00419 00420 return 0; 00421 } 00422 00423 00424 /* daemon id */ 00425 00426 int xp_id_compare(struct xp_daemon_id *id1, struct xp_daemon_id *id2) 00427 { 00428 if (id1 == NULL || id2 == NULL) 00429 return -1; 00430 00431 /* if file's are available and they match, 00432 * then we say that the id's match */ 00433 if (id1->file != NULL && id1->file == id2->file) 00434 return 0; 00435 00436 if (id1->pid == id2->pid) 00437 return 0; 00438 00439 return 1; 00440 } 00441 00442 int xp_id_free(struct xp_daemon_id *id) 00443 { 00444 xp_free(id); 00445 00446 return 0; 00447 } 00448 00449 struct xp_daemon_id* xp_id_copy(struct xp_daemon_id *id) 00450 { 00451 struct xp_daemon_id *ptr; 00452 00453 if (id == NULL) 00454 return NULL; 00455 00456 ptr = (struct xp_daemon_id *)xp_malloc(sizeof(struct xp_daemon_id)); 00457 00458 if (ptr != NULL) 00459 { 00460 ptr->pid = id->pid; 00461 ptr->file = id->file; 00462 } 00463 00464 return ptr; 00465 } 00466 00467 00468 /* system hook */ 00469 00470 inline int xp_sys_hook() 00471 { 00472 /* Called insmod when inserting the module. */ 00473 00474 /* register the dazuko device */ 00475 #ifdef DEVFS_SUPPORT 00476 dev_major = devfs_register_chrdev(CONFIG_RSBAC_DAZ_DEV_MAJOR, DEVICE_NAME, &fops); 00477 devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, 00478 dev_major, 0, S_IFCHR | S_IRUSR | S_IWUSR, 00479 &fops, NULL); 00480 #else 00481 dev_major = register_chrdev(CONFIG_RSBAC_DAZ_DEV_MAJOR, DEVICE_NAME, &fops); 00482 #endif 00483 if (dev_major < 0) 00484 { 00485 xp_print("dazuko: unable to register device chrdev, err=%d\n", dev_major); 00486 return dev_major; 00487 } 00488 00489 /* initialization complete */ 00490 00491 return 0; 00492 } 00493 00494 inline int xp_sys_unhook() 00495 { 00496 /* Called by rmmod when removing the module. */ 00497 00498 int error; 00499 00500 #ifdef DEVFS_SUPPORT 00501 error = devfs_unregister_chrdev(dev_major, DEVICE_NAME); 00502 devfs_unregister(devfs_find_handle(NULL, DEVICE_NAME, dev_major, 0, DEVFS_SPECIAL_CHR, 0)); 00503 #else 00504 error = unregister_chrdev(dev_major, DEVICE_NAME); 00505 #endif 00506 if (error < 0) 00507 { 00508 xp_print("dazuko: error unregistering chrdev, err=%d\n", error); 00509 } 00510 00511 return 0; 00512 } 00513 00514 00515 /* output */ 00516 00517 int xp_print(const char *fmt, ...) 00518 { 00519 va_list args; 00520 char *p; 00521 size_t size = 1024; 00522 00523 p = (char *)xp_malloc(size); 00524 if (!p) 00525 return -1; 00526 00527 va_start(args, fmt); 00528 dazuko_vsnprintf(p, size-1, fmt, args); 00529 va_end(args); 00530 00531 p[size-1] = 0; 00532 00533 printk(p); 00534 rsbac_printk(p); 00535 00536 xp_free(p); 00537 00538 return 0; 00539 } 00540 00541 00542 /* ioctl's */ 00543 00544 int linux_dazuko_device_open(struct inode *inode, struct file *file) 00545 { 00546 DPRINT(("dazuko: linux_dazuko_device_open() [%d]\n", current->pid)); 00547 00548 return 0; 00549 } 00550 00551 ssize_t linux_dazuko_device_read(struct file *file, char *buffer, size_t length, loff_t *pos) 00552 { 00553 /* Reading from the dazuko device simply 00554 * returns the device number. This is to 00555 * help out the daemon. */ 00556 00557 char tmp[20]; 00558 size_t dev_major_len; 00559 00560 DPRINT(("dazuko: linux_dazuko_device_read() [%d]\n", current->pid)); 00561 00562 /* only one read is allowed */ 00563 if (*pos != 0) 00564 return 0; 00565 00566 if (dev_major < 0) 00567 return -ENODEV; 00568 00569 /* print dev_major to a string 00570 * and get length (with terminator) */ 00571 dazuko_bzero(tmp, sizeof(tmp)); 00572 00573 dev_major_len = dazuko_snprintf(tmp, sizeof(tmp), "%d", dev_major) + 1; 00574 00575 if (tmp[sizeof(tmp)-1] != 0) 00576 { 00577 xp_print("dazuko: failing device_read, device number overflow for dameon %d (dev_major=%d)\n", current->pid, dev_major); 00578 return -EFAULT; 00579 } 00580 00581 if (length < dev_major_len) 00582 return -EINVAL; 00583 00584 /* copy dev_major string to userspace */ 00585 if (xp_copyout(tmp, buffer, dev_major_len) != 0) 00586 return -EFAULT; 00587 00588 *pos = dev_major_len; 00589 00590 return dev_major_len; 00591 } 00592 00593 ssize_t linux_dazuko_device_write(struct file *file, const char *buffer, size_t length, loff_t *pos) 00594 { 00595 struct dazuko_request *u_request; 00596 struct xp_daemon_id xp_id; 00597 char tmpbuffer[32]; 00598 char *value; 00599 int size; 00600 00601 size = length; 00602 if (length >= sizeof(tmpbuffer)) 00603 size = sizeof(tmpbuffer) -1; 00604 00605 /* copy request pointer string to kernelspace */ 00606 if (xp_copyin(buffer, tmpbuffer, size) != 0) 00607 return -EFAULT; 00608 00609 tmpbuffer[size] = 0; 00610 00611 if (dazuko_get_value("\nRA=", buffer, &value) != 0) 00612 { 00613 xp_print("dazuko: error: linux_dazuko_device_write.RA missing\n"); 00614 return -EFAULT; 00615 } 00616 00617 u_request = (struct dazuko_request *)simple_strtoul(value, NULL, 10); 00618 00619 xp_free(value); 00620 00621 xp_id.pid = current->pid; 00622 xp_id.file = file; 00623 00624 if (dazuko_handle_user_request(u_request, &xp_id) == 0) 00625 return length; 00626 else 00627 return -EINTR; 00628 } 00629 00630 int linux_dazuko_device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param) 00631 { 00632 /* A daemon uses this function to interact with 00633 * the kernel. A daemon can set scanning parameters, 00634 * give scanning response, and get filenames to scan. */ 00635 00636 struct xp_daemon_id xp_id; 00637 int error = 0; 00638 00639 if (param == 0) 00640 { 00641 xp_print("dazuko: error: linux_dazuko_device_ioctl(..., 0)\n"); 00642 return -EFAULT; 00643 } 00644 00645 xp_id.pid = current->pid; 00646 xp_id.file = file; 00647 00648 error = dazuko_handle_user_request_compat12((void *)param, _IOC_NR(cmd), &xp_id); 00649 00650 if (error != 0) 00651 { 00652 /* general error occurred */ 00653 00654 return -EPERM; 00655 } 00656 00657 return error; 00658 } 00659 00660 int linux_dazuko_device_release(struct inode *inode, struct file *file) 00661 { 00662 struct xp_daemon_id xp_id; 00663 00664 DPRINT(("dazuko: dazuko_device_release() [%d]\n", current->pid)); 00665 00666 xp_id.pid = current->pid; 00667 xp_id.file = file; 00668 00669 return dazuko_unregister_daemon(&xp_id); 00670 } 00671 00672 00673 /************************************************* */ 00674 /* Externally visible functions */ 00675 /************************************************* */ 00676 00677 #ifdef CONFIG_RSBAC_INIT_DELAY 00678 int rsbac_init_daz(void) 00679 #else 00680 int __init rsbac_init_daz(void) 00681 #endif 00682 { 00683 if (rsbac_is_initialized()) 00684 { 00685 #ifdef CONFIG_RSBAC_RMSG 00686 rsbac_printk(KERN_WARNING "rsbac_init_daz(): RSBAC already initialized\n"); 00687 #endif 00688 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00689 if (!rsbac_nosyslog) 00690 #endif 00691 printk(KERN_WARNING "rsbac_init_daz(): RSBAC already initialized\n"); 00692 return(-RSBAC_EREINIT); 00693 } 00694 00695 /* init data structures */ 00696 #ifdef CONFIG_RSBAC_RMSG 00697 rsbac_printk(KERN_INFO "rsbac_init_daz(): Initializing RSBAC: DAZuko subsystem\n"); 00698 #endif 00699 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00700 if (!rsbac_nosyslog) 00701 #endif 00702 printk(KERN_INFO "rsbac_init_daz(): Initializing RSBAC: DAZuko subsystem\n"); 00703 00704 return dazuko_init(); 00705 } 00706 00707 00708 enum rsbac_adf_req_ret_t 00709 rsbac_adf_request_daz (enum rsbac_adf_request_t request, 00710 rsbac_pid_t caller_pid, 00711 enum rsbac_target_t target, 00712 union rsbac_target_id_t tid, 00713 enum rsbac_attribute_t attr, 00714 union rsbac_attribute_value_t attr_val, 00715 rsbac_uid_t owner) 00716 { 00717 struct dazuko_file_struct *dfs = NULL; 00718 struct xp_daemon_id xp_id; 00719 int error = 0; 00720 int check_error = 0; 00721 struct event_properties event_p; 00722 int event; 00723 int daemon_allowed; 00724 00725 union rsbac_target_id_t i_tid; 00726 union rsbac_attribute_value_t i_attr_val1; 00727 00728 switch (request) 00729 { 00730 case R_DELETE: 00731 if (target == T_FILE) 00732 { 00733 event = DAZUKO_ON_UNLINK; 00734 daemon_allowed = 1; 00735 } 00736 else if (target == T_DIR) 00737 { 00738 event = DAZUKO_ON_RMDIR; 00739 daemon_allowed = 1; 00740 } 00741 else 00742 { 00743 return DO_NOT_CARE; 00744 } 00745 break; 00746 case R_CLOSE: 00747 if (target == T_FILE) 00748 { 00749 event = DAZUKO_ON_CLOSE; 00750 daemon_allowed = 1; 00751 } 00752 else 00753 { 00754 return DO_NOT_CARE; 00755 } 00756 break; 00757 00758 case R_EXECUTE: 00759 if (target == T_FILE) 00760 { 00761 event = DAZUKO_ON_EXEC; 00762 daemon_allowed = 0; 00763 } 00764 else 00765 { 00766 return DO_NOT_CARE; 00767 } 00768 break; 00769 00770 case R_APPEND_OPEN: 00771 case R_READ_WRITE_OPEN: 00772 case R_READ_OPEN: 00773 case R_WRITE_OPEN: 00774 if (target == T_FILE) 00775 { 00776 event = DAZUKO_ON_OPEN; 00777 daemon_allowed = 1; 00778 } 00779 else 00780 if (target == T_DEV) 00781 { 00782 if( (tid.dev.type == D_char) 00783 && (MAJOR(tid.dev.id) == CONFIG_RSBAC_DAZ_DEV_MAJOR) 00784 ) 00785 { 00786 i_tid.process = caller_pid; 00787 if (rsbac_get_attr(DAZ, 00788 T_PROCESS, 00789 i_tid, 00790 A_daz_scanner, 00791 &i_attr_val1, 00792 TRUE)) 00793 { 00794 #ifdef CONFIG_RSBAC_RMSG 00795 rsbac_printk(KERN_WARNING 00796 "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n"); 00797 #endif 00798 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00799 if (!rsbac_nosyslog) 00800 #endif 00801 printk(KERN_WARNING 00802 "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n"); 00803 return(NOT_GRANTED); 00804 } 00805 /* if scanner, then grant */ 00806 if (i_attr_val1.daz_scanner) 00807 return(GRANTED); 00808 else 00809 return(NOT_GRANTED); 00810 } 00811 else 00812 return DO_NOT_CARE; 00813 } 00814 else 00815 { 00816 return DO_NOT_CARE; 00817 } 00818 break; 00819 00820 case R_MODIFY_ATTRIBUTE: 00821 switch(attr) 00822 { 00823 case A_daz_scanned: 00824 case A_daz_scanner: 00825 case A_system_role: 00826 case A_daz_role: 00827 /* All attributes (remove target!) */ 00828 case A_none: 00829 /* Security Officer? */ 00830 i_tid.user = owner; 00831 if (rsbac_get_attr(DAZ, 00832 T_USER, 00833 i_tid, 00834 A_daz_role, 00835 &i_attr_val1, 00836 TRUE)) 00837 { 00838 #ifdef CONFIG_RSBAC_RMSG 00839 rsbac_printk(KERN_WARNING 00840 "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n"); 00841 #endif 00842 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00843 if (!rsbac_nosyslog) 00844 #endif 00845 printk(KERN_WARNING 00846 "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n"); 00847 return(NOT_GRANTED); 00848 } 00849 /* if sec_officer, then grant */ 00850 if (i_attr_val1.system_role == SR_security_officer) 00851 return(GRANTED); 00852 else 00853 return(NOT_GRANTED); 00854 00855 default: 00856 return(DO_NOT_CARE); 00857 } 00858 00859 case R_READ_ATTRIBUTE: 00860 switch(attr) 00861 { 00862 /* every user may see scan status of files */ 00863 case A_daz_scanned: 00864 return(GRANTED); 00865 /* ...but only security officers may see other attributes */ 00866 case A_system_role: 00867 case A_daz_role: 00868 case A_daz_scanner: 00869 /* Security Officer? */ 00870 i_tid.user = owner; 00871 if (rsbac_get_attr(DAZ, 00872 T_USER, 00873 i_tid, 00874 A_daz_role, 00875 &i_attr_val1, 00876 TRUE)) 00877 { 00878 #ifdef CONFIG_RSBAC_RMSG 00879 rsbac_printk(KERN_WARNING 00880 "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n"); 00881 #endif 00882 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00883 if (!rsbac_nosyslog) 00884 #endif 00885 printk(KERN_WARNING 00886 "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n"); 00887 return(NOT_GRANTED); 00888 } 00889 /* if sec_officer, then grant */ 00890 if (i_attr_val1.system_role == SR_security_officer) 00891 return(GRANTED); 00892 else 00893 return(NOT_GRANTED); 00894 00895 default: 00896 return(DO_NOT_CARE); 00897 } 00898 00899 case R_SWITCH_MODULE: 00900 switch(target) 00901 { 00902 case T_NONE: 00903 /* we need the switch_target */ 00904 if(attr != A_switch_target) 00905 return(UNDEFINED); 00906 /* do not care for other modules */ 00907 if( (attr_val.switch_target != DAZ) 00908 #ifdef CONFIG_RSBAC_SOFTMODE 00909 && (attr_val.switch_target != SOFTMODE) 00910 #endif 00911 ) 00912 return(DO_NOT_CARE); 00913 /* test owner's daz_role */ 00914 i_tid.user = owner; 00915 if (rsbac_get_attr(DAZ, 00916 T_USER, 00917 i_tid, 00918 A_daz_role, 00919 &i_attr_val1, 00920 TRUE)) 00921 { 00922 #ifdef CONFIG_RSBAC_RMSG 00923 rsbac_printk(KERN_WARNING "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n"); 00924 #endif 00925 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00926 if (!rsbac_nosyslog) 00927 #endif 00928 printk(KERN_WARNING "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n"); 00929 return(NOT_GRANTED); 00930 } 00931 /* security officer? -> grant */ 00932 if (i_attr_val1.system_role == SR_security_officer) 00933 return(GRANTED); 00934 else 00935 return(NOT_GRANTED); 00936 00937 /* all other cases are undefined */ 00938 default: return(DO_NOT_CARE); 00939 } 00940 00941 /*********************/ 00942 default: return DO_NOT_CARE; 00943 } 00944 00945 #if defined(CONFIG_RSBAC_DAZ_CACHE) 00946 /* get daz_scanned for file */ 00947 if (rsbac_get_attr(DAZ, 00948 T_FILE, 00949 tid, 00950 A_daz_scanned, 00951 &i_attr_val1, 00952 TRUE)) 00953 { 00954 #ifdef CONFIG_RSBAC_RMSG 00955 rsbac_printk(KERN_WARNING 00956 "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n"); 00957 #endif 00958 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00959 if (!rsbac_nosyslog) 00960 #endif 00961 printk(KERN_WARNING 00962 "rsbac_adf_request_daz(): rsbac_get_attr() returned error!\n"); 00963 return(-RSBAC_EREADFAILED); 00964 } 00965 if(i_attr_val1.daz_scanned == DAZ_clean) 00966 return GRANTED; 00967 #endif 00968 00969 xp_id.pid = current->pid; 00970 xp_id.file = NULL; 00971 00972 check_error = dazuko_sys_check(event, daemon_allowed, &xp_id); 00973 00974 if (!check_error) 00975 { 00976 dazuko_bzero(&event_p, sizeof(event_p)); 00977 /* 00978 event_p.flags = flags; 00979 event_p.set_flags = 1; 00980 event_p.mode = mode; 00981 event_p.set_mode = 1; 00982 */ 00983 event_p.pid = current->pid; 00984 event_p.set_pid = 1; 00985 event_p.uid = current->uid; 00986 event_p.set_uid = 1; 00987 00988 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct)); 00989 if (dfs != NULL) 00990 { 00991 dazuko_bzero(dfs, sizeof(struct dazuko_file_struct)); 00992 00993 dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct)); 00994 if (dfs->extra_data != NULL) 00995 { 00996 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct)); 00997 00998 dfs->extra_data->dentry = tid.file.dentry_p; 00999 01000 error = dazuko_sys_pre(event, dfs, &event_p); 01001 01002 #if defined(CONFIG_RSBAC_DAZ_CACHE) 01003 if(!error) 01004 i_attr_val1.daz_scanned = DAZ_clean; 01005 else 01006 i_attr_val1.daz_scanned = DAZ_infected; 01007 01008 if (rsbac_set_attr(DAZ, 01009 target, 01010 tid, 01011 A_daz_scanned, 01012 i_attr_val1)) 01013 { 01014 #ifdef CONFIG_RSBAC_RMSG 01015 rsbac_printk(KERN_WARNING "rsbac_adf_request_daz(): rsbac_set_attr() returned error!\n"); 01016 #endif 01017 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01018 if (!rsbac_nosyslog) 01019 #endif 01020 printk(KERN_WARNING "rsbac_adf_request_daz(): rsbac_set_attr() returned error!\n"); 01021 return NOT_GRANTED; 01022 } 01023 #endif 01024 } 01025 else 01026 { 01027 xp_free(dfs); 01028 dfs = NULL; 01029 } 01030 01031 dazuko_file_struct_cleanup(&dfs); 01032 } 01033 } 01034 01035 if(!error) 01036 return GRANTED; 01037 else 01038 return NOT_GRANTED; 01039 }; /* end of rsbac_adf_request_daz() */ 01040 01041 01042 /*****************************************************************************/ 01043 /* If the request returned granted and the operation is performed, */ 01044 /* the following function can be called by the AEF to get all aci set */ 01045 /* correctly. For write accesses that are performed fully within the kernel, */ 01046 /* this is usually not done to prevent extra calls, including R_CLOSE for */ 01047 /* cleaning up. Because of this, the write boundary is not adjusted - there */ 01048 /* is no user-level writing anyway... */ 01049 /* The second instance of target specification is the new target, if one has */ 01050 /* been created, otherwise its values are ignored. */ 01051 /* On success, 0 is returned, and an error from rsbac/error.h otherwise. */ 01052 01053 int rsbac_adf_set_attr_daz( 01054 enum rsbac_adf_request_t request, 01055 rsbac_pid_t caller_pid, 01056 enum rsbac_target_t target, 01057 union rsbac_target_id_t tid, 01058 enum rsbac_target_t new_target, 01059 union rsbac_target_id_t new_tid, 01060 enum rsbac_attribute_t attr, 01061 union rsbac_attribute_value_t attr_val, 01062 rsbac_uid_t owner) 01063 { 01064 struct dazuko_file_struct *dfs = NULL; 01065 struct xp_daemon_id xp_id; 01066 int check_error = 0; 01067 struct event_properties event_p; 01068 int event; 01069 int daemon_allowed; 01070 union rsbac_target_id_t i_tid; 01071 union rsbac_attribute_value_t i_attr_val1; 01072 union rsbac_attribute_value_t i_attr_val2; 01073 01074 switch (request) 01075 { 01076 case R_DELETE: 01077 if (target == T_FILE) 01078 { 01079 reset_scanned(tid.file); 01080 event = DAZUKO_ON_UNLINK; 01081 daemon_allowed = 1; 01082 } 01083 else if (target == T_DIR) 01084 { 01085 event = DAZUKO_ON_RMDIR; 01086 daemon_allowed = 1; 01087 } 01088 else 01089 { 01090 return(0); 01091 } 01092 break; 01093 case R_CLOSE: 01094 if (target == T_FILE) 01095 { 01096 event = DAZUKO_ON_CLOSE; 01097 daemon_allowed = 1; 01098 } 01099 else 01100 { 01101 return(0); 01102 } 01103 break; 01104 01105 case R_EXECUTE: 01106 if (target == T_FILE) 01107 { 01108 /* get daz_scanner for file */ 01109 if (rsbac_get_attr(DAZ, 01110 T_FILE, 01111 tid, 01112 A_daz_scanner, 01113 &i_attr_val1, 01114 TRUE)) 01115 { 01116 #ifdef CONFIG_RSBAC_RMSG 01117 rsbac_printk(KERN_WARNING 01118 "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n"); 01119 #endif 01120 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01121 if (!rsbac_nosyslog) 01122 #endif 01123 printk(KERN_WARNING 01124 "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n"); 01125 return(-RSBAC_EREADFAILED); 01126 } 01127 /* get for process */ 01128 i_tid.process = caller_pid; 01129 if (rsbac_get_attr(DAZ, 01130 T_PROCESS, 01131 i_tid, 01132 A_daz_scanner, 01133 &i_attr_val2, 01134 FALSE)) 01135 { 01136 #ifdef CONFIG_RSBAC_RMSG 01137 rsbac_printk(KERN_WARNING 01138 "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n"); 01139 #endif 01140 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01141 if (!rsbac_nosyslog) 01142 #endif 01143 printk(KERN_WARNING 01144 "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n"); 01145 return(-RSBAC_EREADFAILED); 01146 } 01147 /* and set for process, if different */ 01148 if(i_attr_val1.daz_scanner != i_attr_val2.daz_scanner) 01149 if (rsbac_set_attr(DAZ, 01150 T_PROCESS, 01151 i_tid, 01152 A_daz_scanner, 01153 i_attr_val1)) 01154 { 01155 #ifdef CONFIG_RSBAC_RMSG 01156 rsbac_printk(KERN_WARNING "rsbac_adf_set_attr_daz(): rsbac_set_attr() returned error!\n"); 01157 #endif 01158 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01159 if (!rsbac_nosyslog) 01160 #endif 01161 printk(KERN_WARNING "rsbac_adf_set_attr_daz(): rsbac_set_attr() returned error!\n"); 01162 return(-RSBAC_EWRITEFAILED); 01163 } 01164 event = DAZUKO_ON_EXEC; 01165 daemon_allowed = 0; 01166 } 01167 else 01168 { 01169 return(0); 01170 } 01171 break; 01172 01173 case R_APPEND_OPEN: 01174 case R_READ_WRITE_OPEN: 01175 case R_WRITE_OPEN: 01176 if (target == T_FILE) 01177 { 01178 reset_scanned(tid.file); 01179 event = DAZUKO_ON_OPEN; 01180 daemon_allowed = 1; 01181 } 01182 else 01183 { 01184 return(0); 01185 } 01186 break; 01187 01188 case R_READ_OPEN: 01189 if (target == T_FILE) 01190 { 01191 event = DAZUKO_ON_OPEN; 01192 daemon_allowed = 1; 01193 } 01194 else 01195 { 01196 return(0); 01197 } 01198 break; 01199 01200 case R_CLONE: 01201 if (target == T_PROCESS) 01202 { 01203 /* Get daz_scanner from first process */ 01204 if (rsbac_get_attr(DAZ, 01205 T_PROCESS, 01206 tid, 01207 A_daz_scanner, 01208 &i_attr_val1, 01209 FALSE)) 01210 { 01211 #ifdef CONFIG_RSBAC_RMSG 01212 rsbac_printk(KERN_WARNING 01213 "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n"); 01214 #endif 01215 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01216 if (!rsbac_nosyslog) 01217 #endif 01218 printk(KERN_WARNING 01219 "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n"); 01220 return(-RSBAC_EREADFAILED); 01221 } 01222 /* Set daz_scanner for new process, if set for first */ 01223 if ( i_attr_val1.daz_scanner 01224 && (rsbac_set_attr(DAZ, 01225 T_PROCESS, 01226 new_tid, 01227 A_daz_scanner, 01228 i_attr_val1)) ) 01229 { 01230 #ifdef CONFIG_RSBAC_RMSG 01231 rsbac_printk(KERN_WARNING "rsbac_adf_set_attr_daz(): rsbac_set_attr() returned error!\n"); 01232 #endif 01233 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01234 if (!rsbac_nosyslog) 01235 #endif 01236 printk(KERN_WARNING "rsbac_adf_set_attr_daz(): rsbac_set_attr() returned error!\n"); 01237 return(-RSBAC_EWRITEFAILED); 01238 } 01239 return(0); 01240 } 01241 else 01242 return(0); 01243 01244 /*********************/ 01245 default: return(0); 01246 } 01247 01248 #if defined(CONFIG_RSBAC_DAZ_CACHE) 01249 /* get daz_scanned for file */ 01250 if (rsbac_get_attr(DAZ, 01251 T_FILE, 01252 tid, 01253 A_daz_scanned, 01254 &i_attr_val1, 01255 TRUE)) 01256 { 01257 #ifdef CONFIG_RSBAC_RMSG 01258 rsbac_printk(KERN_WARNING 01259 "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n"); 01260 #endif 01261 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 01262 if (!rsbac_nosyslog) 01263 #endif 01264 printk(KERN_WARNING 01265 "rsbac_adf_set_attr_daz(): rsbac_get_attr() returned error!\n"); 01266 return(-RSBAC_EREADFAILED); 01267 } 01268 if(i_attr_val1.daz_scanned == DAZ_clean) 01269 return 0; 01270 #endif 01271 01272 xp_id.pid = current->pid; 01273 xp_id.file = NULL; 01274 01275 check_error = dazuko_sys_check(event, daemon_allowed, &xp_id); 01276 01277 if (!check_error) 01278 { 01279 dazuko_bzero(&event_p, sizeof(event_p)); 01280 /* 01281 event_p.flags = flags; 01282 event_p.set_flags = 1; 01283 event_p.mode = mode; 01284 event_p.set_mode = 1; 01285 */ 01286 event_p.pid = current->pid; 01287 event_p.set_pid = 1; 01288 event_p.uid = current->uid; 01289 event_p.set_uid = 1; 01290 01291 dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct)); 01292 if (dfs != NULL) 01293 { 01294 dazuko_bzero(dfs, sizeof(struct dazuko_file_struct)); 01295 01296 dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct)); 01297 if (dfs->extra_data != NULL) 01298 { 01299 dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct)); 01300 01301 dfs->extra_data->dentry = tid.file.dentry_p; 01302 01303 dazuko_sys_post(event, dfs, NULL, &event_p); 01304 } 01305 else 01306 { 01307 xp_free(dfs); 01308 dfs = NULL; 01309 } 01310 01311 dazuko_file_struct_cleanup(&dfs); 01312 } 01313 } 01314 01315 return(0); 01316 }; /* end of rsbac_adf_set_attr_daz() */ 01317 01318 /* end of rsbac/adf/daz/daz_main.c */ 01319

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