1 /* 2 * AppArmor security module 3 * 4 * This file contains basic common functions used in AppArmor 5 * 6 * Copyright (C) 1998-2008 Novell/SUSE 7 * Copyright 2009-2010 Canonical Ltd. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation, version 2 of the 12 * License. 13 */ 14 15 #include <linux/mm.h> 16 #include <linux/slab.h> 17 #include <linux/string.h> 18 #include <linux/vmalloc.h> 19 20 #include "include/audit.h" 21 22 23 /** 24 * aa_split_fqname - split a fqname into a profile and namespace name 25 * @fqname: a full qualified name in namespace profile format (NOT NULL) 26 * @ns_name: pointer to portion of the string containing the ns name (NOT NULL) 27 * 28 * Returns: profile name or NULL if one is not specified 29 * 30 * Split a namespace name from a profile name (see policy.c for naming 31 * description). If a portion of the name is missing it returns NULL for 32 * that portion. 33 * 34 * NOTE: may modify the @fqname string. The pointers returned point 35 * into the @fqname string. 36 */ 37 char *aa_split_fqname(char *fqname, char **ns_name) 38 { 39 char *name = strim(fqname); 40 41 *ns_name = NULL; 42 if (name[0] == ':') { 43 char *split = strchr(&name[1], ':'); 44 *ns_name = skip_spaces(&name[1]); 45 if (split) { 46 /* overwrite ':' with \0 */ 47 *split = 0; 48 name = skip_spaces(split + 1); 49 } else 50 /* a ns name without a following profile is allowed */ 51 name = NULL; 52 } 53 if (name && *name == 0) 54 name = NULL; 55 56 return name; 57 } 58 59 /** 60 * aa_info_message - log a none profile related status message 61 * @str: message to log 62 */ 63 void aa_info_message(const char *str) 64 { 65 if (audit_enabled) { 66 struct common_audit_data sa; 67 COMMON_AUDIT_DATA_INIT(&sa, NONE); 68 sa.aad.info = str; 69 aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL); 70 } 71 printk(KERN_INFO "AppArmor: %s\n", str); 72 } 73 74 /** 75 * kvmalloc - do allocation preferring kmalloc but falling back to vmalloc 76 * @size: size of allocation 77 * 78 * Return: allocated buffer or NULL if failed 79 * 80 * It is possible that policy being loaded from the user is larger than 81 * what can be allocated by kmalloc, in those cases fall back to vmalloc. 82 */ 83 void *kvmalloc(size_t size) 84 { 85 void *buffer = NULL; 86 87 if (size == 0) 88 return NULL; 89 90 /* do not attempt kmalloc if we need more than 16 pages at once */ 91 if (size <= (16*PAGE_SIZE)) 92 buffer = kmalloc(size, GFP_NOIO | __GFP_NOWARN); 93 if (!buffer) { 94 /* see kvfree for why size must be at least work_struct size 95 * when allocated via vmalloc 96 */ 97 if (size < sizeof(struct work_struct)) 98 size = sizeof(struct work_struct); 99 buffer = vmalloc(size); 100 } 101 return buffer; 102 } 103 104 /** 105 * do_vfree - workqueue routine for freeing vmalloced memory 106 * @work: data to be freed 107 * 108 * The work_struct is overlaid to the data being freed, as at the point 109 * the work is scheduled the data is no longer valid, be its freeing 110 * needs to be delayed until safe. 111 */ 112 static void do_vfree(struct work_struct *work) 113 { 114 vfree(work); 115 } 116 117 /** 118 * kvfree - free an allocation do by kvmalloc 119 * @buffer: buffer to free (MAYBE_NULL) 120 * 121 * Free a buffer allocated by kvmalloc 122 */ 123 void kvfree(void *buffer) 124 { 125 if (is_vmalloc_addr(buffer)) { 126 /* Data is no longer valid so just use the allocated space 127 * as the work_struct 128 */ 129 struct work_struct *work = (struct work_struct *) buffer; 130 INIT_WORK(work, do_vfree); 131 schedule_work(work); 132 } else 133 kfree(buffer); 134 } 135