/daten/src/linux-2.4.27-rsbac-v1.2.3/rsbac/adf/reg/reg_sample2.c

Go to the documentation of this file.
00001 /* 00002 * RSBAC REG decision module sample 00003 * 00004 * Author and (c) 1999-2001 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/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 boolean 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 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 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 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 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 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 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 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 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 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 boolean need_overwrite_func (struct dentry * dentry_p) 00409 { 00410 nr_need_overwrite_calls++; 00411 return FALSE; 00412 } 00413 00414 static int write_func(boolean 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 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 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 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 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 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 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 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 printk(KERN_WARNING "RSBAC REG decision module sample 2: Registering syscall failed. Unloading.\n"); 00505 if(rsbac_reg_unregister(handle)) 00506 { 00507 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 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 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 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 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 printk(KERN_INFO "RSBAC REG decision module sample 2: Loaded.\n"); 00539 00540 return 0; 00541 } 00542 00543 void cleanup_module(void) 00544 { 00545 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 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 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 printk(KERN_ERR "RSBAC REG decision module sample 2: Unregistering module failed - beware of possible system failure!\n"); 00561 } 00562 printk(KERN_INFO "RSBAC REG decision module sample 2: Unloaded.\n"); 00563 }

Generated on Tue Aug 31 10:05:24 2004 for RSBAC by doxygen 1.3.8