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

Generated on Wed May 16 11:53:30 2007 for RSBAC by  doxygen 1.5.1