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