1eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/* 2eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * security/tomoyo/audit.c 3eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 40f2a55d5bb2372058275b0b343d90dd5d640d045Tetsuo Handa * Copyright (C) 2005-2011 NTT DATA CORPORATION 5eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */ 6eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 7eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa#include "common.h" 8eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa#include <linux/slab.h> 9eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 10eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/** 115b636857fee642694e287e3a181b523b16098c93Tetsuo Handa * tomoyo_print_bprm - Print "struct linux_binprm" for auditing. 125b636857fee642694e287e3a181b523b16098c93Tetsuo Handa * 135b636857fee642694e287e3a181b523b16098c93Tetsuo Handa * @bprm: Pointer to "struct linux_binprm". 145b636857fee642694e287e3a181b523b16098c93Tetsuo Handa * @dump: Pointer to "struct tomoyo_page_dump". 155b636857fee642694e287e3a181b523b16098c93Tetsuo Handa * 165b636857fee642694e287e3a181b523b16098c93Tetsuo Handa * Returns the contents of @bprm on success, NULL otherwise. 175b636857fee642694e287e3a181b523b16098c93Tetsuo Handa * 185b636857fee642694e287e3a181b523b16098c93Tetsuo Handa * This function uses kzalloc(), so caller must kfree() if this function 195b636857fee642694e287e3a181b523b16098c93Tetsuo Handa * didn't return NULL. 205b636857fee642694e287e3a181b523b16098c93Tetsuo Handa */ 215b636857fee642694e287e3a181b523b16098c93Tetsuo Handastatic char *tomoyo_print_bprm(struct linux_binprm *bprm, 225b636857fee642694e287e3a181b523b16098c93Tetsuo Handa struct tomoyo_page_dump *dump) 235b636857fee642694e287e3a181b523b16098c93Tetsuo Handa{ 245b636857fee642694e287e3a181b523b16098c93Tetsuo Handa static const int tomoyo_buffer_len = 4096 * 2; 255b636857fee642694e287e3a181b523b16098c93Tetsuo Handa char *buffer = kzalloc(tomoyo_buffer_len, GFP_NOFS); 265b636857fee642694e287e3a181b523b16098c93Tetsuo Handa char *cp; 275b636857fee642694e287e3a181b523b16098c93Tetsuo Handa char *last_start; 285b636857fee642694e287e3a181b523b16098c93Tetsuo Handa int len; 295b636857fee642694e287e3a181b523b16098c93Tetsuo Handa unsigned long pos = bprm->p; 305b636857fee642694e287e3a181b523b16098c93Tetsuo Handa int offset = pos % PAGE_SIZE; 315b636857fee642694e287e3a181b523b16098c93Tetsuo Handa int argv_count = bprm->argc; 325b636857fee642694e287e3a181b523b16098c93Tetsuo Handa int envp_count = bprm->envc; 335b636857fee642694e287e3a181b523b16098c93Tetsuo Handa bool truncated = false; 345b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (!buffer) 355b636857fee642694e287e3a181b523b16098c93Tetsuo Handa return NULL; 365b636857fee642694e287e3a181b523b16098c93Tetsuo Handa len = snprintf(buffer, tomoyo_buffer_len - 1, "argv[]={ "); 375b636857fee642694e287e3a181b523b16098c93Tetsuo Handa cp = buffer + len; 385b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (!argv_count) { 395b636857fee642694e287e3a181b523b16098c93Tetsuo Handa memmove(cp, "} envp[]={ ", 11); 405b636857fee642694e287e3a181b523b16098c93Tetsuo Handa cp += 11; 415b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } 425b636857fee642694e287e3a181b523b16098c93Tetsuo Handa last_start = cp; 435b636857fee642694e287e3a181b523b16098c93Tetsuo Handa while (argv_count || envp_count) { 445b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (!tomoyo_dump_page(bprm, pos, dump)) 455b636857fee642694e287e3a181b523b16098c93Tetsuo Handa goto out; 465b636857fee642694e287e3a181b523b16098c93Tetsuo Handa pos += PAGE_SIZE - offset; 475b636857fee642694e287e3a181b523b16098c93Tetsuo Handa /* Read. */ 485b636857fee642694e287e3a181b523b16098c93Tetsuo Handa while (offset < PAGE_SIZE) { 495b636857fee642694e287e3a181b523b16098c93Tetsuo Handa const char *kaddr = dump->data; 505b636857fee642694e287e3a181b523b16098c93Tetsuo Handa const unsigned char c = kaddr[offset++]; 515b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (cp == last_start) 525b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp++ = '"'; 535b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (cp >= buffer + tomoyo_buffer_len - 32) { 545b636857fee642694e287e3a181b523b16098c93Tetsuo Handa /* Reserve some room for "..." string. */ 555b636857fee642694e287e3a181b523b16098c93Tetsuo Handa truncated = true; 565b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } else if (c == '\\') { 575b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp++ = '\\'; 585b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp++ = '\\'; 595b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } else if (c > ' ' && c < 127) { 605b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp++ = c; 615b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } else if (!c) { 625b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp++ = '"'; 635b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp++ = ' '; 645b636857fee642694e287e3a181b523b16098c93Tetsuo Handa last_start = cp; 655b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } else { 665b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp++ = '\\'; 675b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp++ = (c >> 6) + '0'; 685b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp++ = ((c >> 3) & 7) + '0'; 695b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp++ = (c & 7) + '0'; 705b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } 715b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (c) 725b636857fee642694e287e3a181b523b16098c93Tetsuo Handa continue; 735b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (argv_count) { 745b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (--argv_count == 0) { 755b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (truncated) { 765b636857fee642694e287e3a181b523b16098c93Tetsuo Handa cp = last_start; 775b636857fee642694e287e3a181b523b16098c93Tetsuo Handa memmove(cp, "... ", 4); 785b636857fee642694e287e3a181b523b16098c93Tetsuo Handa cp += 4; 795b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } 805b636857fee642694e287e3a181b523b16098c93Tetsuo Handa memmove(cp, "} envp[]={ ", 11); 815b636857fee642694e287e3a181b523b16098c93Tetsuo Handa cp += 11; 825b636857fee642694e287e3a181b523b16098c93Tetsuo Handa last_start = cp; 835b636857fee642694e287e3a181b523b16098c93Tetsuo Handa truncated = false; 845b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } 855b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } else if (envp_count) { 865b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (--envp_count == 0) { 875b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (truncated) { 885b636857fee642694e287e3a181b523b16098c93Tetsuo Handa cp = last_start; 895b636857fee642694e287e3a181b523b16098c93Tetsuo Handa memmove(cp, "... ", 4); 905b636857fee642694e287e3a181b523b16098c93Tetsuo Handa cp += 4; 915b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } 925b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } 935b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } 945b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (!argv_count && !envp_count) 955b636857fee642694e287e3a181b523b16098c93Tetsuo Handa break; 965b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } 975b636857fee642694e287e3a181b523b16098c93Tetsuo Handa offset = 0; 985b636857fee642694e287e3a181b523b16098c93Tetsuo Handa } 995b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp++ = '}'; 1005b636857fee642694e287e3a181b523b16098c93Tetsuo Handa *cp = '\0'; 1015b636857fee642694e287e3a181b523b16098c93Tetsuo Handa return buffer; 1025b636857fee642694e287e3a181b523b16098c93Tetsuo Handaout: 1035b636857fee642694e287e3a181b523b16098c93Tetsuo Handa snprintf(buffer, tomoyo_buffer_len - 1, 1045b636857fee642694e287e3a181b523b16098c93Tetsuo Handa "argv[]={ ... } envp[]= { ... }"); 1055b636857fee642694e287e3a181b523b16098c93Tetsuo Handa return buffer; 1065b636857fee642694e287e3a181b523b16098c93Tetsuo Handa} 1075b636857fee642694e287e3a181b523b16098c93Tetsuo Handa 1085b636857fee642694e287e3a181b523b16098c93Tetsuo Handa/** 1098761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa * tomoyo_filetype - Get string representation of file type. 1108761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa * 1118761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa * @mode: Mode value for stat(). 1128761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa * 1138761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa * Returns file type string. 1148761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa */ 115d179333f37d33533f4c77118f757b9e7835ccb7cAl Virostatic inline const char *tomoyo_filetype(const umode_t mode) 1168761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa{ 1178761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa switch (mode & S_IFMT) { 1188761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa case S_IFREG: 1198761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa case 0: 1208761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FILE]; 1218761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa case S_IFDIR: 1228761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa return tomoyo_condition_keyword[TOMOYO_TYPE_IS_DIRECTORY]; 1238761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa case S_IFLNK: 1248761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SYMLINK]; 1258761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa case S_IFIFO: 1268761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FIFO]; 1278761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa case S_IFSOCK: 1288761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SOCKET]; 1298761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa case S_IFBLK: 1308761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa return tomoyo_condition_keyword[TOMOYO_TYPE_IS_BLOCK_DEV]; 1318761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa case S_IFCHR: 1328761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa return tomoyo_condition_keyword[TOMOYO_TYPE_IS_CHAR_DEV]; 1338761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa } 1348761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa return "unknown"; /* This should not happen. */ 1358761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa} 1368761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa 1378761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa/** 138eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_print_header - Get header line of audit log. 139eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 140eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @r: Pointer to "struct tomoyo_request_info". 141eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 142eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns string representation. 143eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 144eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * This function uses kmalloc(), so caller must kfree() if this function 145eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * didn't return NULL. 146eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */ 147eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastatic char *tomoyo_print_header(struct tomoyo_request_info *r) 148eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{ 149eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa struct tomoyo_time stamp; 150eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa const pid_t gpid = task_pid_nr(current); 1518761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa struct tomoyo_obj_info *obj = r->obj; 152eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa static const int tomoyo_buffer_len = 4096; 153eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS); 1542066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa int pos; 1558761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa u8 i; 156eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (!buffer) 157eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return NULL; 15877f4fa089c724adc3a87c10eb031bca91b144ac0Thomas Gleixner 15977f4fa089c724adc3a87c10eb031bca91b144ac0Thomas Gleixner tomoyo_convert_time(get_seconds(), &stamp); 16077f4fa089c724adc3a87c10eb031bca91b144ac0Thomas Gleixner 1612066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa pos = snprintf(buffer, tomoyo_buffer_len - 1, 1622066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s " 1632066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa "granted=%s (global-pid=%u) task={ pid=%u ppid=%u " 1642066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u " 1652066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa "fsuid=%u fsgid=%u }", stamp.year, stamp.month, 1662066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile, 1672066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid, 1682066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa tomoyo_sys_getpid(), tomoyo_sys_getppid(), 169609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kuid(&init_user_ns, current_uid()), 170609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kgid(&init_user_ns, current_gid()), 171609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kuid(&init_user_ns, current_euid()), 172609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kgid(&init_user_ns, current_egid()), 173609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kuid(&init_user_ns, current_suid()), 174609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kgid(&init_user_ns, current_sgid()), 175609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kuid(&init_user_ns, current_fsuid()), 176609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kgid(&init_user_ns, current_fsgid())); 1778761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa if (!obj) 1788761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa goto no_obj_info; 1798761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa if (!obj->validate_done) { 1808761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa tomoyo_get_attributes(obj); 1818761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa obj->validate_done = true; 1828761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa } 1838761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) { 1848761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa struct tomoyo_mini_stat *stat; 1858761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa unsigned int dev; 186d179333f37d33533f4c77118f757b9e7835ccb7cAl Viro umode_t mode; 1878761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa if (!obj->stat_valid[i]) 1888761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa continue; 1898761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa stat = &obj->stat[i]; 1908761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa dev = stat->dev; 1918761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa mode = stat->mode; 1928761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa if (i & 1) { 1938761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa pos += snprintf(buffer + pos, 1948761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa tomoyo_buffer_len - 1 - pos, 1958761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa " path%u.parent={ uid=%u gid=%u " 1968761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa "ino=%lu perm=0%o }", (i >> 1) + 1, 197609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kuid(&init_user_ns, stat->uid), 198609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kgid(&init_user_ns, stat->gid), 199609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman (unsigned long)stat->ino, 200609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman stat->mode & S_IALLUGO); 2018761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa continue; 2028761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa } 2038761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos, 2048761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa " path%u={ uid=%u gid=%u ino=%lu major=%u" 2058761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa " minor=%u perm=0%o type=%s", (i >> 1) + 1, 206609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kuid(&init_user_ns, stat->uid), 207609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman from_kgid(&init_user_ns, stat->gid), 208609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman (unsigned long)stat->ino, 209609fcd1b3a55f99667c61609895c83019b21baadEric W. Biederman MAJOR(dev), MINOR(dev), 2108761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa mode & S_IALLUGO, tomoyo_filetype(mode)); 2118761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa if (S_ISCHR(mode) || S_ISBLK(mode)) { 2128761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa dev = stat->rdev; 2138761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa pos += snprintf(buffer + pos, 2148761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa tomoyo_buffer_len - 1 - pos, 2158761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa " dev_major=%u dev_minor=%u", 2168761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa MAJOR(dev), MINOR(dev)); 2178761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa } 2188761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos, 2198761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa " }"); 2208761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa } 2218761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handano_obj_info: 2222066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa if (pos < tomoyo_buffer_len - 1) 2232066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa return buffer; 2242066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa kfree(buffer); 2252066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa return NULL; 226eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa} 227eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 228eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/** 229eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_init_log - Allocate buffer for audit logs. 230eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 231eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @r: Pointer to "struct tomoyo_request_info". 232eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @len: Buffer size needed for @fmt and @args. 233eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @fmt: The printf()'s format string. 234eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @args: va_list structure for @fmt. 235eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 236eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns pointer to allocated memory. 237eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 238eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * This function uses kzalloc(), so caller must kfree() if this function 239eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * didn't return NULL. 240eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */ 241eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handachar *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt, 242eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa va_list args) 243eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{ 244eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa char *buf = NULL; 2455b636857fee642694e287e3a181b523b16098c93Tetsuo Handa char *bprm_info = NULL; 246eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa const char *header = NULL; 2472ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa char *realpath = NULL; 2482ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa const char *symlink = NULL; 249eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa int pos; 250ea504819122a76a236f8b95d1556f807a0a41397Tetsuo Handa const char *domainname = r->domain->domainname->name; 251eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa header = tomoyo_print_header(r); 252eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (!header) 253eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return NULL; 254eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa /* +10 is for '\n' etc. and '\0'. */ 255eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa len += strlen(domainname) + strlen(header) + 10; 2562ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa if (r->ee) { 2572ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa struct file *file = r->ee->bprm->file; 2582ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa realpath = tomoyo_realpath_from_path(&file->f_path); 2595b636857fee642694e287e3a181b523b16098c93Tetsuo Handa bprm_info = tomoyo_print_bprm(r->ee->bprm, &r->ee->dump); 2605b636857fee642694e287e3a181b523b16098c93Tetsuo Handa if (!realpath || !bprm_info) 2612ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa goto out; 2625b636857fee642694e287e3a181b523b16098c93Tetsuo Handa /* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */ 2635b636857fee642694e287e3a181b523b16098c93Tetsuo Handa len += strlen(realpath) + 80 + strlen(bprm_info); 2642ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa } else if (r->obj && r->obj->symlink_target) { 2652ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa symlink = r->obj->symlink_target->name; 2662ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa /* +18 is for " symlink.target=\"%s\"" */ 2672ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa len += 18 + strlen(symlink); 2682ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa } 269eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa len = tomoyo_round2(len); 270eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa buf = kzalloc(len, GFP_NOFS); 271eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (!buf) 272eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa goto out; 273eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa len--; 274eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa pos = snprintf(buf, len, "%s", header); 2752ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa if (realpath) { 2765b636857fee642694e287e3a181b523b16098c93Tetsuo Handa struct linux_binprm *bprm = r->ee->bprm; 2772ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa pos += snprintf(buf + pos, len - pos, 2785b636857fee642694e287e3a181b523b16098c93Tetsuo Handa " exec={ realpath=\"%s\" argc=%d envc=%d %s }", 2795b636857fee642694e287e3a181b523b16098c93Tetsuo Handa realpath, bprm->argc, bprm->envc, bprm_info); 2802ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa } else if (symlink) 2812ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"", 2822ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa symlink); 283eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname); 284eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa vsnprintf(buf + pos, len - pos, fmt, args); 285eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handaout: 2862ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563Tetsuo Handa kfree(realpath); 2875b636857fee642694e287e3a181b523b16098c93Tetsuo Handa kfree(bprm_info); 288eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa kfree(header); 289eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return buf; 290eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa} 291eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 292eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/* Wait queue for /sys/kernel/security/tomoyo/audit. */ 293eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastatic DECLARE_WAIT_QUEUE_HEAD(tomoyo_log_wait); 294eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 295eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/* Structure for audit log. */ 296eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastruct tomoyo_log { 297eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa struct list_head list; 298eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa char *log; 299eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa int size; 300eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa}; 301eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 302eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/* The list for "struct tomoyo_log". */ 303eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastatic LIST_HEAD(tomoyo_log); 304eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 305eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/* Lock for "struct list_head tomoyo_log". */ 306eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastatic DEFINE_SPINLOCK(tomoyo_log_lock); 307eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 308eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/* Length of "stuct list_head tomoyo_log". */ 309eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastatic unsigned int tomoyo_log_count; 310eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 311eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/** 312eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_get_audit - Get audit mode. 313eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 314bd03a3e4c9a9df0c6b007045fa7fc8889111a478Tetsuo Handa * @ns: Pointer to "struct tomoyo_policy_namespace". 315eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @profile: Profile number. 316eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @index: Index number of functionality. 317eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @is_granted: True if granted log, false otherwise. 318eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 319eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns true if this request should be audited, false otherwise. 320eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */ 321bd03a3e4c9a9df0c6b007045fa7fc8889111a478Tetsuo Handastatic bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns, 322bd03a3e4c9a9df0c6b007045fa7fc8889111a478Tetsuo Handa const u8 profile, const u8 index, 3231f067a682a9bd252107ac6f6946b7332fde42344Tetsuo Handa const struct tomoyo_acl_info *matched_acl, 324eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa const bool is_granted) 325eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{ 326eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa u8 mode; 3272c47ab9353242b0f061959318f83c55360b88fa4Tetsuo Handa const u8 category = tomoyo_index2category[index] + 3282c47ab9353242b0f061959318f83c55360b88fa4Tetsuo Handa TOMOYO_MAX_MAC_INDEX; 329eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa struct tomoyo_profile *p; 330eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (!tomoyo_policy_loaded) 331eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return false; 332bd03a3e4c9a9df0c6b007045fa7fc8889111a478Tetsuo Handa p = tomoyo_profile(ns, profile); 333eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG]) 334eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return false; 3351f067a682a9bd252107ac6f6946b7332fde42344Tetsuo Handa if (is_granted && matched_acl && matched_acl->cond && 3361f067a682a9bd252107ac6f6946b7332fde42344Tetsuo Handa matched_acl->cond->grant_log != TOMOYO_GRANTLOG_AUTO) 3371f067a682a9bd252107ac6f6946b7332fde42344Tetsuo Handa return matched_acl->cond->grant_log == TOMOYO_GRANTLOG_YES; 338eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa mode = p->config[index]; 339eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (mode == TOMOYO_CONFIG_USE_DEFAULT) 340eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa mode = p->config[category]; 341eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (mode == TOMOYO_CONFIG_USE_DEFAULT) 342eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa mode = p->default_config; 343eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (is_granted) 344eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return mode & TOMOYO_CONFIG_WANT_GRANT_LOG; 345eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return mode & TOMOYO_CONFIG_WANT_REJECT_LOG; 346eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa} 347eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 348eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/** 349eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_write_log2 - Write an audit log. 350eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 351eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @r: Pointer to "struct tomoyo_request_info". 352eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @len: Buffer size needed for @fmt and @args. 353eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @fmt: The printf()'s format string. 354eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @args: va_list structure for @fmt. 355eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 356eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns nothing. 357eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */ 358eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handavoid tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt, 359eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa va_list args) 360eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{ 361eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa char *buf; 362eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa struct tomoyo_log *entry; 363eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa bool quota_exceeded = false; 3641f067a682a9bd252107ac6f6946b7332fde42344Tetsuo Handa if (!tomoyo_get_audit(r->domain->ns, r->profile, r->type, 3651f067a682a9bd252107ac6f6946b7332fde42344Tetsuo Handa r->matched_acl, r->granted)) 366eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa goto out; 367eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa buf = tomoyo_init_log(r, len, fmt, args); 368eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (!buf) 369eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa goto out; 370eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa entry = kzalloc(sizeof(*entry), GFP_NOFS); 371eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (!entry) { 372eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa kfree(buf); 373eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa goto out; 374eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa } 375eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa entry->log = buf; 376eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa len = tomoyo_round2(strlen(buf) + 1); 377eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa /* 378eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * The entry->size is used for memory quota checks. 379eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Don't go beyond strlen(entry->log). 380eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */ 381eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa entry->size = len + tomoyo_round2(sizeof(*entry)); 382eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa spin_lock(&tomoyo_log_lock); 383eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT] && 384eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] + entry->size >= 385eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT]) { 386eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa quota_exceeded = true; 387eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa } else { 388eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] += entry->size; 389eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa list_add_tail(&entry->list, &tomoyo_log); 390eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa tomoyo_log_count++; 391eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa } 392eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa spin_unlock(&tomoyo_log_lock); 393eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (quota_exceeded) { 394eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa kfree(buf); 395eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa kfree(entry); 396eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa goto out; 397eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa } 398eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa wake_up(&tomoyo_log_wait); 399eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handaout: 400eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return; 401eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa} 402eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 403eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/** 404eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_write_log - Write an audit log. 405eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 406eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @r: Pointer to "struct tomoyo_request_info". 407eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @fmt: The printf()'s format string, followed by parameters. 408eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 409eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns nothing. 410eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */ 411eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handavoid tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...) 412eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{ 413eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa va_list args; 414eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa int len; 415eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa va_start(args, fmt); 416eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa len = vsnprintf((char *) &len, 1, fmt, args) + 1; 417eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa va_end(args); 418eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa va_start(args, fmt); 419eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa tomoyo_write_log2(r, len, fmt, args); 420eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa va_end(args); 421eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa} 422eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 423eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/** 424eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_read_log - Read an audit log. 425eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 426eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @head: Pointer to "struct tomoyo_io_buffer". 427eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 428eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns nothing. 429eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */ 430eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handavoid tomoyo_read_log(struct tomoyo_io_buffer *head) 431eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{ 432eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa struct tomoyo_log *ptr = NULL; 433eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (head->r.w_pos) 434eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return; 435eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa kfree(head->read_buf); 436eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa head->read_buf = NULL; 437eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa spin_lock(&tomoyo_log_lock); 438eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (!list_empty(&tomoyo_log)) { 439eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa ptr = list_entry(tomoyo_log.next, typeof(*ptr), list); 440eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa list_del(&ptr->list); 441eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa tomoyo_log_count--; 442eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] -= ptr->size; 443eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa } 444eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa spin_unlock(&tomoyo_log_lock); 445eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (ptr) { 446eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa head->read_buf = ptr->log; 447eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa head->r.w[head->r.w_pos++] = head->read_buf; 448eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa kfree(ptr); 449eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa } 450eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa} 451eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa 452eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/** 453eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_poll_log - Wait for an audit log. 454eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 455eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @file: Pointer to "struct file". 4566041e8346f2165679c2184cab60db768d6a26a1dTetsuo Handa * @wait: Pointer to "poll_table". Maybe NULL. 457eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * 458eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns POLLIN | POLLRDNORM when ready to read an audit log. 459eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */ 4606041e8346f2165679c2184cab60db768d6a26a1dTetsuo Handaunsigned int tomoyo_poll_log(struct file *file, poll_table *wait) 461eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{ 462eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (tomoyo_log_count) 463eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return POLLIN | POLLRDNORM; 464eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa poll_wait(file, &tomoyo_log_wait, wait); 465eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa if (tomoyo_log_count) 466eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return POLLIN | POLLRDNORM; 467eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa return 0; 468eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa} 469