blob: 90eb14c9e0cfe435c0c07c5b8abcc5a2076746ed [file] [log] [blame]
John Johansencdff2642010-07-29 14:47:57 -07001/*
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
John Johansen3b0aaf52017-01-16 00:42:23 -080015#include <linux/ctype.h>
Alexey Dobriyanb7f080c2011-06-16 11:01:34 +000016#include <linux/mm.h>
John Johansencdff2642010-07-29 14:47:57 -070017#include <linux/slab.h>
18#include <linux/string.h>
19#include <linux/vmalloc.h>
20
21#include "include/audit.h"
James Morris32c3df62011-08-29 11:15:25 +100022#include "include/apparmor.h"
John Johansen12557dc2017-01-16 00:42:13 -080023#include "include/lib.h"
John Johansenfc7e0b22017-05-26 01:57:09 -070024#include "include/perms.h"
John Johansenfe6bb312017-01-16 00:42:14 -080025#include "include/policy.h"
John Johansencdff2642010-07-29 14:47:57 -070026
27/**
28 * aa_split_fqname - split a fqname into a profile and namespace name
29 * @fqname: a full qualified name in namespace profile format (NOT NULL)
30 * @ns_name: pointer to portion of the string containing the ns name (NOT NULL)
31 *
32 * Returns: profile name or NULL if one is not specified
33 *
34 * Split a namespace name from a profile name (see policy.c for naming
35 * description). If a portion of the name is missing it returns NULL for
36 * that portion.
37 *
38 * NOTE: may modify the @fqname string. The pointers returned point
39 * into the @fqname string.
40 */
41char *aa_split_fqname(char *fqname, char **ns_name)
42{
43 char *name = strim(fqname);
44
45 *ns_name = NULL;
46 if (name[0] == ':') {
47 char *split = strchr(&name[1], ':');
John Johansen04ccd532010-08-27 18:33:28 -070048 *ns_name = skip_spaces(&name[1]);
John Johansencdff2642010-07-29 14:47:57 -070049 if (split) {
50 /* overwrite ':' with \0 */
John Johansen2654bfb2013-02-27 03:45:05 -080051 *split++ = 0;
52 if (strncmp(split, "//", 2) == 0)
53 split += 2;
54 name = skip_spaces(split);
John Johansencdff2642010-07-29 14:47:57 -070055 } else
56 /* a ns name without a following profile is allowed */
57 name = NULL;
John Johansencdff2642010-07-29 14:47:57 -070058 }
59 if (name && *name == 0)
60 name = NULL;
61
62 return name;
63}
64
65/**
John Johansen3b0aaf52017-01-16 00:42:23 -080066 * skipn_spaces - Removes leading whitespace from @str.
67 * @str: The string to be stripped.
68 *
69 * Returns a pointer to the first non-whitespace character in @str.
70 * if all whitespace will return NULL
71 */
72
John Johansenb91deb92017-05-22 02:47:22 -070073const char *skipn_spaces(const char *str, size_t n)
John Johansen3b0aaf52017-01-16 00:42:23 -080074{
75 for (; n && isspace(*str); --n)
76 ++str;
77 if (n)
78 return (char *)str;
79 return NULL;
80}
81
82const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
83 size_t *ns_len)
84{
85 const char *end = fqname + n;
86 const char *name = skipn_spaces(fqname, n);
87
88 if (!name)
89 return NULL;
90 *ns_name = NULL;
91 *ns_len = 0;
92 if (name[0] == ':') {
93 char *split = strnchr(&name[1], end - &name[1], ':');
94 *ns_name = skipn_spaces(&name[1], end - &name[1]);
95 if (!*ns_name)
96 return NULL;
97 if (split) {
98 *ns_len = split - *ns_name;
99 if (*ns_len == 0)
100 *ns_name = NULL;
101 split++;
102 if (end - split > 1 && strncmp(split, "//", 2) == 0)
103 split += 2;
104 name = skipn_spaces(split, end - split);
105 } else {
106 /* a ns name without a following profile is allowed */
107 name = NULL;
108 *ns_len = end - *ns_name;
109 }
110 }
111 if (name && *name == 0)
112 name = NULL;
113
114 return name;
115}
116
117/**
John Johansencdff2642010-07-29 14:47:57 -0700118 * aa_info_message - log a none profile related status message
119 * @str: message to log
120 */
121void aa_info_message(const char *str)
122{
123 if (audit_enabled) {
John Johansenef88a7a2017-01-16 00:43:02 -0800124 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL);
125
126 aad(&sa)->info = str;
John Johansencdff2642010-07-29 14:47:57 -0700127 aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL);
128 }
129 printk(KERN_INFO "AppArmor: %s\n", str);
130}
131
132/**
John Johansenfe6bb312017-01-16 00:42:14 -0800133 * aa_policy_init - initialize a policy structure
134 * @policy: policy to initialize (NOT NULL)
135 * @prefix: prefix name if any is required. (MAYBE NULL)
136 * @name: name of the policy, init will make a copy of it (NOT NULL)
137 *
138 * Note: this fn creates a copy of strings passed in
139 *
140 * Returns: true if policy init successful
141 */
142bool aa_policy_init(struct aa_policy *policy, const char *prefix,
John Johansend102d892017-01-16 00:42:31 -0800143 const char *name, gfp_t gfp)
John Johansenfe6bb312017-01-16 00:42:14 -0800144{
145 /* freed by policy_free */
146 if (prefix) {
147 policy->hname = kmalloc(strlen(prefix) + strlen(name) + 3,
John Johansend102d892017-01-16 00:42:31 -0800148 gfp);
John Johansenfe6bb312017-01-16 00:42:14 -0800149 if (policy->hname)
John Johansenbbe4a7c2017-01-16 00:42:30 -0800150 sprintf((char *)policy->hname, "%s//%s", prefix, name);
John Johansenfe6bb312017-01-16 00:42:14 -0800151 } else
John Johansend102d892017-01-16 00:42:31 -0800152 policy->hname = kstrdup(name, gfp);
John Johansenfe6bb312017-01-16 00:42:14 -0800153 if (!policy->hname)
kbuild test robotb9c42ac2017-04-06 06:55:19 -0700154 return false;
John Johansenfe6bb312017-01-16 00:42:14 -0800155 /* base.name is a substring of fqname */
John Johansend102d892017-01-16 00:42:31 -0800156 policy->name = basename(policy->hname);
John Johansenfe6bb312017-01-16 00:42:14 -0800157 INIT_LIST_HEAD(&policy->list);
158 INIT_LIST_HEAD(&policy->profiles);
159
kbuild test robotb9c42ac2017-04-06 06:55:19 -0700160 return true;
John Johansenfe6bb312017-01-16 00:42:14 -0800161}
162
163/**
164 * aa_policy_destroy - free the elements referenced by @policy
165 * @policy: policy that is to have its elements freed (NOT NULL)
166 */
167void aa_policy_destroy(struct aa_policy *policy)
168{
John Johansen5fd1b952017-01-16 00:42:32 -0800169 AA_BUG(on_list_rcu(&policy->profiles));
170 AA_BUG(on_list_rcu(&policy->list));
John Johansenfe6bb312017-01-16 00:42:14 -0800171
172 /* don't free name as its a subset of hname */
173 kzfree(policy->hname);
174}