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/ctype.h> 16 #include <linux/mm.h> 17 #include <linux/slab.h> 18 #include <linux/string.h> 19 #include <linux/vmalloc.h> 20 21 #include "include/audit.h" 22 #include "include/apparmor.h" 23 #include "include/lib.h" 24 #include "include/policy.h" 25 26 /** 27 * aa_split_fqname - split a fqname into a profile and namespace name 28 * @fqname: a full qualified name in namespace profile format (NOT NULL) 29 * @ns_name: pointer to portion of the string containing the ns name (NOT NULL) 30 * 31 * Returns: profile name or NULL if one is not specified 32 * 33 * Split a namespace name from a profile name (see policy.c for naming 34 * description). If a portion of the name is missing it returns NULL for 35 * that portion. 36 * 37 * NOTE: may modify the @fqname string. The pointers returned point 38 * into the @fqname string. 39 */ 40 char *aa_split_fqname(char *fqname, char **ns_name) 41 { 42 char *name = strim(fqname); 43 44 *ns_name = NULL; 45 if (name[0] == ':') { 46 char *split = strchr(&name[1], ':'); 47 *ns_name = skip_spaces(&name[1]); 48 if (split) { 49 /* overwrite ':' with \0 */ 50 *split++ = 0; 51 if (strncmp(split, "//", 2) == 0) 52 split += 2; 53 name = skip_spaces(split); 54 } else 55 /* a ns name without a following profile is allowed */ 56 name = NULL; 57 } 58 if (name && *name == 0) 59 name = NULL; 60 61 return name; 62 } 63 64 /** 65 * skipn_spaces - Removes leading whitespace from @str. 66 * @str: The string to be stripped. 67 * 68 * Returns a pointer to the first non-whitespace character in @str. 69 * if all whitespace will return NULL 70 */ 71 72 static const char *skipn_spaces(const char *str, size_t n) 73 { 74 for (; n && isspace(*str); --n) 75 ++str; 76 if (n) 77 return (char *)str; 78 return NULL; 79 } 80 81 const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name, 82 size_t *ns_len) 83 { 84 const char *end = fqname + n; 85 const char *name = skipn_spaces(fqname, n); 86 87 if (!name) 88 return NULL; 89 *ns_name = NULL; 90 *ns_len = 0; 91 if (name[0] == ':') { 92 char *split = strnchr(&name[1], end - &name[1], ':'); 93 *ns_name = skipn_spaces(&name[1], end - &name[1]); 94 if (!*ns_name) 95 return NULL; 96 if (split) { 97 *ns_len = split - *ns_name; 98 if (*ns_len == 0) 99 *ns_name = NULL; 100 split++; 101 if (end - split > 1 && strncmp(split, "//", 2) == 0) 102 split += 2; 103 name = skipn_spaces(split, end - split); 104 } else { 105 /* a ns name without a following profile is allowed */ 106 name = NULL; 107 *ns_len = end - *ns_name; 108 } 109 } 110 if (name && *name == 0) 111 name = NULL; 112 113 return name; 114 } 115 116 /** 117 * aa_info_message - log a none profile related status message 118 * @str: message to log 119 */ 120 void aa_info_message(const char *str) 121 { 122 if (audit_enabled) { 123 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL); 124 125 aad(&sa)->info = str; 126 aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL); 127 } 128 printk(KERN_INFO "AppArmor: %s\n", str); 129 } 130 131 /** 132 * __aa_kvmalloc - do allocation preferring kmalloc but falling back to vmalloc 133 * @size: how many bytes of memory are required 134 * @flags: the type of memory to allocate (see kmalloc). 135 * 136 * Return: allocated buffer or NULL if failed 137 * 138 * It is possible that policy being loaded from the user is larger than 139 * what can be allocated by kmalloc, in those cases fall back to vmalloc. 140 */ 141 void *__aa_kvmalloc(size_t size, gfp_t flags) 142 { 143 void *buffer = NULL; 144 145 if (size == 0) 146 return NULL; 147 148 /* do not attempt kmalloc if we need more than 16 pages at once */ 149 if (size <= (16*PAGE_SIZE)) 150 buffer = kmalloc(size, flags | GFP_KERNEL | __GFP_NORETRY | 151 __GFP_NOWARN); 152 if (!buffer) { 153 if (flags & __GFP_ZERO) 154 buffer = vzalloc(size); 155 else 156 buffer = vmalloc(size); 157 } 158 return buffer; 159 } 160 161 /** 162 * aa_policy_init - initialize a policy structure 163 * @policy: policy to initialize (NOT NULL) 164 * @prefix: prefix name if any is required. (MAYBE NULL) 165 * @name: name of the policy, init will make a copy of it (NOT NULL) 166 * 167 * Note: this fn creates a copy of strings passed in 168 * 169 * Returns: true if policy init successful 170 */ 171 bool aa_policy_init(struct aa_policy *policy, const char *prefix, 172 const char *name, gfp_t gfp) 173 { 174 /* freed by policy_free */ 175 if (prefix) { 176 policy->hname = kmalloc(strlen(prefix) + strlen(name) + 3, 177 gfp); 178 if (policy->hname) 179 sprintf((char *)policy->hname, "%s//%s", prefix, name); 180 } else 181 policy->hname = kstrdup(name, gfp); 182 if (!policy->hname) 183 return 0; 184 /* base.name is a substring of fqname */ 185 policy->name = basename(policy->hname); 186 INIT_LIST_HEAD(&policy->list); 187 INIT_LIST_HEAD(&policy->profiles); 188 189 return 1; 190 } 191 192 /** 193 * aa_policy_destroy - free the elements referenced by @policy 194 * @policy: policy that is to have its elements freed (NOT NULL) 195 */ 196 void aa_policy_destroy(struct aa_policy *policy) 197 { 198 AA_BUG(on_list_rcu(&policy->profiles)); 199 AA_BUG(on_list_rcu(&policy->list)); 200 201 /* don't free name as its a subset of hname */ 202 kzfree(policy->hname); 203 } 204