reg_sample2.c

Go to the documentation of this file.
00001 /*
00002  * RSBAC REG decision module sample2
00003  * (not working any more, kept for reference)
00004  *
00005  * Author and (c) 1999-2005 Amon Ott <ao@rsbac.org>
00006  */
00007 
00008 /* general stuff */
00009 #include <linux/config.h>
00010 #include <linux/module.h>
00011 #include <linux/types.h>
00012 #include <linux/kernel.h>
00013 #include <linux/string.h>
00014 /* for (un)lock_kernel() */
00015 #include <linux/sched.h>
00016 #include <linux/smp.h>
00017 #include <linux/smp_lock.h>
00018 /* for file access */
00019 #include <linux/fs.h>
00020 #include <asm/uaccess.h>
00021 /* rsbac */
00022 #include <rsbac/types.h>
00023 #include <rsbac/reg.h>
00024 #include <rsbac/adf.h>
00025 #include <rsbac/aci.h>
00026 #include <rsbac/aci_data_structures.h>
00027 #include <rsbac/getname.h>
00028 #include <rsbac/error.h>
00029 #include <rsbac/proc_fs.h>
00030 
00031 static u_long nr_request_calls = 0;
00032 static u_long nr_set_attr_calls = 0;
00033 static u_long nr_need_overwrite_calls = 0;
00034 static rsbac_boolean_t no_write = FALSE;
00035 static u_long nr_system_calls = 0;
00036 static void * system_call_arg = 0;
00037 
00038 MODULE_AUTHOR("Amon Ott");
00039 MODULE_DESCRIPTION("RSBAC REG sample decision module 2");
00040 
00041 MODULE_PARM(name, "s");
00042 static char * name = NULL;
00043 static char dummy_buf[70]="To protect against wrong insmod params";
00044 
00045 MODULE_PARM(syscall_name, "s");
00046 static char * syscall_name = NULL;
00047 static char dummy_buf2[70]="To protect against wrong insmod params";
00048 
00049 MODULE_PARM(handle, "l");
00050 static long handle = 123457;
00051 
00052 MODULE_PARM(syscall_registration_handle, "l");
00053 static long syscall_registration_handle = 754321;
00054 MODULE_PARM(syscall_dispatcher_handle, "l");
00055 static long syscall_dispatcher_handle = 2;
00056 
00057 /* Filename for persistent data in /rsbac dir of ROOT_DEV (max 7 chars) */
00058 #define FILENAME "regsmp2"
00059 
00060 /* Version number for on disk data structures */
00061 #define FILE_VERSION 1
00062 
00063 /* PROC functions */
00064 
00065 #if defined(CONFIG_RSBAC_PROC)
00066 #define PROC_NAME "reg_sample2"
00067 static struct proc_dir_entry * proc_reg_sample_p;
00068 
00069 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
00070 static int
00071 adf_sample_proc_info(char *buffer, char **start, off_t offset, int length, int dummy)
00072 #else
00073 static int
00074 adf_sample_proc_info(char *buffer, char **start, off_t offset, int length)
00075 #endif
00076 {
00077   int len = 0;
00078   off_t pos   = 0;
00079   off_t begin = 0;
00080 
00081   union rsbac_target_id_t       rsbac_target_id;
00082   union rsbac_attribute_value_t rsbac_attribute_value;
00083 
00084   if (!rsbac_is_initialized())
00085     return (-ENOSYS);
00086 
00087   rsbac_target_id.scd = ST_rsbac;
00088   rsbac_attribute_value.dummy = 0;
00089   if (!rsbac_adf_request(R_GET_STATUS_DATA,
00090                          current->pid,
00091                          T_SCD,
00092                          rsbac_target_id,
00093                          A_none,
00094                          rsbac_attribute_value))
00095     {
00096       return -EPERM;
00097     }
00098   len += sprintf(buffer, "RSBAC REG decision module sample 2\n----------------------------------\n");
00099   pos = begin + len;
00100   if (pos < offset)
00101     {
00102       len = 0;
00103       begin = pos;
00104     }
00105   if (pos > offset+length)
00106     goto out;
00107 
00108   len += sprintf(buffer + len, "%lu calls to request function.\n",
00109                  nr_request_calls);
00110   pos = begin + len;
00111   if (pos < offset)
00112     {
00113       len = 0;
00114       begin = pos;
00115     }
00116   if (pos > offset+length)
00117     goto out;
00118 
00119   len += sprintf(buffer + len, "%lu calls to set_attr function.\n",
00120                  nr_set_attr_calls);
00121   pos = begin + len;
00122   if (pos < offset)
00123     {
00124       len = 0;
00125       begin = pos;
00126     }
00127   if (pos > offset+length)
00128     goto out;
00129 
00130   len += sprintf(buffer + len, "%lu calls to need_overwrite function.\n",
00131                  nr_need_overwrite_calls);
00132   pos = begin + len;
00133   if (pos < offset)
00134     {
00135       len = 0;
00136       begin = pos;
00137     }
00138   if (pos > offset+length)
00139     goto out;
00140 
00141   len += sprintf(buffer + len, "%lu calls to system_call function %lu, last arg was %p.\n",
00142                  nr_system_calls,
00143                  syscall_dispatcher_handle,
00144                  system_call_arg);
00145   pos = begin + len;
00146   if (pos < offset)
00147     {
00148       len = 0;
00149       begin = pos;
00150     }
00151   if (pos > offset+length)
00152     goto out;
00153 
00154 out:
00155   *start = buffer + (offset - begin);
00156   len -= (offset - begin);
00157   
00158   if (len > length)
00159     len = length;
00160   return len;
00161 }
00162 #endif /* CONFIG_RSBAC_PROC */
00163 
00164 
00165 /**** Read/Write Functions ****/
00166 
00167 /* read_info() */
00168 /* reading the system wide adf_sample2 data */
00169 
00170 static int read_info(void)
00171   {
00172     struct file                     file;
00173     char                            name[RSBAC_MAXNAMELEN];
00174     int                             err = 0;
00175     int                             tmperr;
00176     mm_segment_t                    oldfs;
00177     u_int                           version;
00178     u_long                          tmpval;
00179 
00180     /* copy name from base name */
00181     strcpy(name, FILENAME);
00182 
00183     /* open file */
00184     if ((err = rsbac_read_open(name,
00185                                &file,
00186                                rsbac_root_dev) ))
00187       return(err);
00188 
00189     /* OK, now we can start reading */
00190 
00191     /* There is a read function for this file, so read data from
00192      * previous module load.
00193      * A positive read return value means a read success,
00194      * 0 end of file and a negative value an error.
00195      */
00196 
00197     /* Set current user space to kernel space, because read() writes */
00198     /* to user space */
00199     oldfs = get_fs();
00200     set_fs(KERNEL_DS);
00201 
00202     tmperr = file.f_op->read(&file,
00203                              (char *) &version,
00204                              sizeof(version),
00205                              &file.f_pos);
00206     /* error? */
00207     if (tmperr < sizeof(version))
00208       {
00209         printk(KERN_WARNING
00210                "read_info(): read error from file!\n");
00211         err = -RSBAC_EREADFAILED;
00212         goto end_read;
00213       }
00214     /* if wrong version, warn and skip */
00215     if (version != FILE_VERSION)
00216       {
00217         printk(KERN_WARNING
00218                "read_info(): wrong version %u, expected %u - skipping file and setting no_write!\n",
00219                version, FILE_VERSION);
00220         no_write = TRUE;
00221         err = -RSBAC_EREADFAILED;
00222         goto end_read;
00223       }
00224 
00225     /* read nr_request_calls */
00226     tmperr = file.f_op->read(&file,
00227                              (char *) &tmpval,
00228                              sizeof(tmpval),
00229                              &file.f_pos);
00230     if (tmperr < sizeof(tmpval))
00231       {
00232         printk(KERN_WARNING "%s\n",
00233                "read_info(): read error from file!");
00234         err = -RSBAC_EREADFAILED;
00235         goto end_read;
00236       }
00237     nr_request_calls = tmpval;
00238 
00239     /* read nr_set_attr_calls */
00240     tmperr = file.f_op->read(&file,
00241                              (char *) &tmpval,
00242                              sizeof(tmpval),
00243                              &file.f_pos);
00244     if (tmperr < sizeof(tmpval))
00245       {
00246         printk(KERN_WARNING "%s\n",
00247                "read_info(): read error from file!");
00248         err = -RSBAC_EREADFAILED;
00249         goto end_read;
00250       }
00251     nr_set_attr_calls = tmpval;
00252 
00253     /* read nr_need_overwrite_calls */
00254     tmperr = file.f_op->read(&file,
00255                              (char *) &tmpval,
00256                              sizeof(tmpval),
00257                              &file.f_pos);
00258     if (tmperr < sizeof(tmpval))
00259       {
00260         printk(KERN_WARNING "%s\n",
00261                "read_info(): read error from file!");
00262         err = -RSBAC_EREADFAILED;
00263         goto end_read;
00264       }
00265     nr_need_overwrite_calls = tmpval;
00266 
00267 end_read:
00268     /* Set current user space back to user space, because read() writes */
00269     /* to user space */
00270     set_fs(oldfs);
00271 
00272     /* We do not need this file dentry any more */
00273     rsbac_read_close(&file);
00274 
00275     /* ready */
00276     return(err);
00277   }; /* end of read_info() */
00278 
00279 static int write_info(void)
00280   {
00281     struct file                     file;
00282     char                            name[RSBAC_MAXNAMELEN];
00283     int                             err = 0;
00284     int                             tmperr;
00285     mm_segment_t                    oldfs;
00286     u_int                           version = FILE_VERSION;
00287     
00288     /* copy name from base name */
00289     strcpy(name, FILENAME);
00290 
00291     /* get rsbac write-to-disk semaphore */
00292     down(&rsbac_write_sem);
00293 
00294     /* open file */
00295     if ((err = rsbac_write_open(name,
00296                                 &file,
00297                                 rsbac_root_dev) ))
00298       {
00299         up(&rsbac_write_sem);
00300         return(err);
00301       }
00302 
00303     /* OK, now we can start writing all sample items.
00304      * A positive return value means a write success,
00305      * 0 end of file and a negative value an error.
00306      */
00307 
00308     /* Set current user space to kernel space, because write() reads
00309      * from user space */
00310     oldfs = get_fs();
00311     set_fs(KERNEL_DS);
00312 
00313     tmperr = file.f_op->write(&file,
00314                               (char *) &version,
00315                               sizeof(version),
00316                               &file.f_pos);
00317     if (tmperr < sizeof(version))
00318       {
00319         printk(KERN_WARNING
00320                "write_info(): write error %i on file!\n",
00321                tmperr);
00322         err = -RSBAC_EWRITEFAILED;
00323         goto end_write;
00324       }
00325 
00326     tmperr = file.f_op->write(&file,
00327                               (char *) &nr_request_calls,
00328                               sizeof(nr_request_calls),
00329                               &file.f_pos);
00330     if (tmperr < sizeof(nr_request_calls))
00331       {
00332         printk(KERN_WARNING
00333                "write_info(): write error %i on file!\n",
00334                tmperr);
00335         err = -RSBAC_EWRITEFAILED;
00336         goto end_write;
00337       }
00338 
00339     tmperr = file.f_op->write(&file,
00340                               (char *) &nr_set_attr_calls,
00341                               sizeof(nr_set_attr_calls),
00342                               &file.f_pos);
00343     if (tmperr < sizeof(nr_set_attr_calls))
00344       {
00345         printk(KERN_WARNING
00346                "write_info(): write error %i on file!\n",
00347                tmperr);
00348         err = -RSBAC_EWRITEFAILED;
00349         goto end_write;
00350       }
00351 
00352     tmperr = file.f_op->write(&file,
00353                               (char *) &nr_need_overwrite_calls,
00354                               sizeof(nr_need_overwrite_calls),
00355                               &file.f_pos);
00356     if (tmperr < sizeof(nr_need_overwrite_calls))
00357       {
00358         printk(KERN_WARNING
00359                "write_info(): write error %i on file!\n",
00360                tmperr);
00361         err = -RSBAC_EWRITEFAILED;
00362         goto end_write;
00363       }
00364 
00365 end_write:
00366     /* Set current user space back to user space, because write() reads */
00367     /* from user space */
00368     set_fs(oldfs);
00369 
00370     /* End of write access */
00371     rsbac_write_close(&file);
00372     up(&rsbac_write_sem);
00373     return(err);
00374   }; /* end of write_info() */
00375 
00376 
00377 /**** Decision Functions ****/
00378 
00379 static  int request_func  ( enum  rsbac_adf_request_t     request,
00380                                   rsbac_pid_t             owner_pid,
00381                             enum  rsbac_target_t          target,
00382                             union rsbac_target_id_t       tid,
00383                             enum  rsbac_attribute_t       attr,
00384                             union rsbac_attribute_value_t attr_val,
00385                             rsbac_uid_t                   owner)
00386   {
00387     /* count call, but not for SEARCH request */
00388     if(request != R_SEARCH)
00389       nr_request_calls++;
00390     return GRANTED;
00391   }
00392 
00393 static  int set_attr_func ( enum  rsbac_adf_request_t     request,
00394                                   rsbac_pid_t             owner_pid,
00395                             enum  rsbac_target_t          target,
00396                             union rsbac_target_id_t       tid,
00397                             enum  rsbac_target_t          new_target,
00398                             union rsbac_target_id_t       new_tid,
00399                             enum  rsbac_attribute_t       attr,
00400                             union rsbac_attribute_value_t attr_val,
00401                             rsbac_uid_t                   owner)
00402   {
00403     /* count call, but not for SEARCH request */
00404     if(request != R_SEARCH)
00405       nr_set_attr_calls++;
00406     return 0;
00407   }
00408 
00409 static rsbac_boolean_t need_overwrite_func (struct dentry * dentry_p)
00410   {
00411     nr_need_overwrite_calls++;
00412     return FALSE;
00413   }
00414 
00415 static int write_func(rsbac_boolean_t need_lock)
00416   {
00417     int res=0;
00418 
00419     if(need_lock)
00420       lock_kernel();
00421 
00422     if(!write_info())
00423       res = 1;
00424 
00425     if(need_lock)
00426       unlock_kernel();
00427 
00428     return(res);
00429   }
00430 
00431 static int syscall_func (void * arg)
00432   {
00433     nr_system_calls++;
00434     system_call_arg = arg;
00435     return nr_system_calls;
00436    }
00437 
00438 /**** Init ****/
00439 
00440 int init_module(void)
00441 {
00442   struct rsbac_reg_entry_t entry;
00443   struct rsbac_reg_syscall_entry_t syscall_entry;
00444 
00445   if(!handle)
00446     handle = 123457;
00447   if(!syscall_registration_handle)
00448     syscall_registration_handle = 754321;
00449   if(!syscall_dispatcher_handle)
00450     syscall_dispatcher_handle = 2;
00451 
00452   printk(KERN_INFO "RSBAC REG decision module sample 2: Initializing.\n");
00453 
00454   /* clearing registration entries */
00455   memset(&entry, 0, sizeof(entry));
00456   memset(&syscall_entry, 0, sizeof(syscall_entry));
00457 
00458   if((dummy_buf[0] != 'T') || (dummy_buf2[0] != 'T'))
00459     {
00460       printk(KERN_WARNING "RSBAC REG decision module sample 2: Not loaded due to invalid param string.\n");
00461       return -ENOEXEC;
00462     }
00463   if(name)
00464     {
00465       strncpy(entry.name, name, RSBAC_REG_NAME_LEN);
00466       entry.name[RSBAC_REG_NAME_LEN] = 0;
00467     }
00468   else
00469     strcpy(entry.name, "RSBAC REG sample 2 ADF module");
00470   printk(KERN_INFO "RSBAC REG decision module sample 2: REG Version: %u, Name: %s, Handle: %li\n",
00471          RSBAC_REG_VERSION, entry.name, handle);
00472 
00473   entry.handle = handle;
00474   entry.request_func = request_func;
00475   entry.set_attr_func = set_attr_func;
00476   entry.need_overwrite_func = need_overwrite_func;
00477   entry.write_func = write_func;
00478   entry.switch_on = TRUE;
00479 
00480   printk(KERN_INFO "RSBAC REG decision module sample 2: Registering to ADF.\n");
00481   if(rsbac_reg_register(RSBAC_REG_VERSION, entry) < 0)
00482     {
00483       printk(KERN_WARNING "RSBAC REG decision module sample 2: Registering failed. Unloading.\n");
00484       return -ENOEXEC;
00485     }
00486 
00487   if(syscall_name)
00488     {
00489       strncpy(syscall_entry.name, syscall_name, RSBAC_REG_NAME_LEN);
00490       syscall_entry.name[RSBAC_REG_NAME_LEN] = 0;
00491     }
00492   else
00493     strcpy(syscall_entry.name, "RSBAC REG sample 2 syscall");
00494   printk(KERN_INFO "RSBAC REG decision module sample 2: REG Version: %u, Name: %s, Dispatcher Handle: %li\n",
00495          RSBAC_REG_VERSION, syscall_entry.name, syscall_dispatcher_handle);
00496 
00497   syscall_entry.registration_handle = syscall_registration_handle;
00498   syscall_entry.dispatcher_handle = syscall_dispatcher_handle;
00499   syscall_entry.syscall_func = syscall_func;
00500 
00501   printk(KERN_INFO "RSBAC REG decision module sample 2: Registering syscall.\n");
00502   syscall_registration_handle = rsbac_reg_register_syscall(RSBAC_REG_VERSION, syscall_entry);
00503   if(syscall_registration_handle < 0)
00504     {
00505       printk(KERN_WARNING "RSBAC REG decision module sample 2: Registering syscall failed. Unloading.\n");
00506       if(rsbac_reg_unregister(handle))
00507         {
00508           printk(KERN_ERR "RSBAC REG decision module sample 2: Unregistering failed - beware of possible system failure!\n");
00509         }
00510       return -ENOEXEC;
00511     }
00512 
00513   if(read_info())
00514     {
00515       printk(KERN_WARNING
00516              "RSBAC REG decision module sample 2: Could not read info from previous session.\n");
00517     }
00518   
00519   #if defined(CONFIG_RSBAC_PROC)
00520   proc_reg_sample_p = create_proc_entry(PROC_NAME,
00521                                         S_IFREG | S_IRUGO,
00522                                         proc_rsbac_root_p);
00523   if(!proc_reg_sample_p)
00524     {
00525       printk(KERN_WARNING "%s: Not loaded due to failed proc entry registering.\n", name);
00526       if(rsbac_reg_unregister_syscall(syscall_registration_handle))
00527         {
00528           printk(KERN_ERR "RSBAC REG decision module sample 2: Unregistering syscall failed - beware of possible system failure!\n");
00529         }
00530       if(rsbac_reg_unregister(handle))
00531         {
00532           printk(KERN_ERR "RSBAC REG decision module sample 2: Unregistering from ADF failed - beware of possible system failure!\n");
00533         }
00534       return -ENOEXEC;
00535     }
00536   proc_reg_sample_p->get_info = adf_sample_proc_info;
00537   #endif 
00538 
00539   printk(KERN_INFO "RSBAC REG decision module sample 2: Loaded.\n");
00540 
00541   return 0;
00542 }
00543 
00544 void cleanup_module(void)
00545 {
00546   printk(KERN_INFO "RSBAC REG decision module sample 2: Unregistering.\n");
00547   #if defined(CONFIG_RSBAC_PROC)
00548   remove_proc_entry(PROC_NAME, proc_rsbac_root_p);
00549   #endif 
00550   if(write_info())
00551     {
00552       printk(KERN_WARNING
00553              "RSBAC REG decision module sample 2: Could not save info for next session.\n");
00554     }
00555   if(rsbac_reg_unregister_syscall(syscall_registration_handle))
00556     {
00557       printk(KERN_ERR "RSBAC REG decision module sample 2: Unregistering syscall failed - beware of possible system failure!\n");
00558     }
00559   if(rsbac_reg_unregister(handle))
00560     {
00561       printk(KERN_ERR "RSBAC REG decision module sample 2: Unregistering module failed - beware of possible system failure!\n");
00562     }
00563   printk(KERN_INFO "RSBAC REG decision module sample 2: Unloaded.\n");
00564 }

Generated on Fri Jun 17 09:45:20 2005 for RSBAC by  doxygen 1.4.2