00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <linux/types.h>
00010 #include <linux/sched.h>
00011 #include <linux/mm.h>
00012 #include <linux/init.h>
00013 #include <linux/ext2_fs.h>
00014 #include <asm/uaccess.h>
00015 #include <rsbac/types.h>
00016 #include <rsbac/aci_data_structures.h>
00017 #include <rsbac/mac_data_structures.h>
00018 #include <rsbac/error.h>
00019 #include <rsbac/helpers.h>
00020 #include <rsbac/adf.h>
00021 #include <rsbac/aci.h>
00022 #include <rsbac/lists.h>
00023 #include <rsbac/proc_fs.h>
00024 #include <rsbac/rkmem.h>
00025 #include <rsbac/getname.h>
00026 #include <linux/string.h>
00027 #include <linux/smp_lock.h>
00028
00029
00030
00031
00032
00033 static struct rsbac_mac_device_list_head_t device_list_head;
00034
00035 static rsbac_list_handle_t process_handle = NULL;
00036
00037
00038
00039
00040
00041 rsbac_boolean_t writable(struct super_block *sb_p);
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 static u_int nr_fd_hashes = RSBAC_MAC_NR_TRU_FD_LISTS;
00052
00053
00054
00055
00056 static int mac_register_fd_lists(struct rsbac_mac_device_list_item_t
00057 *device_p, kdev_t kdev)
00058 {
00059 int err = 0;
00060 int tmperr;
00061 struct rsbac_list_lol_info_t lol_info;
00062
00063 if (!device_p)
00064 return (-RSBAC_EINVALIDPOINTER);
00065
00066 lol_info.version = RSBAC_MAC_FD_LIST_VERSION;
00067 lol_info.key = RSBAC_MAC_LIST_KEY;
00068 lol_info.desc_size = sizeof(rsbac_inode_nr_t);
00069 lol_info.data_size = 0;
00070 lol_info.subdesc_size = sizeof(rsbac_uid_t);
00071 lol_info.subdata_size = 0;
00072 lol_info.max_age = 0;
00073 tmperr = rsbac_list_lol_register_hashed(RSBAC_LIST_VERSION,
00074 &device_p->handle,
00075 &lol_info,
00076 RSBAC_LIST_PERSIST |
00077 RSBAC_LIST_DEF_DATA,
00078 NULL,
00079 NULL,
00080 NULL, NULL, NULL, NULL,
00081 RSBAC_MAC_FD_FILENAME, kdev,
00082 nr_fd_hashes,
00083 rsbac_list_hash_fd,
00084 RSBAC_MAC_FD_OLD_FILENAME);
00085 if (tmperr) {
00086 char *tmp;
00087
00088 tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00089 if (tmp) {
00090 rsbac_printk(KERN_WARNING "mac_register_fd_lists(): registering list %s for device %02u:%02u failed with error %s!\n",
00091 RSBAC_MAC_FD_FILENAME,
00092 RSBAC_MAJOR(kdev),
00093 RSBAC_MINOR(kdev),
00094 get_error_name(tmp, tmperr));
00095 rsbac_kfree(tmp);
00096 }
00097 err = tmperr;
00098 }
00099 return err;
00100 }
00101
00102
00103
00104
00105 static int mac_detach_fd_lists(struct rsbac_mac_device_list_item_t
00106 *device_p)
00107 {
00108 int err = 0;
00109
00110 if (!device_p)
00111 return (-RSBAC_EINVALIDPOINTER);
00112
00113 err = rsbac_list_lol_detach(&device_p->handle,
00114 RSBAC_MAC_LIST_KEY);
00115 if (err) {
00116 char *tmp;
00117
00118 tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00119 if (tmp) {
00120 rsbac_printk(KERN_WARNING "mac_detach_fd_lists(): detaching from list %s for device %02u:%02u failed with error %s!\n",
00121 RSBAC_MAC_FD_FILENAME,
00122 RSBAC_MAJOR(device_p->id),
00123 RSBAC_MINOR(device_p->id),
00124 get_error_name(tmp, err));
00125 rsbac_kfree(tmp);
00126 }
00127 }
00128 return err;
00129 }
00130
00131
00132
00133
00134
00135
00136 static struct rsbac_mac_device_list_item_t *lookup_device(kdev_t kdev)
00137 {
00138 struct rsbac_mac_device_list_item_t *curr = device_list_head.curr;
00139
00140
00141 if (!(curr && (RSBAC_MAJOR(curr->id) == RSBAC_MAJOR(kdev))
00142 && (RSBAC_MINOR(curr->id) == RSBAC_MINOR(kdev))
00143 )
00144 ) {
00145 curr = device_list_head.head;
00146 while (curr
00147 && ((RSBAC_MAJOR(curr->id) != RSBAC_MAJOR(kdev))
00148 || (RSBAC_MINOR(curr->id) != RSBAC_MINOR(kdev))
00149 )
00150 ) {
00151 curr = curr->next;
00152 }
00153 if (curr)
00154 device_list_head.curr = curr;
00155 }
00156
00157 return (curr);
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 static struct rsbac_mac_device_list_item_t
00170 *create_device_item(kdev_t kdev)
00171 {
00172 struct rsbac_mac_device_list_item_t *new_item_p;
00173
00174
00175 if (!(new_item_p = (struct rsbac_mac_device_list_item_t *)
00176 rsbac_kmalloc(sizeof(*new_item_p))))
00177 return (NULL);
00178
00179 new_item_p->id = kdev;
00180 new_item_p->mount_count = 1;
00181
00182
00183 new_item_p->handle = NULL;
00184 return (new_item_p);
00185 }
00186
00187
00188 static struct rsbac_mac_device_list_item_t
00189 *add_device_item(struct rsbac_mac_device_list_item_t *device_p)
00190 {
00191 if (!device_p)
00192 return (NULL);
00193
00194
00195 if (!device_list_head.head) {
00196 device_list_head.head = device_p;
00197 device_list_head.tail = device_p;
00198 device_list_head.curr = device_p;
00199 device_list_head.count = 1;
00200 device_p->prev = NULL;
00201 device_p->next = NULL;
00202 } else {
00203 device_p->prev = device_list_head.tail;
00204 device_p->next = NULL;
00205 device_list_head.tail->next = device_p;
00206 device_list_head.tail = device_p;
00207 device_list_head.curr = device_p;
00208 device_list_head.count++;
00209 }
00210 return (device_p);
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220 static void clear_device_item(struct rsbac_mac_device_list_item_t *item_p)
00221 {
00222 if (!item_p)
00223 return;
00224
00225
00226 mac_detach_fd_lists(item_p);
00227
00228 rsbac_kfree(item_p);
00229 }
00230
00231 static void remove_device_item(kdev_t kdev)
00232 {
00233 struct rsbac_mac_device_list_item_t *item_p;
00234
00235
00236 if ((item_p = lookup_device(kdev))) {
00237 if (device_list_head.head == item_p) {
00238 if (device_list_head.tail == item_p) {
00239 device_list_head.head = NULL;
00240 device_list_head.tail = NULL;
00241 } else {
00242 item_p->next->prev = NULL;
00243 device_list_head.head = item_p->next;
00244 }
00245 } else {
00246 if (device_list_head.tail == item_p) {
00247 item_p->prev->next = NULL;
00248 device_list_head.tail = item_p->prev;
00249 } else {
00250 item_p->prev->next = item_p->next;
00251 item_p->next->prev = item_p->prev;
00252 }
00253 }
00254
00255
00256 device_list_head.curr = NULL;
00257
00258 device_list_head.count--;
00259
00260
00261
00262 clear_device_item(item_p);
00263 }
00264
00265 }
00266
00267
00268
00269
00270
00271 static int copy_fp_tru_set_item(struct rsbac_mac_device_list_item_t
00272 *device_p, rsbac_mac_file_t file,
00273 rsbac_pid_t pid)
00274 {
00275 rsbac_uid_t *tru_item_p;
00276 rsbac_time_t *ttl_p;
00277 int i;
00278 long count;
00279 enum rsbac_target_t target = T_FILE;
00280 union rsbac_target_id_t tid;
00281
00282 rsbac_list_lol_remove(process_handle, &pid);
00283 count = rsbac_list_lol_get_all_subdesc_ttl(device_p->handle,
00284 &file.inode,
00285 (void **) &tru_item_p,
00286 &ttl_p);
00287 if (!count || (count == -RSBAC_ENOTFOUND)
00288 ) {
00289 tid.file = file;
00290 if (!rsbac_get_parent(target, tid, &target, &tid))
00291 count =
00292 rsbac_list_lol_get_all_subdesc_ttl(device_p->handle,
00293 &tid.file.
00294 inode,
00295 (void **)
00296 &tru_item_p,
00297 &ttl_p);
00298 }
00299 if (count > 0) {
00300 for (i = 0; i < count; i++) {
00301 rsbac_list_lol_subadd_ttl(process_handle,
00302 ttl_p[i],
00303 &pid,
00304 &tru_item_p[i], NULL);
00305 }
00306 rsbac_vfree(tru_item_p);
00307 rsbac_vfree(ttl_p);
00308 } else {
00309 if ((count < 0)
00310 && (count != -RSBAC_ENOTFOUND)
00311 )
00312 return count;
00313 }
00314
00315 return 0;
00316 }
00317
00318
00319
00320
00321 static int copy_pp_tru_set_item_handle(rsbac_list_handle_t handle,
00322 rsbac_pid_t old_pid,
00323 rsbac_pid_t new_pid)
00324 {
00325 rsbac_uid_t *tru_item_p;
00326 rsbac_time_t *ttl_p;
00327 int i;
00328 long count;
00329
00330 rsbac_list_lol_remove(handle, &new_pid);
00331 count = rsbac_list_lol_get_all_subdesc_ttl(handle,
00332 &old_pid,
00333 (void **) &tru_item_p,
00334 &ttl_p);
00335 if (count > 0) {
00336 for (i = 0; i < count; i++) {
00337 rsbac_list_lol_subadd_ttl(handle,
00338 ttl_p[i],
00339 &new_pid,
00340 &tru_item_p[i], NULL);
00341 }
00342 rsbac_vfree(tru_item_p);
00343 rsbac_vfree(ttl_p);
00344 } else {
00345 if (count < 0)
00346 return count;
00347 }
00348 return 0;
00349 }
00350
00351 static int copy_pp_tru_set_item(rsbac_pid_t old_pid, rsbac_pid_t new_pid)
00352 {
00353 return copy_pp_tru_set_item_handle(process_handle, old_pid,
00354 new_pid);
00355 }
00356
00357
00358
00359
00360
00361 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
00362 static int
00363 mac_devices_proc_info(char *buffer, char **start, off_t offset, int length)
00364 {
00365 int len = 0;
00366 off_t pos = 0;
00367 off_t begin = 0;
00368 struct rsbac_mac_device_list_item_t *device_p;
00369 u_long dflags;
00370
00371 if (!rsbac_is_initialized())
00372 return (-ENOSYS);
00373
00374 len +=
00375 sprintf(buffer, "%u RSBAC MAC Devices\n-------------------\n",
00376 device_list_head.count);
00377
00378
00379 rsbac_read_lock(&device_list_head.lock, &dflags);
00380
00381 for (device_p = device_list_head.head; device_p;
00382 device_p = device_p->next) {
00383 len += sprintf(buffer + len,
00384 "%02u:%02u with mount_count = %u\n",
00385 RSBAC_MAJOR(device_p->id),
00386 RSBAC_MINOR(device_p->id),
00387 device_p->mount_count);
00388 pos = begin + len;
00389 if (pos < offset) {
00390 len = 0;
00391 begin = pos;
00392 }
00393 if (pos > offset + length)
00394 break;
00395 }
00396
00397
00398 rsbac_read_unlock(&device_list_head.lock, &dflags);
00399
00400 *start = buffer + (offset - begin);
00401 len -= (offset - begin);
00402
00403 if (len > length)
00404 len = length;
00405 return len;
00406 }
00407
00408 static int
00409 stats_mac_proc_info(char *buffer, char **start, off_t offset, int length)
00410 {
00411 u_int len = 0;
00412 off_t pos = 0;
00413 off_t begin = 0;
00414
00415 u_long dflags;
00416 struct rsbac_mac_device_list_item_t *device_p;
00417
00418 union rsbac_target_id_t rsbac_target_id;
00419 union rsbac_attribute_value_t rsbac_attribute_value;
00420
00421 if (!rsbac_is_initialized()) {
00422 rsbac_printk(KERN_WARNING "stats_mac_proc_info(): RSBAC not initialized\n");
00423 return (-RSBAC_ENOTINITIALIZED);
00424 }
00425 rsbac_pr_debug(aef_mac, "calling ADF\n");
00426 rsbac_target_id.scd = ST_rsbac;
00427 rsbac_attribute_value.dummy = 0;
00428 if (!rsbac_adf_request(R_GET_STATUS_DATA,
00429 current->pid,
00430 T_SCD,
00431 rsbac_target_id,
00432 A_none, rsbac_attribute_value)) {
00433 return -EPERM;
00434 }
00435
00436 len += sprintf(buffer, "MAC Status\n----------\n");
00437
00438 len +=
00439 sprintf(buffer + len,
00440 "%lu process trusted user set items, sum of %lu members\n",
00441 rsbac_list_lol_count(process_handle),
00442 rsbac_list_lol_all_subcount(process_handle));
00443 pos = begin + len;
00444 if (pos < offset) {
00445 len = 0;
00446 begin = pos;
00447 }
00448 if (pos > offset + length)
00449 goto out;
00450
00451
00452 rsbac_read_lock(&device_list_head.lock, &dflags);
00453 device_p = device_list_head.head;
00454 while (device_p) {
00455
00456 len +=
00457 sprintf(buffer + len,
00458 "device %02u:%02u has %lu file trusted user set items, sum of %lu members\n",
00459 RSBAC_MAJOR(device_p->id),
00460 RSBAC_MINOR(device_p->id),
00461 rsbac_list_lol_count(device_p->handle),
00462 rsbac_list_lol_all_subcount(device_p->handle));
00463 pos = begin + len;
00464 if (pos < offset) {
00465 len = 0;
00466 begin = pos;
00467 }
00468 if (pos > offset + length)
00469 goto out_unlock;
00470
00471 device_p = device_p->next;
00472 }
00473 out_unlock:
00474
00475 rsbac_read_unlock(&device_list_head.lock, &dflags);
00476
00477 out:
00478 *start = buffer + (offset - begin);
00479 len -= (offset - begin);
00480
00481 if (len > length)
00482 len = length;
00483 return len;
00484 }
00485
00486 static int
00487 mac_trulist_proc_info(char *buffer, char **start, off_t offset, int length)
00488 {
00489 u_int len = 0;
00490 off_t pos = 0;
00491 off_t begin = 0;
00492
00493 u_int count = 0;
00494 u_int member_count = 0;
00495 u_long all_member_count;
00496 u_long dflags;
00497 int i, j;
00498 struct rsbac_mac_device_list_item_t *device_p;
00499 rsbac_pid_t *p_list;
00500 rsbac_inode_nr_t *f_list;
00501 rsbac_uid_t *tru_list;
00502
00503 union rsbac_target_id_t rsbac_target_id;
00504 union rsbac_attribute_value_t rsbac_attribute_value;
00505
00506 if (!rsbac_is_initialized()) {
00507 rsbac_printk(KERN_WARNING "mac_trulist_proc_info(): RSBAC not initialized\n");
00508 return (-RSBAC_ENOTINITIALIZED);
00509 }
00510 rsbac_pr_debug(aef_mac, "calling ADF\n");
00511 rsbac_target_id.scd = ST_rsbac;
00512 rsbac_attribute_value.dummy = 0;
00513 if (!rsbac_adf_request(R_GET_STATUS_DATA,
00514 current->pid,
00515 T_SCD,
00516 rsbac_target_id,
00517 A_none, rsbac_attribute_value)) {
00518 return -EPERM;
00519 }
00520
00521 len += sprintf(buffer,
00522 "MAC Trusted User Lists\n---------------------\n");
00523
00524
00525 len +=
00526 sprintf(buffer + len,
00527 "Process trusted user sets:\nset-id count members");
00528 pos = begin + len;
00529 if (pos < offset) {
00530 len = 0;
00531 begin = pos;
00532 }
00533 if (pos > offset + length)
00534 goto out;
00535
00536 all_member_count = 0;
00537 count = rsbac_list_lol_get_all_desc(process_handle,
00538 (void **) &p_list);
00539 if (count > 0) {
00540 for (i = 0; i < count; i++) {
00541 member_count =
00542 rsbac_list_lol_get_all_subdesc(process_handle,
00543 &p_list[i],
00544 (void **)
00545 &tru_list);
00546 len +=
00547 sprintf(buffer + len, "\n %u\t%u\t", p_list[i],
00548 member_count);
00549 if (member_count > 0) {
00550 for (j = 0; j < member_count; j++) {
00551 len += sprintf(buffer + len, "%u ",
00552 tru_list[j]);
00553 pos = begin + len;
00554 if (pos < offset) {
00555 len = 0;
00556 begin = pos;
00557 }
00558 if (pos > offset + length) {
00559 rsbac_vfree(tru_list);
00560 rsbac_vfree(p_list);
00561 goto out;
00562 }
00563 }
00564 rsbac_vfree(tru_list);
00565 all_member_count += member_count;
00566 }
00567 pos = begin + len;
00568 if (pos < offset) {
00569 len = 0;
00570 begin = pos;
00571 }
00572 if (pos > offset + length) {
00573 rsbac_vfree(p_list);
00574 goto out;
00575 }
00576 }
00577 rsbac_vfree(p_list);
00578 }
00579 len +=
00580 sprintf(buffer + len,
00581 "\n%u process trusted user set items, sum of %lu members\n",
00582 count, all_member_count);
00583 pos = begin + len;
00584 if (pos < offset) {
00585 len = 0;
00586 begin = pos;
00587 }
00588 if (pos > offset + length)
00589 goto out;
00590
00591 len +=
00592 sprintf(buffer + len,
00593 "\nFile trusted user sets:\nset-id count members");
00594 pos = begin + len;
00595 if (pos < offset) {
00596 len = 0;
00597 begin = pos;
00598 }
00599 if (pos > offset + length)
00600 goto out;
00601
00602
00603 rsbac_read_lock(&device_list_head.lock, &dflags);
00604 device_p = device_list_head.head;
00605 while (device_p) {
00606
00607 all_member_count = 0;
00608 count = rsbac_list_lol_get_all_desc(device_p->handle,
00609 (void **) &f_list);
00610 if (count > 0) {
00611 for (i = 0; i < count; i++) {
00612 member_count =
00613 rsbac_list_lol_get_all_subdesc
00614 (device_p->handle,
00615 &f_list[i],
00616 (void **) &tru_list);
00617 len +=
00618 sprintf(buffer + len,
00619 "\n %u\t%u\t",
00620 f_list[i],
00621 member_count);
00622 if (member_count > 0) {
00623 for (j = 0;
00624 j < member_count;
00625 j++) {
00626 len +=
00627 sprintf(buffer
00628 + len,
00629 "%u ",
00630 tru_list
00631 [j]);
00632 pos = begin + len;
00633 if (pos < offset) {
00634 len = 0;
00635 begin =
00636 pos;
00637 }
00638 if (pos >
00639 offset +
00640 length) {
00641 rsbac_vfree
00642 (tru_list);
00643 rsbac_vfree
00644 (f_list);
00645 goto out_unlock;
00646 }
00647 }
00648 rsbac_vfree(tru_list);
00649 all_member_count +=
00650 member_count;
00651 }
00652 pos = begin + len;
00653 if (pos < offset) {
00654 len = 0;
00655 begin = pos;
00656 }
00657 if (pos > offset + length) {
00658 rsbac_vfree(f_list);
00659 goto out_unlock;
00660 }
00661 }
00662 rsbac_vfree(f_list);
00663 }
00664 len +=
00665 sprintf(buffer + len,
00666 "\ndevice %02u:%02u has %u file trusted user set items, sum of %lu members\n",
00667 RSBAC_MAJOR(device_p->id),
00668 RSBAC_MINOR(device_p->id), count,
00669 all_member_count);
00670 pos = begin + len;
00671 if (pos < offset) {
00672 len = 0;
00673 begin = pos;
00674 }
00675 if (pos > offset + length)
00676 goto out_unlock;
00677
00678 device_p = device_p->next;
00679 }
00680 out_unlock:
00681
00682 rsbac_read_unlock(&device_list_head.lock, &dflags);
00683
00684 out:
00685 *start = buffer + (offset - begin);
00686 len -= (offset - begin);
00687
00688 if (len > length)
00689 len = length;
00690 return len;
00691 }
00692 #endif
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 #ifdef CONFIG_RSBAC_INIT_DELAY
00710 int rsbac_init_mac(void)
00711 #else
00712 int __init rsbac_init_mac(void)
00713 #endif
00714 {
00715 int err = 0;
00716 struct rsbac_mac_device_list_item_t *device_p = NULL;
00717 u_long dflags;
00718 struct proc_dir_entry *tmp_entry_p;
00719 struct rsbac_list_lol_info_t lol_info;
00720
00721 if (rsbac_is_initialized()) {
00722 rsbac_printk(KERN_WARNING "rsbac_init_mac(): RSBAC already initialized\n");
00723 return (-RSBAC_EREINIT);
00724 }
00725
00726
00727 rsbac_printk(KERN_INFO "rsbac_init_mac(): Initializing RSBAC: MAC subsystem\n");
00728
00729 lol_info.version = RSBAC_MAC_P_LIST_VERSION;
00730 lol_info.key = RSBAC_MAC_LIST_KEY;
00731 lol_info.desc_size = sizeof(rsbac_pid_t);
00732 lol_info.data_size = 0;
00733 lol_info.subdesc_size = sizeof(rsbac_uid_t);
00734 lol_info.subdata_size = 0;
00735 lol_info.max_age = 0;
00736 err = rsbac_list_lol_register(RSBAC_LIST_VERSION,
00737 &process_handle,
00738 &lol_info,
00739 RSBAC_LIST_DEF_DATA,
00740 NULL,
00741 NULL,
00742 NULL,
00743 NULL,
00744 NULL,
00745 NULL,
00746 RSBAC_MAC_P_LIST_NAME,
00747 RSBAC_AUTO_DEV);
00748 if (err) {
00749 char *tmp = rsbac_kmalloc(RSBAC_MAXNAMELEN);
00750
00751 if (tmp) {
00752 rsbac_printk(KERN_WARNING "rsbac_init_mac(): Registering MAC process trusted user list failed with error %s\n",
00753 get_error_name(tmp, err));
00754 rsbac_kfree(tmp);
00755 }
00756 }
00757
00758
00759 device_list_head.lock = RW_LOCK_UNLOCKED;
00760 device_list_head.head = NULL;
00761 device_list_head.tail = NULL;
00762 device_list_head.curr = NULL;
00763 device_list_head.count = 0;
00764
00765
00766 rsbac_pr_debug(ds_mac, "rsbac_init_mac(): Registering FD lists\n");
00767 device_p = create_device_item(rsbac_root_dev);
00768 if (!device_p) {
00769 rsbac_printk(KERN_CRIT
00770 "rsbac_init_mac(): Could not add device!\n");
00771 return (-RSBAC_ECOULDNOTADDDEVICE);
00772 }
00773 if ((err = mac_register_fd_lists(device_p, rsbac_root_dev))) {
00774 char tmp[RSBAC_MAXNAMELEN];
00775
00776 rsbac_printk(KERN_WARNING "rsbac_init_mac(): File/Dir trusted user set registration failed for dev %02u:%02u, err %s!\n",
00777 RSBAC_MAJOR(rsbac_root_dev),
00778 RSBAC_MINOR(rsbac_root_dev),
00779 get_error_name(tmp, err));
00780 }
00781
00782 rsbac_write_lock_irq(&device_list_head.lock, &dflags);
00783 device_p = add_device_item(device_p);
00784
00785 rsbac_write_unlock_irq(&device_list_head.lock, &dflags);
00786 if (!device_p) {
00787 rsbac_printk(KERN_CRIT
00788 "rsbac_init_mac(): Could not add device!\n");
00789 return (-RSBAC_ECOULDNOTADDDEVICE);
00790 }
00791 #if defined(CONFIG_RSBAC_PROC) && defined(CONFIG_PROC_FS)
00792 tmp_entry_p = create_proc_entry("mac_devices",
00793 S_IFREG | S_IRUGO | S_IWUGO,
00794 proc_rsbac_root_p);
00795 if (tmp_entry_p) {
00796 tmp_entry_p->get_info = mac_devices_proc_info;
00797 }
00798 tmp_entry_p = create_proc_entry("stats_mac",
00799 S_IFREG | S_IRUGO,
00800 proc_rsbac_root_p);
00801 if (tmp_entry_p) {
00802 tmp_entry_p->get_info = stats_mac_proc_info;
00803 }
00804 tmp_entry_p = create_proc_entry("mac_trusted",
00805 S_IFREG | S_IRUGO,
00806 proc_rsbac_root_p);
00807 if (tmp_entry_p) {
00808 tmp_entry_p->get_info = mac_trulist_proc_info;
00809 }
00810 #endif
00811
00812 rsbac_pr_debug(aef_mac, "Ready.\n");
00813 return (err);
00814 }
00815
00816 int rsbac_mount_mac(kdev_t kdev)
00817 {
00818 int err = 0;
00819 struct rsbac_mac_device_list_item_t *device_p;
00820 struct rsbac_mac_device_list_item_t *new_device_p;
00821 u_long dflags;
00822
00823 if (!rsbac_is_initialized()) {
00824 rsbac_printk(KERN_WARNING "rsbac_mount_mac(): RSBAC not initialized\n");
00825 return (-RSBAC_ENOTINITIALIZED);
00826 }
00827 rsbac_pr_debug(aef_mac, "mounting device %02u:%02u\n",
00828 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
00829
00830 rsbac_read_lock(&device_list_head.lock, &dflags);
00831 device_p = lookup_device(kdev);
00832
00833 if (device_p) {
00834 rsbac_printk(KERN_WARNING "rsbac_mount_mac: repeated mount %u of device %02u:%02u\n",
00835 device_p->mount_count, RSBAC_MAJOR(kdev),
00836 RSBAC_MINOR(kdev));
00837 device_p->mount_count++;
00838 rsbac_read_unlock(&device_list_head.lock, &dflags);
00839 return 0;
00840 }
00841 rsbac_read_unlock(&device_list_head.lock, &dflags);
00842
00843 new_device_p = create_device_item(kdev);
00844 if (!new_device_p)
00845 return -RSBAC_ECOULDNOTADDDEVICE;
00846
00847
00848 if ((err = mac_register_fd_lists(new_device_p, kdev))) {
00849 char tmp[RSBAC_MAXNAMELEN];
00850
00851 rsbac_printk(KERN_WARNING "rsbac_mount_mac(): File/Dir ACL registration failed for dev %02u:%02u, err %s!\n",
00852 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev),
00853 get_error_name(tmp, err));
00854 }
00855
00856
00857 rsbac_read_lock(&device_list_head.lock, &dflags);
00858
00859 device_p = lookup_device(kdev);
00860 if (device_p) {
00861 rsbac_printk(KERN_WARNING "rsbac_mount_mac(): mount race for device %02u:%02u detected!\n",
00862 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
00863 device_p->mount_count++;
00864 rsbac_read_unlock(&device_list_head.lock, &dflags);
00865 clear_device_item(new_device_p);
00866 } else {
00867 rsbac_read_unlock(&device_list_head.lock, &dflags);
00868 rsbac_write_lock_irq(&device_list_head.lock, &dflags);
00869 device_p = add_device_item(new_device_p);
00870 rsbac_write_unlock_irq(&device_list_head.lock, &dflags);
00871 if (!device_p) {
00872 rsbac_printk(KERN_WARNING "rsbac_mount_mac: adding device %02u:%02u failed!\n",
00873 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
00874 clear_device_item(new_device_p);
00875 err = -RSBAC_ECOULDNOTADDDEVICE;
00876 }
00877 }
00878 return (err);
00879 }
00880
00881
00882
00883 int rsbac_umount_mac(kdev_t kdev)
00884 {
00885 u_long flags;
00886 struct rsbac_mac_device_list_item_t *device_p;
00887
00888 if (!rsbac_is_initialized()) {
00889 rsbac_printk(KERN_WARNING "rsbac_umount(): RSBAC not initialized\n");
00890 return (-RSBAC_ENOTINITIALIZED);
00891 }
00892 rsbac_pr_debug(aef_mac, "umounting device %02u:%02u\n",
00893 RSBAC_MAJOR(kdev), RSBAC_MINOR(kdev));
00894
00895
00896 rsbac_write_lock(&device_list_head.lock, &flags);
00897
00898 device_p = lookup_device(kdev);
00899 if (device_p) {
00900 if (device_p->mount_count == 1)
00901 remove_device_item(kdev);
00902 else {
00903 if (device_p->mount_count > 1) {
00904 device_p->mount_count--;
00905 } else {
00906 rsbac_printk(KERN_WARNING "rsbac_mount_mac: device %02u:%02u has mount_count < 1!\n",
00907 RSBAC_MAJOR(kdev),
00908 RSBAC_MINOR(kdev));
00909 }
00910 }
00911 }
00912
00913
00914 rsbac_write_unlock(&device_list_head.lock, &flags);
00915 return 0;
00916 }
00917
00918
00919
00920
00921 int rsbac_stats_mac(void)
00922 {
00923 u_long dflags;
00924 struct rsbac_mac_device_list_item_t *device_p;
00925
00926 union rsbac_target_id_t rsbac_target_id;
00927 union rsbac_attribute_value_t rsbac_attribute_value;
00928
00929 if (!rsbac_is_initialized()) {
00930 rsbac_printk(KERN_WARNING "rsbac_stats_mac(): RSBAC not initialized\n");
00931 return (-RSBAC_ENOTINITIALIZED);
00932 }
00933 rsbac_pr_debug(aef_mac, "calling ADF\n");
00934 rsbac_target_id.scd = ST_rsbac;
00935 rsbac_attribute_value.dummy = 0;
00936 if (!rsbac_adf_request(R_GET_STATUS_DATA,
00937 current->pid,
00938 T_SCD,
00939 rsbac_target_id,
00940 A_none, rsbac_attribute_value)) {
00941 return -EPERM;
00942 }
00943
00944 rsbac_printk(KERN_INFO "MAC Status\n----------\n");
00945
00946 rsbac_printk(KERN_INFO "%lu process trusted user set items, sum of %lu members\n",
00947 rsbac_list_lol_count(process_handle),
00948 rsbac_list_lol_all_subcount(process_handle));
00949
00950
00951 rsbac_read_lock(&device_list_head.lock, &dflags);
00952 device_p = device_list_head.head;
00953 while (device_p) {
00954 rsbac_printk(KERN_INFO "device %02u:%02u has %u file trusted user set items, sum of %u members\n",
00955 RSBAC_MAJOR(device_p->id),
00956 RSBAC_MINOR(device_p->id),
00957 rsbac_list_lol_count(device_p->handle),
00958 rsbac_list_lol_all_subcount(device_p->handle));
00959 device_p = device_p->next;
00960 }
00961
00962 rsbac_read_unlock(&device_list_head.lock, &dflags);
00963 return 0;
00964 }
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978 int rsbac_mac_add_to_p_truset(rsbac_list_ta_number_t ta_number,
00979 rsbac_pid_t pid,
00980 rsbac_uid_t member, rsbac_time_t ttl)
00981 {
00982 if (!rsbac_is_initialized()) {
00983 rsbac_printk(KERN_WARNING "rsbac_mac_add_to_p_truset(): RSBAC not initialized\n");
00984 return (-RSBAC_ENOTINITIALIZED);
00985 }
00986 if (in_interrupt()) {
00987 rsbac_printk(KERN_WARNING "rsbac_mac_add_to_p_truset(): called from interrupt!\n");
00988 }
00989 return rsbac_ta_list_lol_subadd_ttl(ta_number, process_handle, ttl,
00990 &pid, &member, NULL);
00991 }
00992
00993 int rsbac_mac_add_to_f_truset(rsbac_list_ta_number_t ta_number,
00994 rsbac_mac_file_t file,
00995 rsbac_uid_t member, rsbac_time_t ttl)
00996 {
00997 int err = 0;
00998 u_long dflags;
00999 struct rsbac_mac_device_list_item_t *device_p;
01000
01001 if (!rsbac_is_initialized()) {
01002 rsbac_printk(KERN_WARNING "rsbac_mac_add_to_f_truset(): RSBAC not initialized\n");
01003 return (-RSBAC_ENOTINITIALIZED);
01004 }
01005 if (in_interrupt()) {
01006 rsbac_printk(KERN_WARNING "rsbac_mac_add_to_f_truset(): called from interrupt!\n");
01007 }
01008
01009
01010 rsbac_read_lock(&device_list_head.lock, &dflags);
01011 device_p = lookup_device(file.device);
01012 if (!device_p) {
01013
01014 rsbac_read_unlock(&device_list_head.lock, &dflags);
01015 rsbac_get_super_block(file.device);
01016
01017 rsbac_read_lock(&device_list_head.lock, &dflags);
01018 device_p = lookup_device(file.device);
01019 if (!device_p) {
01020 rsbac_printk(KERN_WARNING "rsbac_mac_add_to_f_truset(): invalid device %02u:%02u!\n",
01021 RSBAC_MAJOR(file.device),
01022 RSBAC_MINOR(file.device));
01023 rsbac_read_unlock(&device_list_head.lock, &dflags);
01024 return (-RSBAC_EINVALIDDEV);
01025 }
01026 }
01027
01028 err = rsbac_ta_list_lol_subadd_ttl(ta_number,
01029 device_p->handle,
01030 ttl, &file.inode, &member,
01031 NULL);
01032 rsbac_read_unlock(&device_list_head.lock, &dflags);
01033 return (err);
01034 }
01035
01036
01037
01038
01039
01040 int rsbac_mac_remove_from_p_truset(rsbac_list_ta_number_t ta_number,
01041 rsbac_pid_t pid, rsbac_uid_t member)
01042 {
01043 if (!rsbac_is_initialized()) {
01044 rsbac_printk(KERN_WARNING "rsbac_mac_remove_from_p_truset(): RSBAC not initialized\n");
01045 return (-RSBAC_ENOTINITIALIZED);
01046 }
01047 if (in_interrupt()) {
01048 rsbac_printk(KERN_WARNING "rsbac_mac_remove_from_p_truset(): called from interrupt!\n");
01049 }
01050 return rsbac_ta_list_lol_subremove(ta_number, process_handle, &pid,
01051 &member);
01052 }
01053
01054 int rsbac_mac_remove_from_f_truset(rsbac_list_ta_number_t ta_number,
01055 rsbac_mac_file_t file,
01056 rsbac_uid_t member)
01057 {
01058 int err = 0;
01059 u_long dflags;
01060 struct rsbac_mac_device_list_item_t *device_p;
01061
01062 if (!rsbac_is_initialized()) {
01063 rsbac_printk(KERN_WARNING "rsbac_mac_remove_from_f_truset(): RSBAC not initialized\n");
01064 return (-RSBAC_ENOTINITIALIZED);
01065 }
01066 if (in_interrupt()) {
01067 rsbac_printk(KERN_WARNING "rsbac_mac_remove_from_f_truset(): called from interrupt!\n");
01068 }
01069
01070
01071 rsbac_read_lock(&device_list_head.lock, &dflags);
01072 device_p = lookup_device(file.device);
01073 if (!device_p) {
01074
01075 rsbac_read_unlock(&device_list_head.lock, &dflags);
01076 rsbac_get_super_block(file.device);
01077
01078 rsbac_read_lock(&device_list_head.lock, &dflags);
01079 device_p = lookup_device(file.device);
01080 if (!device_p) {
01081 rsbac_printk(KERN_WARNING "rsbac_mac_remove_from_f_truset(): invalid device %02u:%02u!\n",
01082 RSBAC_MAJOR(file.device),
01083 RSBAC_MINOR(file.device));
01084 rsbac_read_unlock(&device_list_head.lock, &dflags);
01085 return (-RSBAC_EINVALIDDEV);
01086 }
01087 }
01088 err = rsbac_ta_list_lol_subremove(ta_number,
01089 device_p->handle,
01090 &file.inode, &member);
01091 rsbac_read_unlock(&device_list_head.lock, &dflags);
01092 return (err);
01093 }
01094
01095
01096
01097
01098
01099 int rsbac_mac_clear_p_truset(rsbac_list_ta_number_t ta_number,
01100 rsbac_pid_t pid)
01101 {
01102 if (!rsbac_is_initialized()) {
01103 rsbac_printk(KERN_WARNING "rsbac_mac_clear_p_truset(): RSBAC not initialized\n");
01104 return (-RSBAC_ENOTINITIALIZED);
01105 }
01106 if (in_interrupt()) {
01107 rsbac_printk(KERN_WARNING "rsbac_mac_clear_p_truset(): called from interrupt!\n");
01108 }
01109 return rsbac_ta_list_lol_remove(ta_number, process_handle, &pid);
01110 }
01111
01112 int rsbac_mac_clear_f_truset(rsbac_list_ta_number_t ta_number,
01113 rsbac_mac_file_t file)
01114 {
01115 int err = 0;
01116 u_long dflags;
01117 struct rsbac_mac_device_list_item_t *device_p;
01118
01119 if (!rsbac_is_initialized()) {
01120 rsbac_printk(KERN_WARNING "rsbac_mac_clear_f_truset(): RSBAC not initialized\n");
01121 return (-RSBAC_ENOTINITIALIZED);
01122 }
01123 if (in_interrupt()) {
01124 rsbac_printk(KERN_WARNING "rsbac_mac_clear_f_truset(): called from interrupt!\n");
01125 }
01126
01127 rsbac_read_lock(&device_list_head.lock, &dflags);
01128 device_p = lookup_device(file.device);
01129 if (!device_p) {
01130
01131 rsbac_read_unlock(&device_list_head.lock, &dflags);
01132 rsbac_get_super_block(file.device);
01133
01134 rsbac_read_lock(&device_list_head.lock, &dflags);
01135 device_p = lookup_device(file.device);
01136 if (!device_p) {
01137 rsbac_printk(KERN_WARNING "rsbac_mac_clear_f_truset(): invalid device %02u:%02u!\n",
01138 RSBAC_MAJOR(file.device),
01139 RSBAC_MINOR(file.device));
01140 rsbac_read_unlock(&device_list_head.lock, &dflags);
01141 return (-RSBAC_EINVALIDDEV);
01142 }
01143 }
01144 err = rsbac_ta_list_lol_remove(ta_number,
01145 device_p->handle,
01146 &file.inode);
01147 rsbac_read_unlock(&device_list_head.lock, &dflags);
01148 return (err);
01149 }
01150
01151
01152
01153
01154 rsbac_boolean_t rsbac_mac_p_truset_member(rsbac_pid_t pid,
01155 rsbac_uid_t member)
01156 {
01157 if (!rsbac_is_initialized()) {
01158 rsbac_printk(KERN_WARNING "rsbac_mac_p_truset_member(): RSBAC not initialized\n");
01159 return FALSE;
01160 }
01161 if (in_interrupt()) {
01162 rsbac_printk(KERN_WARNING "rsbac_mac_p_truset_member(): called from interrupt!\n");
01163 }
01164 if (rsbac_list_lol_subexist(process_handle, &pid, &member))
01165 return TRUE;
01166 member = RSBAC_ALL_USERS;
01167 return rsbac_list_lol_subexist(process_handle, &pid, &member);
01168 }
01169
01170
01171
01172
01173
01174 int rsbac_mac_remove_p_trusets(rsbac_pid_t pid)
01175 {
01176 return rsbac_mac_clear_p_truset(FALSE, pid);
01177 }
01178
01179 int rsbac_mac_remove_f_trusets(rsbac_mac_file_t file)
01180 {
01181 return rsbac_mac_clear_f_truset(FALSE, file);
01182 }
01183
01184 int rsbac_mac_copy_fp_truset(rsbac_mac_file_t file,
01185 rsbac_pid_t p_tru_set_id)
01186 {
01187 u_long dflags;
01188 struct rsbac_mac_device_list_item_t *device_p;
01189 int err = 0;
01190
01191 if (!rsbac_is_initialized()) {
01192 rsbac_printk(KERN_WARNING "rsbac_mac_copy_fp_truset(): RSBAC not initialized\n");
01193 return (-RSBAC_ENOTINITIALIZED);
01194 }
01195 if (in_interrupt()) {
01196 rsbac_printk(KERN_WARNING "rsbac_mac_copy_fp_truset(): called from interrupt!\n");
01197 }
01198
01199
01200
01201
01202 rsbac_read_lock(&device_list_head.lock, &dflags);
01203 device_p = lookup_device(file.device);
01204 if (!device_p) {
01205
01206 rsbac_read_unlock(&device_list_head.lock, &dflags);
01207 rsbac_get_super_block(file.device);
01208
01209 rsbac_read_lock(&device_list_head.lock, &dflags);
01210 device_p = lookup_device(file.device);
01211 if (!device_p) {
01212 rsbac_printk(KERN_WARNING "rsbac_mac_copy_fp_truset(): invalid device %02u:%02u!\n",
01213 RSBAC_MAJOR(file.device),
01214 RSBAC_MINOR(file.device));
01215 rsbac_read_unlock(&device_list_head.lock, &dflags);
01216 return (-RSBAC_EINVALIDDEV);
01217 }
01218 }
01219
01220 err = copy_fp_tru_set_item(device_p, file, p_tru_set_id);
01221 rsbac_read_unlock(&device_list_head.lock, &dflags);
01222 return (err);
01223 }
01224
01225 int rsbac_mac_copy_pp_truset(rsbac_pid_t old_p_set_id,
01226 rsbac_pid_t new_p_set_id)
01227 {
01228 if (!rsbac_is_initialized()) {
01229 rsbac_printk(KERN_WARNING "rsbac_mac_copy_pp_truset(): RSBAC not initialized\n");
01230 return (-RSBAC_ENOTINITIALIZED);
01231 }
01232 if (in_interrupt()) {
01233 rsbac_printk(KERN_WARNING "rsbac_mac_copy_pp_truset(): called from interrupt!\n");
01234 }
01235
01236
01237
01238
01239 return copy_pp_tru_set_item(old_p_set_id, new_p_set_id);
01240 }
01241
01242 int rsbac_mac_get_f_trulist(rsbac_list_ta_number_t ta_number,
01243 rsbac_mac_file_t file,
01244 rsbac_uid_t ** trulist_p,
01245 rsbac_time_t ** ttllist_p)
01246 {
01247 u_long dflags;
01248 struct rsbac_mac_device_list_item_t *device_p;
01249 long count;
01250
01251 if (!rsbac_is_initialized()) {
01252 rsbac_printk(KERN_WARNING "rsbac_mac_get_f_trulist(): RSBAC not initialized\n");
01253 return (-RSBAC_ENOTINITIALIZED);
01254 }
01255 if (in_interrupt()) {
01256 rsbac_printk(KERN_WARNING "rsbac_mac_get_f_trulist(): called from interrupt!\n");
01257 }
01258
01259
01260
01261
01262 rsbac_read_lock(&device_list_head.lock, &dflags);
01263 device_p = lookup_device(file.device);
01264 if (!device_p) {
01265
01266 rsbac_read_unlock(&device_list_head.lock, &dflags);
01267 rsbac_get_super_block(file.device);
01268
01269 rsbac_read_lock(&device_list_head.lock, &dflags);
01270 device_p = lookup_device(file.device);
01271 if (!device_p) {
01272 rsbac_printk(KERN_WARNING "rsbac_mac_get_f_trulist(): invalid device %02u:%02u!\n",
01273 RSBAC_MAJOR(file.device),
01274 RSBAC_MINOR(file.device));
01275 rsbac_read_unlock(&device_list_head.lock, &dflags);
01276 return (-RSBAC_EINVALIDDEV);
01277 }
01278 }
01279 count = rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
01280 device_p->handle,
01281 &file.inode,
01282 (void **) trulist_p,
01283 ttllist_p);
01284 rsbac_read_unlock(&device_list_head.lock, &dflags);
01285 return (count);
01286 }
01287
01288 int rsbac_mac_get_p_trulist(rsbac_list_ta_number_t ta_number,
01289 rsbac_pid_t pid,
01290 rsbac_uid_t ** trulist_p,
01291 rsbac_time_t ** ttllist_p)
01292 {
01293 if (!rsbac_is_initialized()) {
01294 rsbac_printk(KERN_WARNING "rsbac_mac_get_p_trulist(): RSBAC not initialized\n");
01295 return (-RSBAC_ENOTINITIALIZED);
01296 }
01297 if (in_interrupt()) {
01298 rsbac_printk(KERN_WARNING "rsbac_mac_get_p_trulist(): called from interrupt!\n");
01299 }
01300
01301
01302
01303 return rsbac_ta_list_lol_get_all_subdesc_ttl(ta_number,
01304 process_handle,
01305 &pid,
01306 (void **) trulist_p,
01307 ttllist_p);
01308 }