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

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