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