reg_sample3.c

Go to the documentation of this file.
00001 /*
00002  * RSBAC REG decision module sample
00003  *
00004  * Author and (c) 1999-2005 Amon Ott <ao@rsbac.org>
00005  */
00006 
00007 /* general stuff */
00008 #include <linux/config.h>
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/lists.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 #define ORD_request 1
00032 static u_long nr_set_attr_calls = 0;
00033 #define ORD_set_attr 2
00034 static u_long nr_need_overwrite_calls = 0;
00035 #define ORD_overwrite 3
00036 static u_long nr_write_calls = 0;
00037 #define ORD_write 4
00038 static u_long nr_system_calls = 0;
00039 #define ORD_syscall 5
00040 static void * system_call_arg = 0;
00041 
00042 MODULE_AUTHOR("Amon Ott");
00043 MODULE_DESCRIPTION("RSBAC REG sample decision module 3");
00044 MODULE_LICENSE("GPL");
00045 
00046 MODULE_PARM(name, "s");
00047 static char * name = NULL;
00048 static char dummy_buf[70]="To protect against wrong insmod params";
00049 
00050 MODULE_PARM(syscall_name, "s");
00051 static char * syscall_name = NULL;
00052 static char dummy_buf2[70]="To protect against wrong insmod params";
00053 
00054 MODULE_PARM(listkey, "l");
00055 static u_int listkey = 133457;
00056 
00057 MODULE_PARM(handle, "l");
00058 static long handle = 133457;
00059 
00060 MODULE_PARM(syscall_registration_handle, "l");
00061 static long syscall_registration_handle = 754331;
00062 MODULE_PARM(syscall_dispatcher_handle, "l");
00063 static long syscall_dispatcher_handle = 3;
00064 
00065 /* Filename for persistent data in /rsbac dir of ROOT_DEV (max 7 chars) */
00066 #define FILENAME "regsmp3"
00067 
00068 /* Version number for on disk data structures */
00069 #define LIST_VERSION 1
00070 
00071 static rsbac_list_handle_t list_handle;
00072 
00073 /* PROC functions */
00074 
00075 #if defined(CONFIG_RSBAC_PROC)
00076 #define PROC_NAME "reg_sample3"
00077 static struct proc_dir_entry * proc_reg_sample_p;
00078 
00079 static int
00080 adf_sample_proc_info(char *buffer, char **start, off_t offset, int length)
00081 {
00082   int len = 0;
00083   off_t pos   = 0;
00084   off_t begin = 0;
00085 
00086   union rsbac_target_id_t       rsbac_target_id;
00087   union rsbac_attribute_value_t rsbac_attribute_value;
00088 
00089   if (!rsbac_is_initialized())
00090     return (-ENOSYS);
00091 
00092   rsbac_target_id.scd = ST_rsbac;
00093   rsbac_attribute_value.dummy = 0;
00094   if (!rsbac_adf_request(R_GET_STATUS_DATA,
00095                          current->pid,
00096                          T_SCD,
00097                          rsbac_target_id,
00098                          A_none,
00099                          rsbac_attribute_value))
00100     {
00101       return -EPERM;
00102     }
00103   len += sprintf(buffer, "RSBAC REG decision module sample 3\n----------------------------------\n");
00104   pos = begin + len;
00105   if (pos < offset)
00106     {
00107       len = 0;
00108       begin = pos;
00109     }
00110   if (pos > offset+length)
00111     goto out;
00112 
00113   len += sprintf(buffer + len, "%lu calls to request function.\n",
00114                  nr_request_calls);
00115   pos = begin + len;
00116   if (pos < offset)
00117     {
00118       len = 0;
00119       begin = pos;
00120     }
00121   if (pos > offset+length)
00122     goto out;
00123 
00124   len += sprintf(buffer + len, "%lu calls to set_attr function.\n",
00125                  nr_set_attr_calls);
00126   pos = begin + len;
00127   if (pos < offset)
00128     {
00129       len = 0;
00130       begin = pos;
00131     }
00132   if (pos > offset+length)
00133     goto out;
00134 
00135   len += sprintf(buffer + len, "%lu calls to need_overwrite function.\n",
00136                  nr_need_overwrite_calls);
00137   pos = begin + len;
00138   if (pos < offset)
00139     {
00140       len = 0;
00141       begin = pos;
00142     }
00143   if (pos > offset+length)
00144     goto out;
00145 
00146   len += sprintf(buffer + len, "%lu calls to write function.\n",
00147                  nr_write_calls);
00148   pos = begin + len;
00149   if (pos < offset)
00150     {
00151       len = 0;
00152       begin = pos;
00153     }
00154   if (pos > offset+length)
00155     goto out;
00156 
00157   len += sprintf(buffer + len, "%lu calls to system_call function %lu, last arg was %p.\n",
00158                  nr_system_calls,
00159                  syscall_dispatcher_handle,
00160                  system_call_arg);
00161   pos = begin + len;
00162   if (pos < offset)
00163     {
00164       len = 0;
00165       begin = pos;
00166     }
00167   if (pos > offset+length)
00168     goto out;
00169 
00170   len += sprintf(buffer + len, "%li list items.\n",
00171                  rsbac_list_count(list_handle));
00172   pos = begin + len;
00173   if (pos < offset)
00174     {
00175       len = 0;
00176       begin = pos;
00177     }
00178   if (pos > offset+length)
00179     goto out;
00180 
00181 out:
00182   *start = buffer + (offset - begin);
00183   len -= (offset - begin);
00184   
00185   if (len > length)
00186     len = length;
00187   return len;
00188 }
00189 #endif /* CONFIG_RSBAC_PROC */
00190 
00191 /**** List helper functions ****/
00192 
00193 static int compare(void * desc1, void * desc2)
00194   {
00195     return memcmp((u_int *) desc1, (u_int *) desc2, sizeof(u_int) );
00196   }
00197 
00198 /*
00199 static rsbac_list_conv_function_t * get_conv(rsbac_version_t version)
00200   {
00201     return compare;
00202   }
00203 */
00204 
00205 /**** Decision Functions ****/
00206 
00207 static  int request_func  ( enum  rsbac_adf_request_t     request,
00208                                   rsbac_pid_t             owner_pid,
00209                             enum  rsbac_target_t          target,
00210                             union rsbac_target_id_t       tid,
00211                             enum  rsbac_attribute_t       attr,
00212                             union rsbac_attribute_value_t attr_val,
00213                             rsbac_uid_t                   owner)
00214   {
00215     /* count call, but not for SEARCH request */
00216     if(request != R_SEARCH)
00217       {
00218         __u32 ord = ORD_request;
00219 
00220         nr_request_calls++;
00221         rsbac_list_add(list_handle, &ord, &nr_request_calls);
00222       }
00223     return GRANTED;
00224   }
00225 
00226 static  int set_attr_func ( enum  rsbac_adf_request_t     request,
00227                                   rsbac_pid_t             owner_pid,
00228                             enum  rsbac_target_t          target,
00229                             union rsbac_target_id_t       tid,
00230                             enum  rsbac_target_t          new_target,
00231                             union rsbac_target_id_t       new_tid,
00232                             enum  rsbac_attribute_t       attr,
00233                             union rsbac_attribute_value_t attr_val,
00234                             rsbac_uid_t                   owner)
00235   {
00236     __u32 ord = ORD_set_attr;
00237 
00238     /* count call, but not for SEARCH request */
00239     if(request != R_SEARCH)
00240       {
00241         nr_set_attr_calls++;
00242         rsbac_list_add(list_handle, &ord, &nr_set_attr_calls);
00243       }
00244     return 0;
00245   }
00246 
00247 static rsbac_boolean_t need_overwrite_func (struct dentry * dentry_p)
00248   {
00249     __u32 ord = ORD_overwrite;
00250 
00251     nr_need_overwrite_calls++;
00252     rsbac_list_add(list_handle, &ord, &nr_need_overwrite_calls);
00253     return FALSE;
00254   }
00255 
00256 static int write_func(rsbac_boolean_t need_lock)
00257   {
00258     __u32 ord = ORD_write;
00259 
00260     nr_write_calls++;
00261     rsbac_list_add(list_handle, &ord, &nr_write_calls);
00262     return(0);
00263   }
00264 
00265 static int syscall_func (void * arg)
00266   {
00267     __u32 ord = ORD_syscall;
00268 
00269     nr_system_calls++;
00270     system_call_arg = arg;
00271     rsbac_list_add(list_handle, &ord, &nr_system_calls);
00272     return nr_system_calls;
00273    }
00274 
00275 /**** Init ****/
00276 
00277 int init_module(void)
00278 {
00279   struct rsbac_reg_entry_t entry;
00280   struct rsbac_reg_syscall_entry_t syscall_entry;
00281   struct rsbac_list_info_t list_info;
00282   __u32 ord;
00283 
00284   if(!listkey)
00285     listkey = 133457;
00286   if(!handle)
00287     handle = 133457;
00288   if(!syscall_registration_handle)
00289     syscall_registration_handle = 754331;
00290   if(!syscall_dispatcher_handle)
00291     syscall_dispatcher_handle = 3;
00292 
00293   printk(KERN_INFO "RSBAC REG decision module sample 3: Initializing.\n");
00294 
00295   /* clearing registration entries */
00296   memset(&entry, 0, sizeof(entry));
00297   memset(&syscall_entry, 0, sizeof(syscall_entry));
00298 
00299   if((dummy_buf[0] != 'T') || (dummy_buf2[0] != 'T'))
00300     {
00301       printk(KERN_WARNING "RSBAC REG decision module sample 3: Not loaded due to invalid param string.\n");
00302       return -ENOEXEC;
00303     }
00304 
00305   /* Register a generic list */
00306   list_info.version = LIST_VERSION;
00307   list_info.key = listkey;
00308   list_info.desc_size = sizeof(__u32);
00309   list_info.data_size = sizeof(nr_request_calls);
00310   list_info.max_age = 3600; /* 1h */
00311   if(rsbac_list_register(RSBAC_LIST_VERSION,
00312                          &list_handle,
00313                          &list_info,
00314                          RSBAC_LIST_PERSIST | RSBAC_LIST_BACKUP,
00315                          compare,
00316                          NULL,
00317                          NULL,
00318                          FILENAME,
00319                          0))
00320     {
00321       printk(KERN_WARNING "RSBAC REG decision module sample 3: Registering list failed. Unloading.\n");
00322       return -ENOEXEC;
00323     }
00324   printk(KERN_INFO "RSBAC REG decision module sample 3: List Version: %u, Name: %s, Handle: %p, Key: %u\n",
00325          RSBAC_LIST_VERSION, FILENAME, list_handle, listkey);
00326   ord = ORD_request;
00327   if(rsbac_list_exist(list_handle, &ord))
00328     rsbac_list_get_data(list_handle, &ord, &nr_request_calls);
00329   ord = ORD_set_attr;
00330   if(rsbac_list_exist(list_handle, &ord))
00331     rsbac_list_get_data(list_handle, &ord, &nr_set_attr_calls);
00332   ord = ORD_overwrite;
00333   if(rsbac_list_exist(list_handle, &ord))
00334     rsbac_list_get_data(list_handle, &ord, &nr_need_overwrite_calls);
00335   ord = ORD_write;
00336   if(rsbac_list_exist(list_handle, &ord))
00337     rsbac_list_get_data(list_handle, &ord, &nr_write_calls);
00338   ord = ORD_syscall;
00339   if(rsbac_list_exist(list_handle, &ord))
00340     rsbac_list_get_data(list_handle, &ord, &nr_system_calls);
00341 
00342   /* Register to ADF */
00343   if(name)
00344     {
00345       strncpy(entry.name, name, RSBAC_REG_NAME_LEN);
00346       entry.name[RSBAC_REG_NAME_LEN] = 0;
00347     }
00348   else
00349     strcpy(entry.name, "RSBAC REG sample 3 ADF module");
00350   printk(KERN_INFO "RSBAC REG decision module sample 3: REG Version: %u, Name: %s, Handle: %li\n",
00351          RSBAC_REG_VERSION, entry.name, handle);
00352 
00353   entry.handle = handle;
00354   entry.request_func = request_func;
00355   entry.set_attr_func = set_attr_func;
00356   entry.need_overwrite_func = need_overwrite_func;
00357   entry.write_func = write_func;
00358   entry.switch_on = TRUE;
00359 
00360   printk(KERN_INFO "RSBAC REG decision module sample 3: Registering to ADF.\n");
00361   if(rsbac_reg_register(RSBAC_REG_VERSION, entry) < 0)
00362     {
00363       printk(KERN_WARNING "RSBAC REG decision module sample 3: Registering failed. Unloading.\n");
00364       if(rsbac_list_detach(&list_handle, listkey))
00365         printk(KERN_WARNING "RSBAC REG decision module sample 3: Unregistering list failed - beware!\n");
00366       return -ENOEXEC;
00367     }
00368 
00369   if(syscall_name)
00370     {
00371       strncpy(syscall_entry.name, syscall_name, RSBAC_REG_NAME_LEN);
00372       syscall_entry.name[RSBAC_REG_NAME_LEN] = 0;
00373     }
00374   else
00375     strcpy(syscall_entry.name, "RSBAC REG sample 3 syscall");
00376   printk(KERN_INFO "RSBAC REG decision module sample 3: REG Version: %u, Name: %s, Dispatcher Handle: %li\n",
00377          RSBAC_REG_VERSION, syscall_entry.name, syscall_dispatcher_handle);
00378 
00379   syscall_entry.registration_handle = syscall_registration_handle;
00380   syscall_entry.dispatcher_handle = syscall_dispatcher_handle;
00381   syscall_entry.syscall_func = syscall_func;
00382 
00383   printk(KERN_INFO "RSBAC REG decision module sample 3: Registering syscall.\n");
00384   syscall_registration_handle = rsbac_reg_register_syscall(RSBAC_REG_VERSION, syscall_entry);
00385   if(syscall_registration_handle < 0)
00386     {
00387       printk(KERN_WARNING "RSBAC REG decision module sample 3: Registering syscall failed. Unloading.\n");
00388       if(rsbac_reg_unregister(handle))
00389         {
00390           printk(KERN_ERR "RSBAC REG decision module sample 3: Unregistering failed - beware of possible system failure!\n");
00391         }
00392       if(rsbac_list_detach(&list_handle, listkey))
00393         printk(KERN_WARNING "RSBAC REG decision module sample 3: Unregistering list failed - beware!\n");
00394       return -ENOEXEC;
00395     }
00396 
00397   #if defined(CONFIG_RSBAC_PROC)
00398   proc_reg_sample_p = create_proc_entry(PROC_NAME,
00399                                         S_IFREG | S_IRUGO,
00400                                         proc_rsbac_root_p);
00401   if(!proc_reg_sample_p)
00402     {
00403       printk(KERN_WARNING "%s: Not loaded due to failed proc entry registering.\n", name);
00404       if(rsbac_reg_unregister_syscall(syscall_registration_handle))
00405         {
00406           printk(KERN_ERR "RSBAC REG decision module sample 3: Unregistering syscall failed - beware of possible system failure!\n");
00407         }
00408       if(rsbac_reg_unregister(handle))
00409         {
00410           printk(KERN_ERR "RSBAC REG decision module sample 3: Unregistering from ADF failed - beware of possible system failure!\n");
00411         }
00412       if(rsbac_list_detach(&list_handle, listkey))
00413         printk(KERN_WARNING "RSBAC REG decision module sample 3: Unregistering list failed - beware!\n");
00414       return -ENOEXEC;
00415     }
00416   proc_reg_sample_p->get_info = adf_sample_proc_info;
00417   #endif 
00418 
00419   printk(KERN_INFO "RSBAC REG decision module sample 3: Loaded.\n");
00420 
00421   return 0;
00422 }
00423 
00424 void cleanup_module(void)
00425 {
00426   printk(KERN_INFO "RSBAC REG decision module sample 3: Unregistering.\n");
00427   #if defined(CONFIG_RSBAC_PROC)
00428   remove_proc_entry(PROC_NAME, proc_rsbac_root_p);
00429   #endif 
00430   if(rsbac_reg_unregister_syscall(syscall_registration_handle))
00431     {
00432       printk(KERN_ERR "RSBAC REG decision module sample 3: Unregistering syscall failed - beware of possible system failure!\n");
00433     }
00434   if(rsbac_reg_unregister(handle))
00435     {
00436       printk(KERN_ERR "RSBAC REG decision module sample 3: Unregistering module failed - beware of possible system failure!\n");
00437     }
00438   if(rsbac_list_detach(&list_handle, listkey))
00439     printk(KERN_WARNING "RSBAC REG decision module sample 3: Unregistering list failed - beware!\n");
00440   printk(KERN_INFO "RSBAC REG decision module sample 3: Unloaded.\n");
00441 }

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