00001
00002
00003
00004
00005
00006
00007
00008
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
00015 #include <linux/sched.h>
00016 #include <linux/smp.h>
00017 #include <linux/smp_lock.h>
00018
00019 #include <linux/fs.h>
00020 #include <asm/uaccess.h>
00021
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
00058 #define FILENAME "regsmp2"
00059
00060
00061 #define FILE_VERSION 1
00062
00063
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
00163
00164
00165
00166
00167
00168
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
00181 strcpy(name, FILENAME);
00182
00183
00184 if ((err = rsbac_read_open(name,
00185 &file,
00186 rsbac_root_dev) ))
00187 return(err);
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
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
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
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
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
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
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
00269
00270 set_fs(oldfs);
00271
00272
00273 rsbac_read_close(&file);
00274
00275
00276 return(err);
00277 };
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
00289 strcpy(name, FILENAME);
00290
00291
00292 down(&rsbac_write_sem);
00293
00294
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
00304
00305
00306
00307
00308
00309
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
00367
00368 set_fs(oldfs);
00369
00370
00371 rsbac_write_close(&file);
00372 up(&rsbac_write_sem);
00373 return(err);
00374 };
00375
00376
00377
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
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
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
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
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 }