aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2008-02-05 01:29:50 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-05 12:44:20 -0500
commite114e473771c848c3cfec05f0123e70f1cdbdc99 (patch)
tree933b840f3ccac6860da56291c742094f9b5a20cb /security/smack
parenteda61d32e8ad1d9102872f9a0abf3344bf9c5e67 (diff)
Smack: Simplified Mandatory Access Control Kernel
Smack is the Simplified Mandatory Access Control Kernel. Smack implements mandatory access control (MAC) using labels attached to tasks and data containers, including files, SVIPC, and other tasks. Smack is a kernel based scheme that requires an absolute minimum of application support and a very small amount of configuration data. Smack uses extended attributes and provides a set of general mount options, borrowing technics used elsewhere. Smack uses netlabel for CIPSO labeling. Smack provides a pseudo-filesystem smackfs that is used for manipulation of system Smack attributes. The patch, patches for ls and sshd, a README, a startup script, and x86 binaries for ls and sshd are also available on http://www.schaufler-ca.com Development has been done using Fedora Core 7 in a virtual machine environment and on an old Sony laptop. Smack provides mandatory access controls based on the label attached to a task and the label attached to the object it is attempting to access. Smack labels are deliberately short (1-23 characters) text strings. Single character labels using special characters are reserved for system use. The only operation applied to Smack labels is equality comparison. No wildcards or expressions, regular or otherwise, are used. Smack labels are composed of printable characters and may not include "/". A file always gets the Smack label of the task that created it. Smack defines and uses these labels: "*" - pronounced "star" "_" - pronounced "floor" "^" - pronounced "hat" "?" - pronounced "huh" The access rules enforced by Smack are, in order: 1. Any access requested by a task labeled "*" is denied. 2. A read or execute access requested by a task labeled "^" is permitted. 3. A read or execute access requested on an object labeled "_" is permitted. 4. Any access requested on an object labeled "*" is permitted. 5. Any access requested by a task on an object with the same label is permitted. 6. Any access requested that is explicitly defined in the loaded rule set is permitted. 7. Any other access is denied. Rules may be explicitly defined by writing subject,object,access triples to /smack/load. Smack rule sets can be easily defined that describe Bell&LaPadula sensitivity, Biba integrity, and a variety of interesting configurations. Smack rule sets can be modified on the fly to accommodate changes in the operating environment or even the time of day. Some practical use cases: Hierarchical levels. The less common of the two usual uses for MLS systems is to define hierarchical levels, often unclassified, confidential, secret, and so on. To set up smack to support this, these rules could be defined: C Unclass rx S C rx S Unclass rx TS S rx TS C rx TS Unclass rx A TS process can read S, C, and Unclass data, but cannot write it. An S process can read C and Unclass. Note that specifying that TS can read S and S can read C does not imply TS can read C, it has to be explicitly stated. Non-hierarchical categories. This is the more common of the usual uses for an MLS system. Since the default rule is that a subject cannot access an object with a different label no access rules are required to implement compartmentalization. A case that the Bell & LaPadula policy does not allow is demonstrated with this Smack access rule: A case that Bell&LaPadula does not allow that Smack does: ESPN ABC r ABC ESPN r On my portable video device I have two applications, one that shows ABC programming and the other ESPN programming. ESPN wants to show me sport stories that show up as news, and ABC will only provide minimal information about a sports story if ESPN is covering it. Each side can look at the other's info, neither can change the other. Neither can see what FOX is up to, which is just as well all things considered. Another case that I especially like: SatData Guard w Guard Publish w A program running with the Guard label opens a UDP socket and accepts messages sent by a program running with a SatData label. The Guard program inspects the message to ensure it is wholesome and if it is sends it to a program running with the Publish label. This program then puts the information passed in an appropriate place. Note that the Guard program cannot write to a Publish file system object because file system semanitic require read as well as write. The four cases (categories, levels, mutual read, guardbox) here are all quite real, and problems I've been asked to solve over the years. The first two are easy to do with traditonal MLS systems while the last two you can't without invoking privilege, at least for a while. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Cc: Joshua Brindle <method@manicmethod.com> Cc: Paul Moore <paul.moore@hp.com> Cc: Stephen Smalley <sds@tycho.nsa.gov> Cc: Chris Wright <chrisw@sous-sol.org> Cc: James Morris <jmorris@namei.org> Cc: "Ahmed S. Darwish" <darwish.07@gmail.com> Cc: Andrew G. Morgan <morgan@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security/smack')
-rw-r--r--security/smack/Kconfig10
-rw-r--r--security/smack/Makefile7
-rw-r--r--security/smack/smack.h220
-rw-r--r--security/smack/smack_access.c356
-rw-r--r--security/smack/smack_lsm.c2518
-rw-r--r--security/smack/smackfs.c981
6 files changed, 4092 insertions, 0 deletions
diff --git a/security/smack/Kconfig b/security/smack/Kconfig
new file mode 100644
index 000000000000..603b08784341
--- /dev/null
+++ b/security/smack/Kconfig
@@ -0,0 +1,10 @@
1config SECURITY_SMACK
2 bool "Simplified Mandatory Access Control Kernel Support"
3 depends on NETLABEL && SECURITY_NETWORK
4 default n
5 help
6 This selects the Simplified Mandatory Access Control Kernel.
7 Smack is useful for sensitivity, integrity, and a variety
8 of other mandatory security schemes.
9 If you are unsure how to answer this question, answer N.
10
diff --git a/security/smack/Makefile b/security/smack/Makefile
new file mode 100644
index 000000000000..67a63aaec827
--- /dev/null
+++ b/security/smack/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the SMACK LSM
3#
4
5obj-$(CONFIG_SECURITY_SMACK) := smack.o
6
7smack-y := smack_lsm.o smack_access.o smackfs.o
diff --git a/security/smack/smack.h b/security/smack/smack.h
new file mode 100644
index 000000000000..a21a0e907ab3
--- /dev/null
+++ b/security/smack/smack.h
@@ -0,0 +1,220 @@
1/*
2 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, version 2.
7 *
8 * Author:
9 * Casey Schaufler <casey@schaufler-ca.com>
10 *
11 */
12
13#ifndef _SECURITY_SMACK_H
14#define _SECURITY_SMACK_H
15
16#include <linux/capability.h>
17#include <linux/spinlock.h>
18#include <net/netlabel.h>
19
20/*
21 * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
22 * bigger than can be used, and 24 is the next lower multiple
23 * of 8, and there are too many issues if there isn't space set
24 * aside for the terminating null byte.
25 */
26#define SMK_MAXLEN 23
27#define SMK_LABELLEN (SMK_MAXLEN+1)
28
29/*
30 * How many kinds of access are there?
31 * Here's your answer.
32 */
33#define SMK_ACCESSDASH '-'
34#define SMK_ACCESSLOW "rwxa"
35#define SMK_ACCESSKINDS (sizeof(SMK_ACCESSLOW) - 1)
36
37struct superblock_smack {
38 char *smk_root;
39 char *smk_floor;
40 char *smk_hat;
41 char *smk_default;
42 int smk_initialized;
43 spinlock_t smk_sblock; /* for initialization */
44};
45
46struct socket_smack {
47 char *smk_out; /* outbound label */
48 char *smk_in; /* inbound label */
49 char smk_packet[SMK_LABELLEN]; /* TCP peer label */
50};
51
52/*
53 * Inode smack data
54 */
55struct inode_smack {
56 char *smk_inode; /* label of the fso */
57 struct mutex smk_lock; /* initialization lock */
58 int smk_flags; /* smack inode flags */
59};
60
61#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */
62
63/*
64 * A label access rule.
65 */
66struct smack_rule {
67 char *smk_subject;
68 char *smk_object;
69 int smk_access;
70};
71
72/*
73 * An entry in the table of permitted label accesses.
74 */
75struct smk_list_entry {
76 struct smk_list_entry *smk_next;
77 struct smack_rule smk_rule;
78};
79
80/*
81 * An entry in the table mapping smack values to
82 * CIPSO level/category-set values.
83 */
84struct smack_cipso {
85 int smk_level;
86 char smk_catset[SMK_LABELLEN];
87};
88
89/*
90 * This is the repository for labels seen so that it is
91 * not necessary to keep allocating tiny chuncks of memory
92 * and so that they can be shared.
93 *
94 * Labels are never modified in place. Anytime a label
95 * is imported (e.g. xattrset on a file) the list is checked
96 * for it and it is added if it doesn't exist. The address
97 * is passed out in either case. Entries are added, but
98 * never deleted.
99 *
100 * Since labels are hanging around anyway it doesn't
101 * hurt to maintain a secid for those awkward situations
102 * where kernel components that ought to use LSM independent
103 * interfaces don't. The secid should go away when all of
104 * these components have been repaired.
105 *
106 * If there is a cipso value associated with the label it
107 * gets stored here, too. This will most likely be rare as
108 * the cipso direct mapping in used internally.
109 */
110struct smack_known {
111 struct smack_known *smk_next;
112 char smk_known[SMK_LABELLEN];
113 u32 smk_secid;
114 struct smack_cipso *smk_cipso;
115 spinlock_t smk_cipsolock; /* for changing cipso map */
116};
117
118/*
119 * Mount options
120 */
121#define SMK_FSDEFAULT "smackfsdef="
122#define SMK_FSFLOOR "smackfsfloor="
123#define SMK_FSHAT "smackfshat="
124#define SMK_FSROOT "smackfsroot="
125
126/*
127 * xattr names
128 */
129#define XATTR_SMACK_SUFFIX "SMACK64"
130#define XATTR_SMACK_IPIN "SMACK64IPIN"
131#define XATTR_SMACK_IPOUT "SMACK64IPOUT"
132#define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX
133#define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN
134#define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT
135
136/*
137 * smackfs macic number
138 */
139#define SMACK_MAGIC 0x43415d53 /* "SMAC" */
140
141/*
142 * A limit on the number of entries in the lists
143 * makes some of the list administration easier.
144 */
145#define SMACK_LIST_MAX 10000
146
147/*
148 * CIPSO defaults.
149 */
150#define SMACK_CIPSO_DOI_DEFAULT 3 /* Historical */
151#define SMACK_CIPSO_DIRECT_DEFAULT 250 /* Arbitrary */
152#define SMACK_CIPSO_MAXCATVAL 63 /* Bigger gets harder */
153#define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */
154#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */
155
156/*
157 * Just to make the common cases easier to deal with
158 */
159#define MAY_ANY (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
160#define MAY_ANYREAD (MAY_READ | MAY_EXEC)
161#define MAY_ANYWRITE (MAY_WRITE | MAY_APPEND)
162#define MAY_READWRITE (MAY_READ | MAY_WRITE)
163#define MAY_NOT 0
164
165/*
166 * These functions are in smack_lsm.c
167 */
168struct inode_smack *new_inode_smack(char *);
169
170/*
171 * These functions are in smack_access.c
172 */
173int smk_access(char *, char *, int);
174int smk_curacc(char *, u32);
175int smack_to_cipso(const char *, struct smack_cipso *);
176void smack_from_cipso(u32, char *, char *);
177char *smack_from_secid(const u32);
178char *smk_import(const char *, int);
179struct smack_known *smk_import_entry(const char *, int);
180u32 smack_to_secid(const char *);
181
182/*
183 * Shared data.
184 */
185extern int smack_cipso_direct;
186extern int smack_net_nltype;
187extern char *smack_net_ambient;
188
189extern struct smack_known *smack_known;
190extern struct smack_known smack_known_floor;
191extern struct smack_known smack_known_hat;
192extern struct smack_known smack_known_huh;
193extern struct smack_known smack_known_invalid;
194extern struct smack_known smack_known_star;
195extern struct smack_known smack_known_unset;
196
197extern struct smk_list_entry *smack_list;
198
199/*
200 * Stricly for CIPSO level manipulation.
201 * Set the category bit number in a smack label sized buffer.
202 */
203static inline void smack_catset_bit(int cat, char *catsetp)
204{
205 if (cat > SMK_LABELLEN * 8)
206 return;
207
208 catsetp[(cat - 1) / 8] |= 0x80 >> ((cat - 1) % 8);
209}
210
211/*
212 * Present a pointer to the smack label in an inode blob.
213 */
214static inline char *smk_of_inode(const struct inode *isp)
215{
216 struct inode_smack *sip = isp->i_security;
217 return sip->smk_inode;
218}
219
220#endif /* _SECURITY_SMACK_H */
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
new file mode 100644
index 000000000000..f6b5f6eed6dd
--- /dev/null
+++ b/security/smack/smack_access.c
@@ -0,0 +1,356 @@
1/*
2 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, version 2.
7 *
8 * Author:
9 * Casey Schaufler <casey@schaufler-ca.com>
10 *
11 */
12
13#include <linux/types.h>
14#include <linux/fs.h>
15#include <linux/sched.h>
16#include "smack.h"
17
18struct smack_known smack_known_unset = {
19 .smk_next = NULL,
20 .smk_known = "UNSET",
21 .smk_secid = 1,
22 .smk_cipso = NULL,
23};
24
25struct smack_known smack_known_huh = {
26 .smk_next = &smack_known_unset,
27 .smk_known = "?",
28 .smk_secid = 2,
29 .smk_cipso = NULL,
30};
31
32struct smack_known smack_known_hat = {
33 .smk_next = &smack_known_huh,
34 .smk_known = "^",
35 .smk_secid = 3,
36 .smk_cipso = NULL,
37};
38
39struct smack_known smack_known_star = {
40 .smk_next = &smack_known_hat,
41 .smk_known = "*",
42 .smk_secid = 4,
43 .smk_cipso = NULL,
44};
45
46struct smack_known smack_known_floor = {
47 .smk_next = &smack_known_star,
48 .smk_known = "_",
49 .smk_secid = 5,
50 .smk_cipso = NULL,
51};
52
53struct smack_known smack_known_invalid = {
54 .smk_next = &smack_known_floor,
55 .smk_known = "",
56 .smk_secid = 6,
57 .smk_cipso = NULL,
58};
59
60struct smack_known *smack_known = &smack_known_invalid;
61
62/*
63 * The initial value needs to be bigger than any of the
64 * known values above.
65 */
66static u32 smack_next_secid = 10;
67
68/**
69 * smk_access - determine if a subject has a specific access to an object
70 * @subject_label: a pointer to the subject's Smack label
71 * @object_label: a pointer to the object's Smack label
72 * @request: the access requested, in "MAY" format
73 *
74 * This function looks up the subject/object pair in the
75 * access rule list and returns 0 if the access is permitted,
76 * non zero otherwise.
77 *
78 * Even though Smack labels are usually shared on smack_list
79 * labels that come in off the network can't be imported
80 * and added to the list for locking reasons.
81 *
82 * Therefore, it is necessary to check the contents of the labels,
83 * not just the pointer values. Of course, in most cases the labels
84 * will be on the list, so checking the pointers may be a worthwhile
85 * optimization.
86 */
87int smk_access(char *subject_label, char *object_label, int request)
88{
89 u32 may = MAY_NOT;
90 struct smk_list_entry *sp;
91 struct smack_rule *srp;
92
93 /*
94 * Hardcoded comparisons.
95 *
96 * A star subject can't access any object.
97 */
98 if (subject_label == smack_known_star.smk_known ||
99 strcmp(subject_label, smack_known_star.smk_known) == 0)
100 return -EACCES;
101 /*
102 * A star object can be accessed by any subject.
103 */
104 if (object_label == smack_known_star.smk_known ||
105 strcmp(object_label, smack_known_star.smk_known) == 0)
106 return 0;
107 /*
108 * An object can be accessed in any way by a subject
109 * with the same label.
110 */
111 if (subject_label == object_label ||
112 strcmp(subject_label, object_label) == 0)
113 return 0;
114 /*
115 * A hat subject can read any object.
116 * A floor object can be read by any subject.
117 */
118 if ((request & MAY_ANYREAD) == request) {
119 if (object_label == smack_known_floor.smk_known ||
120 strcmp(object_label, smack_known_floor.smk_known) == 0)
121 return 0;
122 if (subject_label == smack_known_hat.smk_known ||
123 strcmp(subject_label, smack_known_hat.smk_known) == 0)
124 return 0;
125 }
126 /*
127 * Beyond here an explicit relationship is required.
128 * If the requested access is contained in the available
129 * access (e.g. read is included in readwrite) it's
130 * good.
131 */
132 for (sp = smack_list; sp != NULL; sp = sp->smk_next) {
133 srp = &sp->smk_rule;
134
135 if (srp->smk_subject == subject_label ||
136 strcmp(srp->smk_subject, subject_label) == 0) {
137 if (srp->smk_object == object_label ||
138 strcmp(srp->smk_object, object_label) == 0) {
139 may = srp->smk_access;
140 break;
141 }
142 }
143 }
144 /*
145 * This is a bit map operation.
146 */
147 if ((request & may) == request)
148 return 0;
149
150 return -EACCES;
151}
152
153/**
154 * smk_curacc - determine if current has a specific access to an object
155 * @object_label: a pointer to the object's Smack label
156 * @request: the access requested, in "MAY" format
157 *
158 * This function checks the current subject label/object label pair
159 * in the access rule list and returns 0 if the access is permitted,
160 * non zero otherwise. It allows that current my have the capability
161 * to override the rules.
162 */
163int smk_curacc(char *obj_label, u32 mode)
164{
165 int rc;
166
167 rc = smk_access(current->security, obj_label, mode);
168 if (rc == 0)
169 return 0;
170
171 if (capable(CAP_MAC_OVERRIDE))
172 return 0;
173
174 return rc;
175}
176
177static DEFINE_MUTEX(smack_known_lock);
178
179/**
180 * smk_import_entry - import a label, return the list entry
181 * @string: a text string that might be a Smack label
182 * @len: the maximum size, or zero if it is NULL terminated.
183 *
184 * Returns a pointer to the entry in the label list that
185 * matches the passed string, adding it if necessary.
186 */
187struct smack_known *smk_import_entry(const char *string, int len)
188{
189 struct smack_known *skp;
190 char smack[SMK_LABELLEN];
191 int found;
192 int i;
193
194 if (len <= 0 || len > SMK_MAXLEN)
195 len = SMK_MAXLEN;
196
197 for (i = 0, found = 0; i < SMK_LABELLEN; i++) {
198 if (found)
199 smack[i] = '\0';
200 else if (i >= len || string[i] > '~' || string[i] <= ' ' ||
201 string[i] == '/') {
202 smack[i] = '\0';
203 found = 1;
204 } else
205 smack[i] = string[i];
206 }
207
208 if (smack[0] == '\0')
209 return NULL;
210
211 mutex_lock(&smack_known_lock);
212
213 for (skp = smack_known; skp != NULL; skp = skp->smk_next)
214 if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0)
215 break;
216
217 if (skp == NULL) {
218 skp = kzalloc(sizeof(struct smack_known), GFP_KERNEL);
219 if (skp != NULL) {
220 skp->smk_next = smack_known;
221 strncpy(skp->smk_known, smack, SMK_MAXLEN);
222 skp->smk_secid = smack_next_secid++;
223 skp->smk_cipso = NULL;
224 spin_lock_init(&skp->smk_cipsolock);
225 /*
226 * Make sure that the entry is actually
227 * filled before putting it on the list.
228 */
229 smp_mb();
230 smack_known = skp;
231 }
232 }
233
234 mutex_unlock(&smack_known_lock);
235
236 return skp;
237}
238
239/**
240 * smk_import - import a smack label
241 * @string: a text string that might be a Smack label
242 * @len: the maximum size, or zero if it is NULL terminated.
243 *
244 * Returns a pointer to the label in the label list that
245 * matches the passed string, adding it if necessary.
246 */
247char *smk_import(const char *string, int len)
248{
249 struct smack_known *skp;
250
251 skp = smk_import_entry(string, len);
252 if (skp == NULL)
253 return NULL;
254 return skp->smk_known;
255}
256
257/**
258 * smack_from_secid - find the Smack label associated with a secid
259 * @secid: an integer that might be associated with a Smack label
260 *
261 * Returns a pointer to the appropraite Smack label if there is one,
262 * otherwise a pointer to the invalid Smack label.
263 */
264char *smack_from_secid(const u32 secid)
265{
266 struct smack_known *skp;
267
268 for (skp = smack_known; skp != NULL; skp = skp->smk_next)
269 if (skp->smk_secid == secid)
270 return skp->smk_known;
271
272 /*
273 * If we got this far someone asked for the translation
274 * of a secid that is not on the list.
275 */
276 return smack_known_invalid.smk_known;
277}
278
279/**
280 * smack_to_secid - find the secid associated with a Smack label
281 * @smack: the Smack label
282 *
283 * Returns the appropriate secid if there is one,
284 * otherwise 0
285 */
286u32 smack_to_secid(const char *smack)
287{
288 struct smack_known *skp;
289
290 for (skp = smack_known; skp != NULL; skp = skp->smk_next)
291 if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0)
292 return skp->smk_secid;
293 return 0;
294}
295
296/**
297 * smack_from_cipso - find the Smack label associated with a CIPSO option
298 * @level: Bell & LaPadula level from the network
299 * @cp: Bell & LaPadula categories from the network
300 * @result: where to put the Smack value
301 *
302 * This is a simple lookup in the label table.
303 *
304 * This is an odd duck as far as smack handling goes in that
305 * it sends back a copy of the smack label rather than a pointer
306 * to the master list. This is done because it is possible for
307 * a foreign host to send a smack label that is new to this
308 * machine and hence not on the list. That would not be an
309 * issue except that adding an entry to the master list can't
310 * be done at that point.
311 */
312void smack_from_cipso(u32 level, char *cp, char *result)
313{
314 struct smack_known *kp;
315 char *final = NULL;
316
317 for (kp = smack_known; final == NULL && kp != NULL; kp = kp->smk_next) {
318 if (kp->smk_cipso == NULL)
319 continue;
320
321 spin_lock_bh(&kp->smk_cipsolock);
322
323 if (kp->smk_cipso->smk_level == level &&
324 memcmp(kp->smk_cipso->smk_catset, cp, SMK_LABELLEN) == 0)
325 final = kp->smk_known;
326
327 spin_unlock_bh(&kp->smk_cipsolock);
328 }
329 if (final == NULL)
330 final = smack_known_huh.smk_known;
331 strncpy(result, final, SMK_MAXLEN);
332 return;
333}
334
335/**
336 * smack_to_cipso - find the CIPSO option to go with a Smack label
337 * @smack: a pointer to the smack label in question
338 * @cp: where to put the result
339 *
340 * Returns zero if a value is available, non-zero otherwise.
341 */
342int smack_to_cipso(const char *smack, struct smack_cipso *cp)
343{
344 struct smack_known *kp;
345
346 for (kp = smack_known; kp != NULL; kp = kp->smk_next)
347 if (kp->smk_known == smack ||
348 strcmp(kp->smk_known, smack) == 0)
349 break;
350
351 if (kp == NULL || kp->smk_cipso == NULL)
352 return -ENOENT;
353
354 memcpy(cp, kp->smk_cipso, sizeof(struct smack_cipso));
355 return 0;
356}
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
new file mode 100644
index 000000000000..1c11e4245859
--- /dev/null
+++ b/security/smack/smack_lsm.c
@@ -0,0 +1,2518 @@
1/*
2 * Simplified MAC Kernel (smack) security module
3 *
4 * This file contains the smack hook function implementations.
5 *
6 * Author:
7 * Casey Schaufler <casey@schaufler-ca.com>
8 *
9 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2,
13 * as published by the Free Software Foundation.
14 */
15
16#include <linux/xattr.h>
17#include <linux/pagemap.h>
18#include <linux/mount.h>
19#include <linux/stat.h>
20#include <linux/ext2_fs.h>
21#include <linux/kd.h>
22#include <asm/ioctls.h>
23#include <linux/tcp.h>
24#include <linux/udp.h>
25#include <linux/mutex.h>
26#include <linux/pipe_fs_i.h>
27#include <net/netlabel.h>
28#include <net/cipso_ipv4.h>
29
30#include "smack.h"
31
32/*
33 * I hope these are the hokeyist lines of code in the module. Casey.
34 */
35#define DEVPTS_SUPER_MAGIC 0x1cd1
36#define SOCKFS_MAGIC 0x534F434B
37#define TMPFS_MAGIC 0x01021994
38
39/**
40 * smk_fetch - Fetch the smack label from a file.
41 * @ip: a pointer to the inode
42 * @dp: a pointer to the dentry
43 *
44 * Returns a pointer to the master list entry for the Smack label
45 * or NULL if there was no label to fetch.
46 */
47static char *smk_fetch(struct inode *ip, struct dentry *dp)
48{
49 int rc;
50 char in[SMK_LABELLEN];
51
52 if (ip->i_op->getxattr == NULL)
53 return NULL;
54
55 rc = ip->i_op->getxattr(dp, XATTR_NAME_SMACK, in, SMK_LABELLEN);
56 if (rc < 0)
57 return NULL;
58
59 return smk_import(in, rc);
60}
61
62/**
63 * new_inode_smack - allocate an inode security blob
64 * @smack: a pointer to the Smack label to use in the blob
65 *
66 * Returns the new blob or NULL if there's no memory available
67 */
68struct inode_smack *new_inode_smack(char *smack)
69{
70 struct inode_smack *isp;
71
72 isp = kzalloc(sizeof(struct inode_smack), GFP_KERNEL);
73 if (isp == NULL)
74 return NULL;
75
76 isp->smk_inode = smack;
77 isp->smk_flags = 0;
78 mutex_init(&isp->smk_lock);
79
80 return isp;
81}
82
83/*
84 * LSM hooks.
85 * We he, that is fun!
86 */
87
88/**
89 * smack_ptrace - Smack approval on ptrace
90 * @ptp: parent task pointer
91 * @ctp: child task pointer
92 *
93 * Returns 0 if access is OK, an error code otherwise
94 *
95 * Do the capability checks, and require read and write.
96 */
97static int smack_ptrace(struct task_struct *ptp, struct task_struct *ctp)
98{
99 int rc;
100
101 rc = cap_ptrace(ptp, ctp);
102 if (rc != 0)
103 return rc;
104
105 rc = smk_access(ptp->security, ctp->security, MAY_READWRITE);
106 if (rc != 0 && __capable(ptp, CAP_MAC_OVERRIDE))
107 return 0;
108
109 return rc;
110}
111
112/**
113 * smack_syslog - Smack approval on syslog
114 * @type: message type
115 *
116 * Require that the task has the floor label
117 *
118 * Returns 0 on success, error code otherwise.
119 */
120static int smack_syslog(int type)
121{
122 int rc;
123 char *sp = current->security;
124
125 rc = cap_syslog(type);
126 if (rc != 0)
127 return rc;
128
129 if (capable(CAP_MAC_OVERRIDE))
130 return 0;
131
132 if (sp != smack_known_floor.smk_known)
133 rc = -EACCES;
134
135 return rc;
136}
137
138
139/*
140 * Superblock Hooks.
141 */
142
143/**
144 * smack_sb_alloc_security - allocate a superblock blob
145 * @sb: the superblock getting the blob
146 *
147 * Returns 0 on success or -ENOMEM on error.
148 */
149static int smack_sb_alloc_security(struct super_block *sb)
150{
151 struct superblock_smack *sbsp;
152
153 sbsp = kzalloc(sizeof(struct superblock_smack), GFP_KERNEL);
154
155 if (sbsp == NULL)
156 return -ENOMEM;
157
158 sbsp->smk_root = smack_known_floor.smk_known;
159 sbsp->smk_default = smack_known_floor.smk_known;
160 sbsp->smk_floor = smack_known_floor.smk_known;
161 sbsp->smk_hat = smack_known_hat.smk_known;
162 sbsp->smk_initialized = 0;
163 spin_lock_init(&sbsp->smk_sblock);
164
165 sb->s_security = sbsp;
166
167 return 0;
168}
169
170/**
171 * smack_sb_free_security - free a superblock blob
172 * @sb: the superblock getting the blob
173 *
174 */
175static void smack_sb_free_security(struct super_block *sb)
176{
177 kfree(sb->s_security);
178 sb->s_security = NULL;
179}
180
181/**
182 * smack_sb_copy_data - copy mount options data for processing
183 * @type: file system type
184 * @orig: where to start
185 * @smackopts
186 *
187 * Returns 0 on success or -ENOMEM on error.
188 *
189 * Copy the Smack specific mount options out of the mount
190 * options list.
191 */
192static int smack_sb_copy_data(struct file_system_type *type, void *orig,
193 void *smackopts)
194{
195 char *cp, *commap, *otheropts, *dp;
196
197 /* Binary mount data: just copy */
198 if (type->fs_flags & FS_BINARY_MOUNTDATA) {
199 copy_page(smackopts, orig);
200 return 0;
201 }
202
203 otheropts = (char *)get_zeroed_page(GFP_KERNEL);
204 if (otheropts == NULL)
205 return -ENOMEM;
206
207 for (cp = orig, commap = orig; commap != NULL; cp = commap + 1) {
208 if (strstr(cp, SMK_FSDEFAULT) == cp)
209 dp = smackopts;
210 else if (strstr(cp, SMK_FSFLOOR) == cp)
211 dp = smackopts;
212 else if (strstr(cp, SMK_FSHAT) == cp)
213 dp = smackopts;
214 else if (strstr(cp, SMK_FSROOT) == cp)
215 dp = smackopts;
216 else
217 dp = otheropts;
218
219 commap = strchr(cp, ',');
220 if (commap != NULL)
221 *commap = '\0';
222
223 if (*dp != '\0')
224 strcat(dp, ",");
225 strcat(dp, cp);
226 }
227
228 strcpy(orig, otheropts);
229 free_page((unsigned long)otheropts);
230
231 return 0;
232}
233
234/**
235 * smack_sb_kern_mount - Smack specific mount processing
236 * @sb: the file system superblock
237 * @data: the smack mount options
238 *
239 * Returns 0 on success, an error code on failure
240 */
241static int smack_sb_kern_mount(struct super_block *sb, void *data)
242{
243 struct dentry *root = sb->s_root;
244 struct inode *inode = root->d_inode;
245 struct superblock_smack *sp = sb->s_security;
246 struct inode_smack *isp;
247 char *op;
248 char *commap;
249 char *nsp;
250
251 spin_lock(&sp->smk_sblock);
252 if (sp->smk_initialized != 0) {
253 spin_unlock(&sp->smk_sblock);
254 return 0;
255 }
256 sp->smk_initialized = 1;
257 spin_unlock(&sp->smk_sblock);
258
259 for (op = data; op != NULL; op = commap) {
260 commap = strchr(op, ',');
261 if (commap != NULL)
262 *commap++ = '\0';
263
264 if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) {
265 op += strlen(SMK_FSHAT);
266 nsp = smk_import(op, 0);
267 if (nsp != NULL)
268 sp->smk_hat = nsp;
269 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) {
270 op += strlen(SMK_FSFLOOR);
271 nsp = smk_import(op, 0);
272 if (nsp != NULL)
273 sp->smk_floor = nsp;
274 } else if (strncmp(op, SMK_FSDEFAULT,
275 strlen(SMK_FSDEFAULT)) == 0) {
276 op += strlen(SMK_FSDEFAULT);
277 nsp = smk_import(op, 0);
278 if (nsp != NULL)
279 sp->smk_default = nsp;
280 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) {
281 op += strlen(SMK_FSROOT);
282 nsp = smk_import(op, 0);
283 if (nsp != NULL)
284 sp->smk_root = nsp;
285 }
286 }
287
288 /*
289 * Initialize the root inode.
290 */
291 isp = inode->i_security;
292 if (isp == NULL)
293 inode->i_security = new_inode_smack(sp->smk_root);
294 else
295 isp->smk_inode = sp->smk_root;
296
297 return 0;
298}
299
300/**
301 * smack_sb_statfs - Smack check on statfs
302 * @dentry: identifies the file system in question
303 *
304 * Returns 0 if current can read the floor of the filesystem,
305 * and error code otherwise
306 */
307static int smack_sb_statfs(struct dentry *dentry)
308{
309 struct superblock_smack *sbp = dentry->d_sb->s_security;
310
311 return smk_curacc(sbp->smk_floor, MAY_READ);
312}
313
314/**
315 * smack_sb_mount - Smack check for mounting
316 * @dev_name: unused
317 * @nd: mount point
318 * @type: unused
319 * @flags: unused
320 * @data: unused
321 *
322 * Returns 0 if current can write the floor of the filesystem
323 * being mounted on, an error code otherwise.
324 */
325static int smack_sb_mount(char *dev_name, struct nameidata *nd,
326 char *type, unsigned long flags, void *data)
327{
328 struct superblock_smack *sbp = nd->mnt->mnt_sb->s_security;
329
330 return smk_curacc(sbp->smk_floor, MAY_WRITE);
331}
332
333/**
334 * smack_sb_umount - Smack check for unmounting
335 * @mnt: file system to unmount
336 * @flags: unused
337 *
338 * Returns 0 if current can write the floor of the filesystem
339 * being unmounted, an error code otherwise.
340 */
341static int smack_sb_umount(struct vfsmount *mnt, int flags)
342{
343 struct superblock_smack *sbp;
344
345 sbp = mnt->mnt_sb->s_security;
346
347 return smk_curacc(sbp->smk_floor, MAY_WRITE);
348}
349
350/*
351 * Inode hooks
352 */
353
354/**
355 * smack_inode_alloc_security - allocate an inode blob
356 * @inode - the inode in need of a blob
357 *
358 * Returns 0 if it gets a blob, -ENOMEM otherwise
359 */
360static int smack_inode_alloc_security(struct inode *inode)
361{
362 inode->i_security = new_inode_smack(current->security);
363 if (inode->i_security == NULL)
364 return -ENOMEM;
365 return 0;
366}
367
368/**
369 * smack_inode_free_security - free an inode blob
370 * @inode - the inode with a blob
371 *
372 * Clears the blob pointer in inode
373 */
374static void smack_inode_free_security(struct inode *inode)
375{
376 kfree(inode->i_security);
377 inode->i_security = NULL;
378}
379
380/**
381 * smack_inode_init_security - copy out the smack from an inode
382 * @inode: the inode
383 * @dir: unused
384 * @name: where to put the attribute name
385 * @value: where to put the attribute value
386 * @len: where to put the length of the attribute
387 *
388 * Returns 0 if it all works out, -ENOMEM if there's no memory
389 */
390static int smack_inode_init_security(struct inode *inode, struct inode *dir,
391 char **name, void **value, size_t *len)
392{
393 char *isp = smk_of_inode(inode);
394
395 if (name) {
396 *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL);
397 if (*name == NULL)
398 return -ENOMEM;
399 }
400
401 if (value) {
402 *value = kstrdup(isp, GFP_KERNEL);
403 if (*value == NULL)
404 return -ENOMEM;
405 }
406
407 if (len)
408 *len = strlen(isp) + 1;
409
410 return 0;
411}
412
413/**
414 * smack_inode_link - Smack check on link
415 * @old_dentry: the existing object
416 * @dir: unused
417 * @new_dentry: the new object
418 *
419 * Returns 0 if access is permitted, an error code otherwise
420 */
421static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
422 struct dentry *new_dentry)
423{
424 int rc;
425 char *isp;
426
427 isp = smk_of_inode(old_dentry->d_inode);
428 rc = smk_curacc(isp, MAY_WRITE);
429
430 if (rc == 0 && new_dentry->d_inode != NULL) {
431 isp = smk_of_inode(new_dentry->d_inode);
432 rc = smk_curacc(isp, MAY_WRITE);
433 }
434
435 return rc;
436}
437
438/**
439 * smack_inode_unlink - Smack check on inode deletion
440 * @dir: containing directory object
441 * @dentry: file to unlink
442 *
443 * Returns 0 if current can write the containing directory
444 * and the object, error code otherwise
445 */
446static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
447{
448 struct inode *ip = dentry->d_inode;
449 int rc;
450
451 /*
452 * You need write access to the thing you're unlinking
453 */
454 rc = smk_curacc(smk_of_inode(ip), MAY_WRITE);
455 if (rc == 0)
456 /*
457 * You also need write access to the containing directory
458 */
459 rc = smk_curacc(smk_of_inode(dir), MAY_WRITE);
460
461 return rc;
462}
463
464/**
465 * smack_inode_rmdir - Smack check on directory deletion
466 * @dir: containing directory object
467 * @dentry: directory to unlink
468 *
469 * Returns 0 if current can write the containing directory
470 * and the directory, error code otherwise
471 */
472static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
473{
474 int rc;
475
476 /*
477 * You need write access to the thing you're removing
478 */
479 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
480 if (rc == 0)
481 /*
482 * You also need write access to the containing directory
483 */
484 rc = smk_curacc(smk_of_inode(dir), MAY_WRITE);
485
486 return rc;
487}
488
489/**
490 * smack_inode_rename - Smack check on rename
491 * @old_inode: the old directory
492 * @old_dentry: unused
493 * @new_inode: the new directory
494 * @new_dentry: unused
495 *
496 * Read and write access is required on both the old and
497 * new directories.
498 *
499 * Returns 0 if access is permitted, an error code otherwise
500 */
501static int smack_inode_rename(struct inode *old_inode,
502 struct dentry *old_dentry,
503 struct inode *new_inode,
504 struct dentry *new_dentry)
505{
506 int rc;
507 char *isp;
508
509 isp = smk_of_inode(old_dentry->d_inode);
510 rc = smk_curacc(isp, MAY_READWRITE);
511
512 if (rc == 0 && new_dentry->d_inode != NULL) {
513 isp = smk_of_inode(new_dentry->d_inode);
514 rc = smk_curacc(isp, MAY_READWRITE);
515 }
516
517 return rc;
518}
519
520/**
521 * smack_inode_permission - Smack version of permission()
522 * @inode: the inode in question
523 * @mask: the access requested
524 * @nd: unused
525 *
526 * This is the important Smack hook.
527 *
528 * Returns 0 if access is permitted, -EACCES otherwise
529 */
530static int smack_inode_permission(struct inode *inode, int mask,
531 struct nameidata *nd)
532{
533 /*
534 * No permission to check. Existence test. Yup, it's there.
535 */
536 if (mask == 0)
537 return 0;
538
539 return smk_curacc(smk_of_inode(inode), mask);
540}
541
542/**
543 * smack_inode_setattr - Smack check for setting attributes
544 * @dentry: the object
545 * @iattr: for the force flag
546 *
547 * Returns 0 if access is permitted, an error code otherwise
548 */
549static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
550{
551 /*
552 * Need to allow for clearing the setuid bit.
553 */
554 if (iattr->ia_valid & ATTR_FORCE)
555 return 0;
556
557 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
558}
559
560/**
561 * smack_inode_getattr - Smack check for getting attributes
562 * @mnt: unused
563 * @dentry: the object
564 *
565 * Returns 0 if access is permitted, an error code otherwise
566 */
567static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
568{
569 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ);
570}
571
572/**
573 * smack_inode_setxattr - Smack check for setting xattrs
574 * @dentry: the object
575 * @name: name of the attribute
576 * @value: unused
577 * @size: unused
578 * @flags: unused
579 *
580 * This protects the Smack attribute explicitly.
581 *
582 * Returns 0 if access is permitted, an error code otherwise
583 */
584static int smack_inode_setxattr(struct dentry *dentry, char *name,
585 void *value, size_t size, int flags)
586{
587 if (!capable(CAP_MAC_ADMIN)) {
588 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
589 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
590 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0)
591 return -EPERM;
592 }
593
594 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
595}
596
597/**
598 * smack_inode_post_setxattr - Apply the Smack update approved above
599 * @dentry: object
600 * @name: attribute name
601 * @value: attribute value
602 * @size: attribute size
603 * @flags: unused
604 *
605 * Set the pointer in the inode blob to the entry found
606 * in the master label list.
607 */
608static void smack_inode_post_setxattr(struct dentry *dentry, char *name,
609 void *value, size_t size, int flags)
610{
611 struct inode_smack *isp;
612 char *nsp;
613
614 /*
615 * Not SMACK
616 */
617 if (strcmp(name, XATTR_NAME_SMACK))
618 return;
619
620 if (size >= SMK_LABELLEN)
621 return;
622
623 isp = dentry->d_inode->i_security;
624
625 /*
626 * No locking is done here. This is a pointer
627 * assignment.
628 */
629 nsp = smk_import(value, size);
630 if (nsp != NULL)
631 isp->smk_inode = nsp;
632 else
633 isp->smk_inode = smack_known_invalid.smk_known;
634
635 return;
636}
637
638/*
639 * smack_inode_getxattr - Smack check on getxattr
640 * @dentry: the object
641 * @name: unused
642 *
643 * Returns 0 if access is permitted, an error code otherwise
644 */
645static int smack_inode_getxattr(struct dentry *dentry, char *name)
646{
647 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ);
648}
649
650/*
651 * smack_inode_removexattr - Smack check on removexattr
652 * @dentry: the object
653 * @name: name of the attribute
654 *
655 * Removing the Smack attribute requires CAP_MAC_ADMIN
656 *
657 * Returns 0 if access is permitted, an error code otherwise
658 */
659static int smack_inode_removexattr(struct dentry *dentry, char *name)
660{
661 if (strcmp(name, XATTR_NAME_SMACK) == 0 && !capable(CAP_MAC_ADMIN))
662 return -EPERM;
663
664 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
665}
666
667/**
668 * smack_inode_getsecurity - get smack xattrs
669 * @inode: the object
670 * @name: attribute name
671 * @buffer: where to put the result
672 * @size: size of the buffer
673 * @err: unused
674 *
675 * Returns the size of the attribute or an error code
676 */
677static int smack_inode_getsecurity(const struct inode *inode,
678 const char *name, void **buffer,
679 bool alloc)
680{
681 struct socket_smack *ssp;
682 struct socket *sock;
683 struct super_block *sbp;
684 struct inode *ip = (struct inode *)inode;
685 char *isp;
686 int ilen;
687 int rc = 0;
688
689 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
690 isp = smk_of_inode(inode);
691 ilen = strlen(isp) + 1;
692 *buffer = isp;
693 return ilen;
694 }
695
696 /*
697 * The rest of the Smack xattrs are only on sockets.
698 */
699 sbp = ip->i_sb;
700 if (sbp->s_magic != SOCKFS_MAGIC)
701 return -EOPNOTSUPP;
702
703 sock = SOCKET_I(ip);
704 if (sock == NULL)
705 return -EOPNOTSUPP;
706
707 ssp = sock->sk->sk_security;
708
709 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
710 isp = ssp->smk_in;
711 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
712 isp = ssp->smk_out;
713 else
714 return -EOPNOTSUPP;
715
716 ilen = strlen(isp) + 1;
717 if (rc == 0) {
718 *buffer = isp;
719 rc = ilen;
720 }
721
722 return rc;
723}
724
725
726/**
727 * smack_inode_listsecurity - list the Smack attributes
728 * @inode: the object
729 * @buffer: where they go
730 * @buffer_size: size of buffer
731 *
732 * Returns 0 on success, -EINVAL otherwise
733 */
734static int smack_inode_listsecurity(struct inode *inode, char *buffer,
735 size_t buffer_size)
736{
737 int len = strlen(XATTR_NAME_SMACK);
738
739 if (buffer != NULL && len <= buffer_size) {
740 memcpy(buffer, XATTR_NAME_SMACK, len);
741 return len;
742 }
743 return -EINVAL;
744}
745
746/*
747 * File Hooks
748 */
749
750/**
751 * smack_file_permission - Smack check on file operations
752 * @file: unused
753 * @mask: unused
754 *
755 * Returns 0
756 *
757 * Should access checks be done on each read or write?
758 * UNICOS and SELinux say yes.
759 * Trusted Solaris, Trusted Irix, and just about everyone else says no.
760 *
761 * I'll say no for now. Smack does not do the frequent
762 * label changing that SELinux does.
763 */
764static int smack_file_permission(struct file *file, int mask)
765{
766 return 0;
767}
768
769/**
770 * smack_file_alloc_security - assign a file security blob
771 * @file: the object
772 *
773 * The security blob for a file is a pointer to the master
774 * label list, so no allocation is done.
775 *
776 * Returns 0
777 */
778static int smack_file_alloc_security(struct file *file)
779{
780 file->f_security = current->security;
781 return 0;
782}
783
784/**
785 * smack_file_free_security - clear a file security blob
786 * @file: the object
787 *
788 * The security blob for a file is a pointer to the master
789 * label list, so no memory is freed.
790 */
791static void smack_file_free_security(struct file *file)
792{
793 file->f_security = NULL;
794}
795
796/**
797 * smack_file_ioctl - Smack check on ioctls
798 * @file: the object
799 * @cmd: what to do
800 * @arg: unused
801 *
802 * Relies heavily on the correct use of the ioctl command conventions.
803 *
804 * Returns 0 if allowed, error code otherwise
805 */
806static int smack_file_ioctl(struct file *file, unsigned int cmd,
807 unsigned long arg)
808{
809 int rc = 0;
810
811 if (_IOC_DIR(cmd) & _IOC_WRITE)
812 rc = smk_curacc(file->f_security, MAY_WRITE);
813
814 if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ))
815 rc = smk_curacc(file->f_security, MAY_READ);
816
817 return rc;
818}
819
820/**
821 * smack_file_lock - Smack check on file locking
822 * @file: the object
823 * @cmd unused
824 *
825 * Returns 0 if current has write access, error code otherwise
826 */
827static int smack_file_lock(struct file *file, unsigned int cmd)
828{
829 return smk_curacc(file->f_security, MAY_WRITE);
830}
831
832/**
833 * smack_file_fcntl - Smack check on fcntl
834 * @file: the object
835 * @cmd: what action to check
836 * @arg: unused
837 *
838 * Returns 0 if current has access, error code otherwise
839 */
840static int smack_file_fcntl(struct file *file, unsigned int cmd,
841 unsigned long arg)
842{
843 int rc;
844
845 switch (cmd) {
846 case F_DUPFD:
847 case F_GETFD:
848 case F_GETFL:
849 case F_GETLK:
850 case F_GETOWN:
851 case F_GETSIG:
852 rc = smk_curacc(file->f_security, MAY_READ);
853 break;
854 case F_SETFD:
855 case F_SETFL:
856 case F_SETLK:
857 case F_SETLKW:
858 case F_SETOWN:
859 case F_SETSIG:
860 rc = smk_curacc(file->f_security, MAY_WRITE);
861 break;
862 default:
863 rc = smk_curacc(file->f_security, MAY_READWRITE);
864 }
865
866 return rc;
867}
868
869/**
870 * smack_file_set_fowner - set the file security blob value
871 * @file: object in question
872 *
873 * Returns 0
874 * Further research may be required on this one.
875 */
876static int smack_file_set_fowner(struct file *file)
877{
878 file->f_security = current->security;
879 return 0;
880}
881
882/**
883 * smack_file_send_sigiotask - Smack on sigio
884 * @tsk: The target task
885 * @fown: the object the signal come from
886 * @signum: unused
887 *
888 * Allow a privileged task to get signals even if it shouldn't
889 *
890 * Returns 0 if a subject with the object's smack could
891 * write to the task, an error code otherwise.
892 */
893static int smack_file_send_sigiotask(struct task_struct *tsk,
894 struct fown_struct *fown, int signum)
895{
896 struct file *file;
897 int rc;
898
899 /*
900 * struct fown_struct is never outside the context of a struct file
901 */
902 file = container_of(fown, struct file, f_owner);
903 rc = smk_access(file->f_security, tsk->security, MAY_WRITE);
904 if (rc != 0 && __capable(tsk, CAP_MAC_OVERRIDE))
905 return 0;
906 return rc;
907}
908
909/**
910 * smack_file_receive - Smack file receive check
911 * @file: the object
912 *
913 * Returns 0 if current has access, error code otherwise
914 */
915static int smack_file_receive(struct file *file)
916{
917 int may = 0;
918
919 /*
920 * This code relies on bitmasks.
921 */
922 if (file->f_mode & FMODE_READ)
923 may = MAY_READ;
924 if (file->f_mode & FMODE_WRITE)
925 may |= MAY_WRITE;
926
927 return smk_curacc(file->f_security, may);
928}
929
930/*
931 * Task hooks
932 */
933
934/**
935 * smack_task_alloc_security - "allocate" a task blob
936 * @tsk: the task in need of a blob
937 *
938 * Smack isn't using copies of blobs. Everyone
939 * points to an immutable list. No alloc required.
940 * No data copy required.
941 *
942 * Always returns 0
943 */
944static int smack_task_alloc_security(struct task_struct *tsk)
945{
946 tsk->security = current->security;
947
948 return 0;
949}
950
951/**
952 * smack_task_free_security - "free" a task blob
953 * @task: the task with the blob
954 *
955 * Smack isn't using copies of blobs. Everyone
956 * points to an immutable list. The blobs never go away.
957 * There is no leak here.
958 */
959static void smack_task_free_security(struct task_struct *task)
960{
961 task->security = NULL;
962}
963
964/**
965 * smack_task_setpgid - Smack check on setting pgid
966 * @p: the task object
967 * @pgid: unused
968 *
969 * Return 0 if write access is permitted
970 */
971static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
972{
973 return smk_curacc(p->security, MAY_WRITE);
974}
975
976/**
977 * smack_task_getpgid - Smack access check for getpgid
978 * @p: the object task
979 *
980 * Returns 0 if current can read the object task, error code otherwise
981 */
982static int smack_task_getpgid(struct task_struct *p)
983{
984 return smk_curacc(p->security, MAY_READ);
985}
986
987/**
988 * smack_task_getsid - Smack access check for getsid
989 * @p: the object task
990 *
991 * Returns 0 if current can read the object task, error code otherwise
992 */
993static int smack_task_getsid(struct task_struct *p)
994{
995 return smk_curacc(p->security, MAY_READ);
996}
997
998/**
999 * smack_task_getsecid - get the secid of the task
1000 * @p: the object task
1001 * @secid: where to put the result
1002 *
1003 * Sets the secid to contain a u32 version of the smack label.
1004 */
1005static void smack_task_getsecid(struct task_struct *p, u32 *secid)
1006{
1007 *secid = smack_to_secid(p->security);
1008}
1009
1010/**
1011 * smack_task_setnice - Smack check on setting nice
1012 * @p: the task object
1013 * @nice: unused
1014 *
1015 * Return 0 if write access is permitted
1016 */
1017static int smack_task_setnice(struct task_struct *p, int nice)
1018{
1019 return smk_curacc(p->security, MAY_WRITE);
1020}
1021
1022/**
1023 * smack_task_setioprio - Smack check on setting ioprio
1024 * @p: the task object
1025 * @ioprio: unused
1026 *
1027 * Return 0 if write access is permitted
1028 */
1029static int smack_task_setioprio(struct task_struct *p, int ioprio)
1030{
1031 return smk_curacc(p->security, MAY_WRITE);
1032}
1033
1034/**
1035 * smack_task_getioprio - Smack check on reading ioprio
1036 * @p: the task object
1037 *
1038 * Return 0 if read access is permitted
1039 */
1040static int smack_task_getioprio(struct task_struct *p)
1041{
1042 return smk_curacc(p->security, MAY_READ);
1043}
1044
1045/**
1046 * smack_task_setscheduler - Smack check on setting scheduler
1047 * @p: the task object
1048 * @policy: unused
1049 * @lp: unused
1050 *
1051 * Return 0 if read access is permitted
1052 */
1053static int smack_task_setscheduler(struct task_struct *p, int policy,
1054 struct sched_param *lp)
1055{
1056 return smk_curacc(p->security, MAY_WRITE);
1057}
1058
1059/**
1060 * smack_task_getscheduler - Smack check on reading scheduler
1061 * @p: the task object
1062 *
1063 * Return 0 if read access is permitted
1064 */
1065static int smack_task_getscheduler(struct task_struct *p)
1066{
1067 return smk_curacc(p->security, MAY_READ);
1068}
1069
1070/**
1071 * smack_task_movememory - Smack check on moving memory
1072 * @p: the task object
1073 *
1074 * Return 0 if write access is permitted
1075 */
1076static int smack_task_movememory(struct task_struct *p)
1077{
1078 return smk_curacc(p->security, MAY_WRITE);
1079}
1080
1081/**
1082 * smack_task_kill - Smack check on signal delivery
1083 * @p: the task object
1084 * @info: unused
1085 * @sig: unused
1086 * @secid: identifies the smack to use in lieu of current's
1087 *
1088 * Return 0 if write access is permitted
1089 *
1090 * The secid behavior is an artifact of an SELinux hack
1091 * in the USB code. Someday it may go away.
1092 */
1093static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1094 int sig, u32 secid)
1095{
1096 /*
1097 * Special cases where signals really ought to go through
1098 * in spite of policy. Stephen Smalley suggests it may
1099 * make sense to change the caller so that it doesn't
1100 * bother with the LSM hook in these cases.
1101 */
1102 if (info != SEND_SIG_NOINFO &&
1103 (is_si_special(info) || SI_FROMKERNEL(info)))
1104 return 0;
1105 /*
1106 * Sending a signal requires that the sender
1107 * can write the receiver.
1108 */
1109 if (secid == 0)
1110 return smk_curacc(p->security, MAY_WRITE);
1111 /*
1112 * If the secid isn't 0 we're dealing with some USB IO
1113 * specific behavior. This is not clean. For one thing
1114 * we can't take privilege into account.
1115 */
1116 return smk_access(smack_from_secid(secid), p->security, MAY_WRITE);
1117}
1118
1119/**
1120 * smack_task_wait - Smack access check for waiting
1121 * @p: task to wait for
1122 *
1123 * Returns 0 if current can wait for p, error code otherwise
1124 */
1125static int smack_task_wait(struct task_struct *p)
1126{
1127 int rc;
1128
1129 rc = smk_access(current->security, p->security, MAY_WRITE);
1130 if (rc == 0)
1131 return 0;
1132
1133 /*
1134 * Allow the operation to succeed if either task
1135 * has privilege to perform operations that might
1136 * account for the smack labels having gotten to
1137 * be different in the first place.
1138 *
1139 * This breaks the strict subjet/object access
1140 * control ideal, taking the object's privilege
1141 * state into account in the decision as well as
1142 * the smack value.
1143 */
1144 if (capable(CAP_MAC_OVERRIDE) || __capable(p, CAP_MAC_OVERRIDE))
1145 return 0;
1146
1147 return rc;
1148}
1149
1150/**
1151 * smack_task_to_inode - copy task smack into the inode blob
1152 * @p: task to copy from
1153 * inode: inode to copy to
1154 *
1155 * Sets the smack pointer in the inode security blob
1156 */
1157static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1158{
1159 struct inode_smack *isp = inode->i_security;
1160 isp->smk_inode = p->security;
1161}
1162
1163/*
1164 * Socket hooks.
1165 */
1166
1167/**
1168 * smack_sk_alloc_security - Allocate a socket blob
1169 * @sk: the socket
1170 * @family: unused
1171 * @priority: memory allocation priority
1172 *
1173 * Assign Smack pointers to current
1174 *
1175 * Returns 0 on success, -ENOMEM is there's no memory
1176 */
1177static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1178{
1179 char *csp = current->security;
1180 struct socket_smack *ssp;
1181
1182 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
1183 if (ssp == NULL)
1184 return -ENOMEM;
1185
1186 ssp->smk_in = csp;
1187 ssp->smk_out = csp;
1188 ssp->smk_packet[0] = '\0';
1189
1190 sk->sk_security = ssp;
1191
1192 return 0;
1193}
1194
1195/**
1196 * smack_sk_free_security - Free a socket blob
1197 * @sk: the socket
1198 *
1199 * Clears the blob pointer
1200 */
1201static void smack_sk_free_security(struct sock *sk)
1202{
1203 kfree(sk->sk_security);
1204}
1205
1206/**
1207 * smack_set_catset - convert a capset to netlabel mls categories
1208 * @catset: the Smack categories
1209 * @sap: where to put the netlabel categories
1210 *
1211 * Allocates and fills attr.mls.cat
1212 */
1213static void smack_set_catset(char *catset, struct netlbl_lsm_secattr *sap)
1214{
1215 unsigned char *cp;
1216 unsigned char m;
1217 int cat;
1218 int rc;
1219 int byte;
1220
1221 if (catset == 0)
1222 return;
1223
1224 sap->flags |= NETLBL_SECATTR_MLS_CAT;
1225 sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1226 sap->attr.mls.cat->startbit = 0;
1227
1228 for (cat = 1, cp = catset, byte = 0; byte < SMK_LABELLEN; cp++, byte++)
1229 for (m = 0x80; m != 0; m >>= 1, cat++) {
1230 if ((m & *cp) == 0)
1231 continue;
1232 rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat,
1233 cat, GFP_ATOMIC);
1234 }
1235}
1236
1237/**
1238 * smack_to_secattr - fill a secattr from a smack value
1239 * @smack: the smack value
1240 * @nlsp: where the result goes
1241 *
1242 * Casey says that CIPSO is good enough for now.
1243 * It can be used to effect.
1244 * It can also be abused to effect when necessary.
1245 * Appologies to the TSIG group in general and GW in particular.
1246 */
1247static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp)
1248{
1249 struct smack_cipso cipso;
1250 int rc;
1251
1252 switch (smack_net_nltype) {
1253 case NETLBL_NLTYPE_CIPSOV4:
1254 nlsp->domain = NULL;
1255 nlsp->flags = NETLBL_SECATTR_DOMAIN;
1256 nlsp->flags |= NETLBL_SECATTR_MLS_LVL;
1257
1258 rc = smack_to_cipso(smack, &cipso);
1259 if (rc == 0) {
1260 nlsp->attr.mls.lvl = cipso.smk_level;
1261 smack_set_catset(cipso.smk_catset, nlsp);
1262 } else {
1263 nlsp->attr.mls.lvl = smack_cipso_direct;
1264 smack_set_catset(smack, nlsp);
1265 }
1266 break;
1267 default:
1268 break;
1269 }
1270}
1271
1272/**
1273 * smack_netlabel - Set the secattr on a socket
1274 * @sk: the socket
1275 *
1276 * Convert the outbound smack value (smk_out) to a
1277 * secattr and attach it to the socket.
1278 *
1279 * Returns 0 on success or an error code
1280 */
1281static int smack_netlabel(struct sock *sk)
1282{
1283 struct socket_smack *ssp = sk->sk_security;
1284 struct netlbl_lsm_secattr secattr;
1285 int rc = 0;
1286
1287 netlbl_secattr_init(&secattr);
1288 smack_to_secattr(ssp->smk_out, &secattr);
1289 if (secattr.flags != NETLBL_SECATTR_NONE)
1290 rc = netlbl_sock_setattr(sk, &secattr);
1291
1292 netlbl_secattr_destroy(&secattr);
1293 return rc;
1294}
1295
1296/**
1297 * smack_inode_setsecurity - set smack xattrs
1298 * @inode: the object
1299 * @name: attribute name
1300 * @value: attribute value
1301 * @size: size of the attribute
1302 * @flags: unused
1303 *
1304 * Sets the named attribute in the appropriate blob
1305 *
1306 * Returns 0 on success, or an error code
1307 */
1308static int smack_inode_setsecurity(struct inode *inode, const char *name,
1309 const void *value, size_t size, int flags)
1310{
1311 char *sp;
1312 struct inode_smack *nsp = inode->i_security;
1313 struct socket_smack *ssp;
1314 struct socket *sock;
1315
1316 if (value == NULL || size > SMK_LABELLEN)
1317 return -EACCES;
1318
1319 sp = smk_import(value, size);
1320 if (sp == NULL)
1321 return -EINVAL;
1322
1323 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
1324 nsp->smk_inode = sp;
1325 return 0;
1326 }
1327 /*
1328 * The rest of the Smack xattrs are only on sockets.
1329 */
1330 if (inode->i_sb->s_magic != SOCKFS_MAGIC)
1331 return -EOPNOTSUPP;
1332
1333 sock = SOCKET_I(inode);
1334 if (sock == NULL)
1335 return -EOPNOTSUPP;
1336
1337 ssp = sock->sk->sk_security;
1338
1339 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
1340 ssp->smk_in = sp;
1341 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
1342 ssp->smk_out = sp;
1343 return smack_netlabel(sock->sk);
1344 } else
1345 return -EOPNOTSUPP;
1346
1347 return 0;
1348}
1349
1350/**
1351 * smack_socket_post_create - finish socket setup
1352 * @sock: the socket
1353 * @family: protocol family
1354 * @type: unused
1355 * @protocol: unused
1356 * @kern: unused
1357 *
1358 * Sets the netlabel information on the socket
1359 *
1360 * Returns 0 on success, and error code otherwise
1361 */
1362static int smack_socket_post_create(struct socket *sock, int family,
1363 int type, int protocol, int kern)
1364{
1365 if (family != PF_INET)
1366 return 0;
1367 /*
1368 * Set the outbound netlbl.
1369 */
1370 return smack_netlabel(sock->sk);
1371}
1372
1373/**
1374 * smack_flags_to_may - convert S_ to MAY_ values
1375 * @flags: the S_ value
1376 *
1377 * Returns the equivalent MAY_ value
1378 */
1379static int smack_flags_to_may(int flags)
1380{
1381 int may = 0;
1382
1383 if (flags & S_IRUGO)
1384 may |= MAY_READ;
1385 if (flags & S_IWUGO)
1386 may |= MAY_WRITE;
1387 if (flags & S_IXUGO)
1388 may |= MAY_EXEC;
1389
1390 return may;
1391}
1392
1393/**
1394 * smack_msg_msg_alloc_security - Set the security blob for msg_msg
1395 * @msg: the object
1396 *
1397 * Returns 0
1398 */
1399static int smack_msg_msg_alloc_security(struct msg_msg *msg)
1400{
1401 msg->security = current->security;
1402 return 0;
1403}
1404
1405/**
1406 * smack_msg_msg_free_security - Clear the security blob for msg_msg
1407 * @msg: the object
1408 *
1409 * Clears the blob pointer
1410 */
1411static void smack_msg_msg_free_security(struct msg_msg *msg)
1412{
1413 msg->security = NULL;
1414}
1415
1416/**
1417 * smack_of_shm - the smack pointer for the shm
1418 * @shp: the object
1419 *
1420 * Returns a pointer to the smack value
1421 */
1422static char *smack_of_shm(struct shmid_kernel *shp)
1423{
1424 return (char *)shp->shm_perm.security;
1425}
1426
1427/**
1428 * smack_shm_alloc_security - Set the security blob for shm
1429 * @shp: the object
1430 *
1431 * Returns 0
1432 */
1433static int smack_shm_alloc_security(struct shmid_kernel *shp)
1434{
1435 struct kern_ipc_perm *isp = &shp->shm_perm;
1436
1437 isp->security = current->security;
1438 return 0;
1439}
1440
1441/**
1442 * smack_shm_free_security - Clear the security blob for shm
1443 * @shp: the object
1444 *
1445 * Clears the blob pointer
1446 */
1447static void smack_shm_free_security(struct shmid_kernel *shp)
1448{
1449 struct kern_ipc_perm *isp = &shp->shm_perm;
1450
1451 isp->security = NULL;
1452}
1453
1454/**
1455 * smack_shm_associate - Smack access check for shm
1456 * @shp: the object
1457 * @shmflg: access requested
1458 *
1459 * Returns 0 if current has the requested access, error code otherwise
1460 */
1461static int smack_shm_associate(struct shmid_kernel *shp, int shmflg)
1462{
1463 char *ssp = smack_of_shm(shp);
1464 int may;
1465
1466 may = smack_flags_to_may(shmflg);
1467 return smk_curacc(ssp, may);
1468}
1469
1470/**
1471 * smack_shm_shmctl - Smack access check for shm
1472 * @shp: the object
1473 * @cmd: what it wants to do
1474 *
1475 * Returns 0 if current has the requested access, error code otherwise
1476 */
1477static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd)
1478{
1479 char *ssp = smack_of_shm(shp);
1480 int may;
1481
1482 switch (cmd) {
1483 case IPC_STAT:
1484 case SHM_STAT:
1485 may = MAY_READ;
1486 break;
1487 case IPC_SET:
1488 case SHM_LOCK:
1489 case SHM_UNLOCK:
1490 case IPC_RMID:
1491 may = MAY_READWRITE;
1492 break;
1493 case IPC_INFO:
1494 case SHM_INFO:
1495 /*
1496 * System level information.
1497 */
1498 return 0;
1499 default:
1500 return -EINVAL;
1501 }
1502
1503 return smk_curacc(ssp, may);
1504}
1505
1506/**
1507 * smack_shm_shmat - Smack access for shmat
1508 * @shp: the object
1509 * @shmaddr: unused
1510 * @shmflg: access requested
1511 *
1512 * Returns 0 if current has the requested access, error code otherwise
1513 */
1514static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
1515 int shmflg)
1516{
1517 char *ssp = smack_of_shm(shp);
1518 int may;
1519
1520 may = smack_flags_to_may(shmflg);
1521 return smk_curacc(ssp, may);
1522}
1523
1524/**
1525 * smack_of_sem - the smack pointer for the sem
1526 * @sma: the object
1527 *
1528 * Returns a pointer to the smack value
1529 */
1530static char *smack_of_sem(struct sem_array *sma)
1531{
1532 return (char *)sma->sem_perm.security;
1533}
1534
1535/**
1536 * smack_sem_alloc_security - Set the security blob for sem
1537 * @sma: the object
1538 *
1539 * Returns 0
1540 */
1541static int smack_sem_alloc_security(struct sem_array *sma)
1542{
1543 struct kern_ipc_perm *isp = &sma->sem_perm;
1544
1545 isp->security = current->security;
1546 return 0;
1547}
1548
1549/**
1550 * smack_sem_free_security - Clear the security blob for sem
1551 * @sma: the object
1552 *
1553 * Clears the blob pointer
1554 */
1555static void smack_sem_free_security(struct sem_array *sma)
1556{
1557 struct kern_ipc_perm *isp = &sma->sem_perm;
1558
1559 isp->security = NULL;
1560}
1561
1562/**
1563 * smack_sem_associate - Smack access check for sem
1564 * @sma: the object
1565 * @semflg: access requested
1566 *
1567 * Returns 0 if current has the requested access, error code otherwise
1568 */
1569static int smack_sem_associate(struct sem_array *sma, int semflg)
1570{
1571 char *ssp = smack_of_sem(sma);
1572 int may;
1573
1574 may = smack_flags_to_may(semflg);
1575 return smk_curacc(ssp, may);
1576}
1577
1578/**
1579 * smack_sem_shmctl - Smack access check for sem
1580 * @sma: the object
1581 * @cmd: what it wants to do
1582 *
1583 * Returns 0 if current has the requested access, error code otherwise
1584 */
1585static int smack_sem_semctl(struct sem_array *sma, int cmd)
1586{
1587 char *ssp = smack_of_sem(sma);
1588 int may;
1589
1590 switch (cmd) {
1591 case GETPID:
1592 case GETNCNT:
1593 case GETZCNT:
1594 case GETVAL:
1595 case GETALL:
1596 case IPC_STAT:
1597 case SEM_STAT:
1598 may = MAY_READ;
1599 break;
1600 case SETVAL:
1601 case SETALL:
1602 case IPC_RMID:
1603 case IPC_SET:
1604 may = MAY_READWRITE;
1605 break;
1606 case IPC_INFO:
1607 case SEM_INFO:
1608 /*
1609 * System level information
1610 */
1611 return 0;
1612 default:
1613 return -EINVAL;
1614 }
1615
1616 return smk_curacc(ssp, may);
1617}
1618
1619/**
1620 * smack_sem_semop - Smack checks of semaphore operations
1621 * @sma: the object
1622 * @sops: unused
1623 * @nsops: unused
1624 * @alter: unused
1625 *
1626 * Treated as read and write in all cases.
1627 *
1628 * Returns 0 if access is allowed, error code otherwise
1629 */
1630static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
1631 unsigned nsops, int alter)
1632{
1633 char *ssp = smack_of_sem(sma);
1634
1635 return smk_curacc(ssp, MAY_READWRITE);
1636}
1637
1638/**
1639 * smack_msg_alloc_security - Set the security blob for msg
1640 * @msq: the object
1641 *
1642 * Returns 0
1643 */
1644static int smack_msg_queue_alloc_security(struct msg_queue *msq)
1645{
1646 struct kern_ipc_perm *kisp = &msq->q_perm;
1647
1648 kisp->security = current->security;
1649 return 0;
1650}
1651
1652/**
1653 * smack_msg_free_security - Clear the security blob for msg
1654 * @msq: the object
1655 *
1656 * Clears the blob pointer
1657 */
1658static void smack_msg_queue_free_security(struct msg_queue *msq)
1659{
1660 struct kern_ipc_perm *kisp = &msq->q_perm;
1661
1662 kisp->security = NULL;
1663}
1664
1665/**
1666 * smack_of_msq - the smack pointer for the msq
1667 * @msq: the object
1668 *
1669 * Returns a pointer to the smack value
1670 */
1671static char *smack_of_msq(struct msg_queue *msq)
1672{
1673 return (char *)msq->q_perm.security;
1674}
1675
1676/**
1677 * smack_msg_queue_associate - Smack access check for msg_queue
1678 * @msq: the object
1679 * @msqflg: access requested
1680 *
1681 * Returns 0 if current has the requested access, error code otherwise
1682 */
1683static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg)
1684{
1685 char *msp = smack_of_msq(msq);
1686 int may;
1687
1688 may = smack_flags_to_may(msqflg);
1689 return smk_curacc(msp, may);
1690}
1691
1692/**
1693 * smack_msg_queue_msgctl - Smack access check for msg_queue
1694 * @msq: the object
1695 * @cmd: what it wants to do
1696 *
1697 * Returns 0 if current has the requested access, error code otherwise
1698 */
1699static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd)
1700{
1701 char *msp = smack_of_msq(msq);
1702 int may;
1703
1704 switch (cmd) {
1705 case IPC_STAT:
1706 case MSG_STAT:
1707 may = MAY_READ;
1708 break;
1709 case IPC_SET:
1710 case IPC_RMID:
1711 may = MAY_READWRITE;
1712 break;
1713 case IPC_INFO:
1714 case MSG_INFO:
1715 /*
1716 * System level information
1717 */
1718 return 0;
1719 default:
1720 return -EINVAL;
1721 }
1722
1723 return smk_curacc(msp, may);
1724}
1725
1726/**
1727 * smack_msg_queue_msgsnd - Smack access check for msg_queue
1728 * @msq: the object
1729 * @msg: unused
1730 * @msqflg: access requested
1731 *
1732 * Returns 0 if current has the requested access, error code otherwise
1733 */
1734static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
1735 int msqflg)
1736{
1737 char *msp = smack_of_msq(msq);
1738 int rc;
1739
1740 rc = smack_flags_to_may(msqflg);
1741 return smk_curacc(msp, rc);
1742}
1743
1744/**
1745 * smack_msg_queue_msgsnd - Smack access check for msg_queue
1746 * @msq: the object
1747 * @msg: unused
1748 * @target: unused
1749 * @type: unused
1750 * @mode: unused
1751 *
1752 * Returns 0 if current has read and write access, error code otherwise
1753 */
1754static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
1755 struct task_struct *target, long type, int mode)
1756{
1757 char *msp = smack_of_msq(msq);
1758
1759 return smk_curacc(msp, MAY_READWRITE);
1760}
1761
1762/**
1763 * smack_ipc_permission - Smack access for ipc_permission()
1764 * @ipp: the object permissions
1765 * @flag: access requested
1766 *
1767 * Returns 0 if current has read and write access, error code otherwise
1768 */
1769static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
1770{
1771 char *isp = ipp->security;
1772 int may;
1773
1774 may = smack_flags_to_may(flag);
1775 return smk_curacc(isp, may);
1776}
1777
1778/**
1779 * smack_d_instantiate - Make sure the blob is correct on an inode
1780 * @opt_dentry: unused
1781 * @inode: the object
1782 *
1783 * Set the inode's security blob if it hasn't been done already.
1784 */
1785static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
1786{
1787 struct super_block *sbp;
1788 struct superblock_smack *sbsp;
1789 struct inode_smack *isp;
1790 char *csp = current->security;
1791 char *fetched;
1792 char *final;
1793 struct dentry *dp;
1794
1795 if (inode == NULL)
1796 return;
1797
1798 isp = inode->i_security;
1799
1800 mutex_lock(&isp->smk_lock);
1801 /*
1802 * If the inode is already instantiated
1803 * take the quick way out
1804 */
1805 if (isp->smk_flags & SMK_INODE_INSTANT)
1806 goto unlockandout;
1807
1808 sbp = inode->i_sb;
1809 sbsp = sbp->s_security;
1810 /*
1811 * We're going to use the superblock default label
1812 * if there's no label on the file.
1813 */
1814 final = sbsp->smk_default;
1815
1816 /*
1817 * This is pretty hackish.
1818 * Casey says that we shouldn't have to do
1819 * file system specific code, but it does help
1820 * with keeping it simple.
1821 */
1822 switch (sbp->s_magic) {
1823 case SMACK_MAGIC:
1824 /*
1825 * Casey says that it's a little embarassing
1826 * that the smack file system doesn't do
1827 * extended attributes.
1828 */
1829 final = smack_known_star.smk_known;
1830 break;
1831 case PIPEFS_MAGIC:
1832 /*
1833 * Casey says pipes are easy (?)
1834 */
1835 final = smack_known_star.smk_known;
1836 break;
1837 case DEVPTS_SUPER_MAGIC:
1838 /*
1839 * devpts seems content with the label of the task.
1840 * Programs that change smack have to treat the
1841 * pty with respect.
1842 */
1843 final = csp;
1844 break;
1845 case SOCKFS_MAGIC:
1846 /*
1847 * Casey says sockets get the smack of the task.
1848 */
1849 final = csp;
1850 break;
1851 case PROC_SUPER_MAGIC:
1852 /*
1853 * Casey says procfs appears not to care.
1854 * The superblock default suffices.
1855 */
1856 break;
1857 case TMPFS_MAGIC:
1858 /*
1859 * Device labels should come from the filesystem,
1860 * but watch out, because they're volitile,
1861 * getting recreated on every reboot.
1862 */
1863 final = smack_known_star.smk_known;
1864 /*
1865 * No break.
1866 *
1867 * If a smack value has been set we want to use it,
1868 * but since tmpfs isn't giving us the opportunity
1869 * to set mount options simulate setting the
1870 * superblock default.
1871 */
1872 default:
1873 /*
1874 * This isn't an understood special case.
1875 * Get the value from the xattr.
1876 *
1877 * No xattr support means, alas, no SMACK label.
1878 * Use the aforeapplied default.
1879 * It would be curious if the label of the task
1880 * does not match that assigned.
1881 */
1882 if (inode->i_op->getxattr == NULL)
1883 break;
1884 /*
1885 * Get the dentry for xattr.
1886 */
1887 if (opt_dentry == NULL) {
1888 dp = d_find_alias(inode);
1889 if (dp == NULL)
1890 break;
1891 } else {
1892 dp = dget(opt_dentry);
1893 if (dp == NULL)
1894 break;
1895 }
1896
1897 fetched = smk_fetch(inode, dp);
1898 if (fetched != NULL)
1899 final = fetched;
1900
1901 dput(dp);
1902 break;
1903 }
1904
1905 if (final == NULL)
1906 isp->smk_inode = csp;
1907 else
1908 isp->smk_inode = final;
1909
1910 isp->smk_flags |= SMK_INODE_INSTANT;
1911
1912unlockandout:
1913 mutex_unlock(&isp->smk_lock);
1914 return;
1915}
1916
1917/**
1918 * smack_getprocattr - Smack process attribute access
1919 * @p: the object task
1920 * @name: the name of the attribute in /proc/.../attr
1921 * @value: where to put the result
1922 *
1923 * Places a copy of the task Smack into value
1924 *
1925 * Returns the length of the smack label or an error code
1926 */
1927static int smack_getprocattr(struct task_struct *p, char *name, char **value)
1928{
1929 char *cp;
1930 int slen;
1931
1932 if (strcmp(name, "current") != 0)
1933 return -EINVAL;
1934
1935 cp = kstrdup(p->security, GFP_KERNEL);
1936 if (cp == NULL)
1937 return -ENOMEM;
1938
1939 slen = strlen(cp);
1940 *value = cp;
1941 return slen;
1942}
1943
1944/**
1945 * smack_setprocattr - Smack process attribute setting
1946 * @p: the object task
1947 * @name: the name of the attribute in /proc/.../attr
1948 * @value: the value to set
1949 * @size: the size of the value
1950 *
1951 * Sets the Smack value of the task. Only setting self
1952 * is permitted and only with privilege
1953 *
1954 * Returns the length of the smack label or an error code
1955 */
1956static int smack_setprocattr(struct task_struct *p, char *name,
1957 void *value, size_t size)
1958{
1959 char *newsmack;
1960
1961 if (!__capable(p, CAP_MAC_ADMIN))
1962 return -EPERM;
1963
1964 /*
1965 * Changing another process' Smack value is too dangerous
1966 * and supports no sane use case.
1967 */
1968 if (p != current)
1969 return -EPERM;
1970
1971 if (value == NULL || size == 0 || size >= SMK_LABELLEN)
1972 return -EINVAL;
1973
1974 if (strcmp(name, "current") != 0)
1975 return -EINVAL;
1976
1977 newsmack = smk_import(value, size);
1978 if (newsmack == NULL)
1979 return -EINVAL;
1980
1981 p->security = newsmack;
1982 return size;
1983}
1984
1985/**
1986 * smack_unix_stream_connect - Smack access on UDS
1987 * @sock: one socket
1988 * @other: the other socket
1989 * @newsk: unused
1990 *
1991 * Return 0 if a subject with the smack of sock could access
1992 * an object with the smack of other, otherwise an error code
1993 */
1994static int smack_unix_stream_connect(struct socket *sock,
1995 struct socket *other, struct sock *newsk)
1996{
1997 struct inode *sp = SOCK_INODE(sock);
1998 struct inode *op = SOCK_INODE(other);
1999
2000 return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_READWRITE);
2001}
2002
2003/**
2004 * smack_unix_may_send - Smack access on UDS
2005 * @sock: one socket
2006 * @other: the other socket
2007 *
2008 * Return 0 if a subject with the smack of sock could access
2009 * an object with the smack of other, otherwise an error code
2010 */
2011static int smack_unix_may_send(struct socket *sock, struct socket *other)
2012{
2013 struct inode *sp = SOCK_INODE(sock);
2014 struct inode *op = SOCK_INODE(other);
2015
2016 return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE);
2017}
2018
2019/**
2020 * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat
2021 * pair to smack
2022 * @sap: netlabel secattr
2023 * @sip: where to put the result
2024 *
2025 * Copies a smack label into sip
2026 */
2027static void smack_from_secattr(struct netlbl_lsm_secattr *sap, char *sip)
2028{
2029 char smack[SMK_LABELLEN];
2030 int pcat;
2031
2032 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) == 0) {
2033 /*
2034 * If there are flags but no level netlabel isn't
2035 * behaving the way we expect it to.
2036 *
2037 * Without guidance regarding the smack value
2038 * for the packet fall back on the network
2039 * ambient value.
2040 */
2041 strncpy(sip, smack_net_ambient, SMK_MAXLEN);
2042 return;
2043 }
2044 /*
2045 * Get the categories, if any
2046 */
2047 memset(smack, '\0', SMK_LABELLEN);
2048 if ((sap->flags & NETLBL_SECATTR_MLS_CAT) != 0)
2049 for (pcat = -1;;) {
2050 pcat = netlbl_secattr_catmap_walk(sap->attr.mls.cat,
2051 pcat + 1);
2052 if (pcat < 0)
2053 break;
2054 smack_catset_bit(pcat, smack);
2055 }
2056 /*
2057 * If it is CIPSO using smack direct mapping
2058 * we are already done. WeeHee.
2059 */
2060 if (sap->attr.mls.lvl == smack_cipso_direct) {
2061 memcpy(sip, smack, SMK_MAXLEN);
2062 return;
2063 }
2064 /*
2065 * Look it up in the supplied table if it is not a direct mapping.
2066 */
2067 smack_from_cipso(sap->attr.mls.lvl, smack, sip);
2068 return;
2069}
2070
2071/**
2072 * smack_socket_sock_rcv_skb - Smack packet delivery access check
2073 * @sk: socket
2074 * @skb: packet
2075 *
2076 * Returns 0 if the packet should be delivered, an error code otherwise
2077 */
2078static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2079{
2080 struct netlbl_lsm_secattr secattr;
2081 struct socket_smack *ssp = sk->sk_security;
2082 char smack[SMK_LABELLEN];
2083 int rc;
2084
2085 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
2086 return 0;
2087
2088 /*
2089 * Translate what netlabel gave us.
2090 */
2091 memset(smack, '\0', SMK_LABELLEN);
2092 netlbl_secattr_init(&secattr);
2093 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
2094 if (rc == 0)
2095 smack_from_secattr(&secattr, smack);
2096 else
2097 strncpy(smack, smack_net_ambient, SMK_MAXLEN);
2098 netlbl_secattr_destroy(&secattr);
2099 /*
2100 * Receiving a packet requires that the other end
2101 * be able to write here. Read access is not required.
2102 * This is the simplist possible security model
2103 * for networking.
2104 */
2105 return smk_access(smack, ssp->smk_in, MAY_WRITE);
2106}
2107
2108/**
2109 * smack_socket_getpeersec_stream - pull in packet label
2110 * @sock: the socket
2111 * @optval: user's destination
2112 * @optlen: size thereof
2113 * @len: max thereoe
2114 *
2115 * returns zero on success, an error code otherwise
2116 */
2117static int smack_socket_getpeersec_stream(struct socket *sock,
2118 char __user *optval,
2119 int __user *optlen, unsigned len)
2120{
2121 struct socket_smack *ssp;
2122 int slen;
2123 int rc = 0;
2124
2125 ssp = sock->sk->sk_security;
2126 slen = strlen(ssp->smk_packet) + 1;
2127
2128 if (slen > len)
2129 rc = -ERANGE;
2130 else if (copy_to_user(optval, ssp->smk_packet, slen) != 0)
2131 rc = -EFAULT;
2132
2133 if (put_user(slen, optlen) != 0)
2134 rc = -EFAULT;
2135
2136 return rc;
2137}
2138
2139
2140/**
2141 * smack_socket_getpeersec_dgram - pull in packet label
2142 * @sock: the socket
2143 * @skb: packet data
2144 * @secid: pointer to where to put the secid of the packet
2145 *
2146 * Sets the netlabel socket state on sk from parent
2147 */
2148static int smack_socket_getpeersec_dgram(struct socket *sock,
2149 struct sk_buff *skb, u32 *secid)
2150
2151{
2152 struct netlbl_lsm_secattr secattr;
2153 struct sock *sk;
2154 char smack[SMK_LABELLEN];
2155 int family = PF_INET;
2156 u32 s;
2157 int rc;
2158
2159 /*
2160 * Only works for families with packets.
2161 */
2162 if (sock != NULL) {
2163 sk = sock->sk;
2164 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
2165 return 0;
2166 family = sk->sk_family;
2167 }
2168 /*
2169 * Translate what netlabel gave us.
2170 */
2171 memset(smack, '\0', SMK_LABELLEN);
2172 netlbl_secattr_init(&secattr);
2173 rc = netlbl_skbuff_getattr(skb, family, &secattr);
2174 if (rc == 0)
2175 smack_from_secattr(&secattr, smack);
2176 netlbl_secattr_destroy(&secattr);
2177
2178 /*
2179 * Give up if we couldn't get anything
2180 */
2181 if (rc != 0)
2182 return rc;
2183
2184 s = smack_to_secid(smack);
2185 if (s == 0)
2186 return -EINVAL;
2187
2188 *secid = s;
2189 return 0;
2190}
2191
2192/**
2193 * smack_sock_graft - graft access state between two sockets
2194 * @sk: fresh sock
2195 * @parent: donor socket
2196 *
2197 * Sets the netlabel socket state on sk from parent
2198 */
2199static void smack_sock_graft(struct sock *sk, struct socket *parent)
2200{
2201 struct socket_smack *ssp;
2202 int rc;
2203
2204 if (sk == NULL)
2205 return;
2206
2207 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
2208 return;
2209
2210 ssp = sk->sk_security;
2211 ssp->smk_in = current->security;
2212 ssp->smk_out = current->security;
2213 ssp->smk_packet[0] = '\0';
2214
2215 rc = smack_netlabel(sk);
2216}
2217
2218/**
2219 * smack_inet_conn_request - Smack access check on connect
2220 * @sk: socket involved
2221 * @skb: packet
2222 * @req: unused
2223 *
2224 * Returns 0 if a task with the packet label could write to
2225 * the socket, otherwise an error code
2226 */
2227static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
2228 struct request_sock *req)
2229{
2230 struct netlbl_lsm_secattr skb_secattr;
2231 struct socket_smack *ssp = sk->sk_security;
2232 char smack[SMK_LABELLEN];
2233 int rc;
2234
2235 if (skb == NULL)
2236 return -EACCES;
2237
2238 memset(smack, '\0', SMK_LABELLEN);
2239 netlbl_secattr_init(&skb_secattr);
2240 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &skb_secattr);
2241 if (rc == 0)
2242 smack_from_secattr(&skb_secattr, smack);
2243 else
2244 strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN);
2245 netlbl_secattr_destroy(&skb_secattr);
2246 /*
2247 * Receiving a packet requires that the other end
2248 * be able to write here. Read access is not required.
2249 *
2250 * If the request is successful save the peer's label
2251 * so that SO_PEERCRED can report it.
2252 */
2253 rc = smk_access(smack, ssp->smk_in, MAY_WRITE);
2254 if (rc == 0)
2255 strncpy(ssp->smk_packet, smack, SMK_MAXLEN);
2256
2257 return rc;
2258}
2259
2260/*
2261 * Key management security hooks
2262 *
2263 * Casey has not tested key support very heavily.
2264 * The permission check is most likely too restrictive.
2265 * If you care about keys please have a look.
2266 */
2267#ifdef CONFIG_KEYS
2268
2269/**
2270 * smack_key_alloc - Set the key security blob
2271 * @key: object
2272 * @tsk: the task associated with the key
2273 * @flags: unused
2274 *
2275 * No allocation required
2276 *
2277 * Returns 0
2278 */
2279static int smack_key_alloc(struct key *key, struct task_struct *tsk,
2280 unsigned long flags)
2281{
2282 key->security = tsk->security;
2283 return 0;
2284}
2285
2286/**
2287 * smack_key_free - Clear the key security blob
2288 * @key: the object
2289 *
2290 * Clear the blob pointer
2291 */
2292static void smack_key_free(struct key *key)
2293{
2294 key->security = NULL;
2295}
2296
2297/*
2298 * smack_key_permission - Smack access on a key
2299 * @key_ref: gets to the object
2300 * @context: task involved
2301 * @perm: unused
2302 *
2303 * Return 0 if the task has read and write to the object,
2304 * an error code otherwise
2305 */
2306static int smack_key_permission(key_ref_t key_ref,
2307 struct task_struct *context, key_perm_t perm)
2308{
2309 struct key *keyp;
2310
2311 keyp = key_ref_to_ptr(key_ref);
2312 if (keyp == NULL)
2313 return -EINVAL;
2314 /*
2315 * If the key hasn't been initialized give it access so that
2316 * it may do so.
2317 */
2318 if (keyp->security == NULL)
2319 return 0;
2320 /*
2321 * This should not occur
2322 */
2323 if (context->security == NULL)
2324 return -EACCES;
2325
2326 return smk_access(context->security, keyp->security, MAY_READWRITE);
2327}
2328#endif /* CONFIG_KEYS */
2329
2330/*
2331 * smack_secid_to_secctx - return the smack label for a secid
2332 * @secid: incoming integer
2333 * @secdata: destination
2334 * @seclen: how long it is
2335 *
2336 * Exists for networking code.
2337 */
2338static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
2339{
2340 char *sp = smack_from_secid(secid);
2341
2342 *secdata = sp;
2343 *seclen = strlen(sp);
2344 return 0;
2345}
2346
2347/*
2348 * smack_release_secctx - don't do anything.
2349 * @key_ref: unused
2350 * @context: unused
2351 * @perm: unused
2352 *
2353 * Exists to make sure nothing gets done, and properly
2354 */
2355static void smack_release_secctx(char *secdata, u32 seclen)
2356{
2357}
2358
2359static struct security_operations smack_ops = {
2360 .ptrace = smack_ptrace,
2361 .capget = cap_capget,
2362 .capset_check = cap_capset_check,
2363 .capset_set = cap_capset_set,
2364 .capable = cap_capable,
2365 .syslog = smack_syslog,
2366 .settime = cap_settime,
2367 .vm_enough_memory = cap_vm_enough_memory,
2368
2369 .bprm_apply_creds = cap_bprm_apply_creds,
2370 .bprm_set_security = cap_bprm_set_security,
2371 .bprm_secureexec = cap_bprm_secureexec,
2372
2373 .sb_alloc_security = smack_sb_alloc_security,
2374 .sb_free_security = smack_sb_free_security,
2375 .sb_copy_data = smack_sb_copy_data,
2376 .sb_kern_mount = smack_sb_kern_mount,
2377 .sb_statfs = smack_sb_statfs,
2378 .sb_mount = smack_sb_mount,
2379 .sb_umount = smack_sb_umount,
2380
2381 .inode_alloc_security = smack_inode_alloc_security,
2382 .inode_free_security = smack_inode_free_security,
2383 .inode_init_security = smack_inode_init_security,
2384 .inode_link = smack_inode_link,
2385 .inode_unlink = smack_inode_unlink,
2386 .inode_rmdir = smack_inode_rmdir,
2387 .inode_rename = smack_inode_rename,
2388 .inode_permission = smack_inode_permission,
2389 .inode_setattr = smack_inode_setattr,
2390 .inode_getattr = smack_inode_getattr,
2391 .inode_setxattr = smack_inode_setxattr,
2392 .inode_post_setxattr = smack_inode_post_setxattr,
2393 .inode_getxattr = smack_inode_getxattr,
2394 .inode_removexattr = smack_inode_removexattr,
2395 .inode_getsecurity = smack_inode_getsecurity,
2396 .inode_setsecurity = smack_inode_setsecurity,
2397 .inode_listsecurity = smack_inode_listsecurity,
2398
2399 .file_permission = smack_file_permission,
2400 .file_alloc_security = smack_file_alloc_security,
2401 .file_free_security = smack_file_free_security,
2402 .file_ioctl = smack_file_ioctl,
2403 .file_lock = smack_file_lock,
2404 .file_fcntl = smack_file_fcntl,
2405 .file_set_fowner = smack_file_set_fowner,
2406 .file_send_sigiotask = smack_file_send_sigiotask,
2407 .file_receive = smack_file_receive,
2408
2409 .task_alloc_security = smack_task_alloc_security,
2410 .task_free_security = smack_task_free_security,
2411 .task_post_setuid = cap_task_post_setuid,
2412 .task_setpgid = smack_task_setpgid,
2413 .task_getpgid = smack_task_getpgid,
2414 .task_getsid = smack_task_getsid,
2415 .task_getsecid = smack_task_getsecid,
2416 .task_setnice = smack_task_setnice,
2417 .task_setioprio = smack_task_setioprio,
2418 .task_getioprio = smack_task_getioprio,
2419 .task_setscheduler = smack_task_setscheduler,
2420 .task_getscheduler = smack_task_getscheduler,
2421 .task_movememory = smack_task_movememory,
2422 .task_kill = smack_task_kill,
2423 .task_wait = smack_task_wait,
2424 .task_reparent_to_init = cap_task_reparent_to_init,
2425 .task_to_inode = smack_task_to_inode,
2426
2427 .ipc_permission = smack_ipc_permission,
2428
2429 .msg_msg_alloc_security = smack_msg_msg_alloc_security,
2430 .msg_msg_free_security = smack_msg_msg_free_security,
2431
2432 .msg_queue_alloc_security = smack_msg_queue_alloc_security,
2433 .msg_queue_free_security = smack_msg_queue_free_security,
2434 .msg_queue_associate = smack_msg_queue_associate,
2435 .msg_queue_msgctl = smack_msg_queue_msgctl,
2436 .msg_queue_msgsnd = smack_msg_queue_msgsnd,
2437 .msg_queue_msgrcv = smack_msg_queue_msgrcv,
2438
2439 .shm_alloc_security = smack_shm_alloc_security,
2440 .shm_free_security = smack_shm_free_security,
2441 .shm_associate = smack_shm_associate,
2442 .shm_shmctl = smack_shm_shmctl,
2443 .shm_shmat = smack_shm_shmat,
2444
2445 .sem_alloc_security = smack_sem_alloc_security,
2446 .sem_free_security = smack_sem_free_security,
2447 .sem_associate = smack_sem_associate,
2448 .sem_semctl = smack_sem_semctl,
2449 .sem_semop = smack_sem_semop,
2450
2451 .netlink_send = cap_netlink_send,
2452 .netlink_recv = cap_netlink_recv,
2453
2454 .d_instantiate = smack_d_instantiate,
2455
2456 .getprocattr = smack_getprocattr,
2457 .setprocattr = smack_setprocattr,
2458
2459 .unix_stream_connect = smack_unix_stream_connect,
2460 .unix_may_send = smack_unix_may_send,
2461
2462 .socket_post_create = smack_socket_post_create,
2463 .socket_sock_rcv_skb = smack_socket_sock_rcv_skb,
2464 .socket_getpeersec_stream = smack_socket_getpeersec_stream,
2465 .socket_getpeersec_dgram = smack_socket_getpeersec_dgram,
2466 .sk_alloc_security = smack_sk_alloc_security,
2467 .sk_free_security = smack_sk_free_security,
2468 .sock_graft = smack_sock_graft,
2469 .inet_conn_request = smack_inet_conn_request,
2470 /* key management security hooks */
2471#ifdef CONFIG_KEYS
2472 .key_alloc = smack_key_alloc,
2473 .key_free = smack_key_free,
2474 .key_permission = smack_key_permission,
2475#endif /* CONFIG_KEYS */
2476 .secid_to_secctx = smack_secid_to_secctx,
2477 .release_secctx = smack_release_secctx,
2478};
2479
2480/**
2481 * smack_init - initialize the smack system
2482 *
2483 * Returns 0
2484 */
2485static __init int smack_init(void)
2486{
2487 printk(KERN_INFO "Smack: Initializing.\n");
2488
2489 /*
2490 * Set the security state for the initial task.
2491 */
2492 current->security = &smack_known_floor.smk_known;
2493
2494 /*
2495 * Initialize locks
2496 */
2497 spin_lock_init(&smack_known_unset.smk_cipsolock);
2498 spin_lock_init(&smack_known_huh.smk_cipsolock);
2499 spin_lock_init(&smack_known_hat.smk_cipsolock);
2500 spin_lock_init(&smack_known_star.smk_cipsolock);
2501 spin_lock_init(&smack_known_floor.smk_cipsolock);
2502 spin_lock_init(&smack_known_invalid.smk_cipsolock);
2503
2504 /*
2505 * Register with LSM
2506 */
2507 if (register_security(&smack_ops))
2508 panic("smack: Unable to register with kernel.\n");
2509
2510 return 0;
2511}
2512
2513/*
2514 * Smack requires early initialization in order to label
2515 * all processes and objects when they are created.
2516 */
2517security_initcall(smack_init);
2518
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
new file mode 100644
index 000000000000..15aa37f65b39
--- /dev/null
+++ b/security/smack/smackfs.c
@@ -0,0 +1,981 @@
1/*
2 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, version 2.
7 *
8 * Authors:
9 * Casey Schaufler <casey@schaufler-ca.com>
10 * Ahmed S. Darwish <darwish.07@gmail.com>
11 *
12 * Special thanks to the authors of selinuxfs.
13 *
14 * Karl MacMillan <kmacmillan@tresys.com>
15 * James Morris <jmorris@redhat.com>
16 *
17 */
18
19#include <linux/kernel.h>
20#include <linux/vmalloc.h>
21#include <linux/security.h>
22#include <linux/mutex.h>
23#include <net/netlabel.h>
24#include <net/cipso_ipv4.h>
25#include <linux/seq_file.h>
26#include <linux/ctype.h>
27#include "smack.h"
28
29/*
30 * smackfs pseudo filesystem.
31 */
32
33enum smk_inos {
34 SMK_ROOT_INO = 2,
35 SMK_LOAD = 3, /* load policy */
36 SMK_CIPSO = 4, /* load label -> CIPSO mapping */
37 SMK_DOI = 5, /* CIPSO DOI */
38 SMK_DIRECT = 6, /* CIPSO level indicating direct label */
39 SMK_AMBIENT = 7, /* internet ambient label */
40 SMK_NLTYPE = 8, /* label scheme to use by default */
41};
42
43/*
44 * List locks
45 */
46static DEFINE_MUTEX(smack_list_lock);
47static DEFINE_MUTEX(smack_cipso_lock);
48
49/*
50 * This is the "ambient" label for network traffic.
51 * If it isn't somehow marked, use this.
52 * It can be reset via smackfs/ambient
53 */
54char *smack_net_ambient = smack_known_floor.smk_known;
55
56/*
57 * This is the default packet marking scheme for network traffic.
58 * It can be reset via smackfs/nltype
59 */
60int smack_net_nltype = NETLBL_NLTYPE_CIPSOV4;
61
62/*
63 * This is the level in a CIPSO header that indicates a
64 * smack label is contained directly in the category set.
65 * It can be reset via smackfs/direct
66 */
67int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;
68
69static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
70struct smk_list_entry *smack_list;
71
72#define SEQ_READ_FINISHED 1
73
74/*
75 * Disable concurrent writing open() operations
76 */
77static struct semaphore smack_write_sem;
78
79/*
80 * Values for parsing cipso rules
81 * SMK_DIGITLEN: Length of a digit field in a rule.
82 * SMK_CIPSOMEN: Minimum possible cipso rule length.
83 */
84#define SMK_DIGITLEN 4
85#define SMK_CIPSOMIN (SMK_MAXLEN + 2 * SMK_DIGITLEN)
86
87/*
88 * Seq_file read operations for /smack/load
89 */
90
91static void *load_seq_start(struct seq_file *s, loff_t *pos)
92{
93 if (*pos == SEQ_READ_FINISHED)
94 return NULL;
95
96 return smack_list;
97}
98
99static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
100{
101 struct smk_list_entry *skp = ((struct smk_list_entry *) v)->smk_next;
102
103 if (skp == NULL)
104 *pos = SEQ_READ_FINISHED;
105
106 return skp;
107}
108
109static int load_seq_show(struct seq_file *s, void *v)
110{
111 struct smk_list_entry *slp = (struct smk_list_entry *) v;
112 struct smack_rule *srp = &slp->smk_rule;
113
114 seq_printf(s, "%s %s", (char *)srp->smk_subject,
115 (char *)srp->smk_object);
116
117 seq_putc(s, ' ');
118
119 if (srp->smk_access & MAY_READ)
120 seq_putc(s, 'r');
121 if (srp->smk_access & MAY_WRITE)
122 seq_putc(s, 'w');
123 if (srp->smk_access & MAY_EXEC)
124 seq_putc(s, 'x');
125 if (srp->smk_access & MAY_APPEND)
126 seq_putc(s, 'a');
127 if (srp->smk_access == 0)
128 seq_putc(s, '-');
129
130 seq_putc(s, '\n');
131
132 return 0;
133}
134
135static void load_seq_stop(struct seq_file *s, void *v)
136{
137 /* No-op */
138}
139
140static struct seq_operations load_seq_ops = {
141 .start = load_seq_start,
142 .next = load_seq_next,
143 .show = load_seq_show,
144 .stop = load_seq_stop,
145};
146
147/**
148 * smk_open_load - open() for /smack/load
149 * @inode: inode structure representing file
150 * @file: "load" file pointer
151 *
152 * For reading, use load_seq_* seq_file reading operations.
153 */
154static int smk_open_load(struct inode *inode, struct file *file)
155{
156 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
157 return seq_open(file, &load_seq_ops);
158
159 if (down_interruptible(&smack_write_sem))
160 return -ERESTARTSYS;
161
162 return 0;
163}
164
165/**
166 * smk_release_load - release() for /smack/load
167 * @inode: inode structure representing file
168 * @file: "load" file pointer
169 *
170 * For a reading session, use the seq_file release
171 * implementation.
172 * Otherwise, we are at the end of a writing session so
173 * clean everything up.
174 */
175static int smk_release_load(struct inode *inode, struct file *file)
176{
177 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
178 return seq_release(inode, file);
179
180 up(&smack_write_sem);
181 return 0;
182}
183
184/**
185 * smk_set_access - add a rule to the rule list
186 * @srp: the new rule to add
187 *
188 * Looks through the current subject/object/access list for
189 * the subject/object pair and replaces the access that was
190 * there. If the pair isn't found add it with the specified
191 * access.
192 */
193static void smk_set_access(struct smack_rule *srp)
194{
195 struct smk_list_entry *sp;
196 struct smk_list_entry *newp;
197
198 mutex_lock(&smack_list_lock);
199
200 for (sp = smack_list; sp != NULL; sp = sp->smk_next)
201 if (sp->smk_rule.smk_subject == srp->smk_subject &&
202 sp->smk_rule.smk_object == srp->smk_object) {
203 sp->smk_rule.smk_access = srp->smk_access;
204 break;
205 }
206
207 if (sp == NULL) {
208 newp = kzalloc(sizeof(struct smk_list_entry), GFP_KERNEL);
209 newp->smk_rule = *srp;
210 newp->smk_next = smack_list;
211 smack_list = newp;
212 }
213
214 mutex_unlock(&smack_list_lock);
215
216 return;
217}
218
219/**
220 * smk_write_load - write() for /smack/load
221 * @filp: file pointer, not actually used
222 * @buf: where to get the data from
223 * @count: bytes sent
224 * @ppos: where to start - must be 0
225 *
226 * Get one smack access rule from above.
227 * The format is exactly:
228 * char subject[SMK_LABELLEN]
229 * char object[SMK_LABELLEN]
230 * char access[SMK_ACCESSKINDS]
231 *
232 * Anything following is commentary and ignored.
233 *
234 * writes must be SMK_LABELLEN+SMK_LABELLEN+4 bytes.
235 */
236#define MINIMUM_LOAD (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSKINDS)
237
238static ssize_t smk_write_load(struct file *file, const char __user *buf,
239 size_t count, loff_t *ppos)
240{
241 struct smack_rule rule;
242 char *data;
243 int rc = -EINVAL;
244
245 /*
246 * Must have privilege.
247 * No partial writes.
248 * Enough data must be present.
249 */
250 if (!capable(CAP_MAC_ADMIN))
251 return -EPERM;
252 if (*ppos != 0)
253 return -EINVAL;
254 if (count < MINIMUM_LOAD)
255 return -EINVAL;
256
257 data = kzalloc(count, GFP_KERNEL);
258 if (data == NULL)
259 return -ENOMEM;
260
261 if (copy_from_user(data, buf, count) != 0) {
262 rc = -EFAULT;
263 goto out;
264 }
265
266 rule.smk_subject = smk_import(data, 0);
267 if (rule.smk_subject == NULL)
268 goto out;
269
270 rule.smk_object = smk_import(data + SMK_LABELLEN, 0);
271 if (rule.smk_object == NULL)
272 goto out;
273
274 rule.smk_access = 0;
275
276 switch (data[SMK_LABELLEN + SMK_LABELLEN]) {
277 case '-':
278 break;
279 case 'r':
280 case 'R':
281 rule.smk_access |= MAY_READ;
282 break;
283 default:
284 goto out;
285 }
286
287 switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) {
288 case '-':
289 break;
290 case 'w':
291 case 'W':
292 rule.smk_access |= MAY_WRITE;
293 break;
294 default:
295 goto out;
296 }
297
298 switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) {
299 case '-':
300 break;
301 case 'x':
302 case 'X':
303 rule.smk_access |= MAY_EXEC;
304 break;
305 default:
306 goto out;
307 }
308
309 switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) {
310 case '-':
311 break;
312 case 'a':
313 case 'A':
314 rule.smk_access |= MAY_READ;
315 break;
316 default:
317 goto out;
318 }
319
320 smk_set_access(&rule);
321 rc = count;
322
323out:
324 kfree(data);
325 return rc;
326}
327
328static const struct file_operations smk_load_ops = {
329 .open = smk_open_load,
330 .read = seq_read,
331 .llseek = seq_lseek,
332 .write = smk_write_load,
333 .release = smk_release_load,
334};
335
336/**
337 * smk_cipso_doi - initialize the CIPSO domain
338 */
339void smk_cipso_doi(void)
340{
341 int rc;
342 struct cipso_v4_doi *doip;
343 struct netlbl_audit audit_info;
344
345 rc = netlbl_cfg_map_del(NULL, &audit_info);
346 if (rc != 0)
347 printk(KERN_WARNING "%s:%d remove rc = %d\n",
348 __func__, __LINE__, rc);
349
350 doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL);
351 if (doip == NULL)
352 panic("smack: Failed to initialize cipso DOI.\n");
353 doip->map.std = NULL;
354 doip->doi = smk_cipso_doi_value;
355 doip->type = CIPSO_V4_MAP_PASS;
356 doip->tags[0] = CIPSO_V4_TAG_RBITMAP;
357 for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++)
358 doip->tags[rc] = CIPSO_V4_TAG_INVALID;
359
360 rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info);
361 if (rc != 0)
362 printk(KERN_WARNING "%s:%d add rc = %d\n",
363 __func__, __LINE__, rc);
364}
365
366/*
367 * Seq_file read operations for /smack/cipso
368 */
369
370static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
371{
372 if (*pos == SEQ_READ_FINISHED)
373 return NULL;
374
375 return smack_known;
376}
377
378static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
379{
380 struct smack_known *skp = ((struct smack_known *) v)->smk_next;
381
382 /*
383 * Omit labels with no associated cipso value
384 */
385 while (skp != NULL && !skp->smk_cipso)
386 skp = skp->smk_next;
387
388 if (skp == NULL)
389 *pos = SEQ_READ_FINISHED;
390
391 return skp;
392}
393
394/*
395 * Print cipso labels in format:
396 * label level[/cat[,cat]]
397 */
398static int cipso_seq_show(struct seq_file *s, void *v)
399{
400 struct smack_known *skp = (struct smack_known *) v;
401 struct smack_cipso *scp = skp->smk_cipso;
402 char *cbp;
403 char sep = '/';
404 int cat = 1;
405 int i;
406 unsigned char m;
407
408 if (scp == NULL)
409 return 0;
410
411 seq_printf(s, "%s %3d", (char *)&skp->smk_known, scp->smk_level);
412
413 cbp = scp->smk_catset;
414 for (i = 0; i < SMK_LABELLEN; i++)
415 for (m = 0x80; m != 0; m >>= 1) {
416 if (m & cbp[i]) {
417 seq_printf(s, "%c%d", sep, cat);
418 sep = ',';
419 }
420 cat++;
421 }
422
423 seq_putc(s, '\n');
424
425 return 0;
426}
427
428static void cipso_seq_stop(struct seq_file *s, void *v)
429{
430 /* No-op */
431}
432
433static struct seq_operations cipso_seq_ops = {
434 .start = cipso_seq_start,
435 .stop = cipso_seq_stop,
436 .next = cipso_seq_next,
437 .show = cipso_seq_show,
438};
439
440/**
441 * smk_open_cipso - open() for /smack/cipso
442 * @inode: inode structure representing file
443 * @file: "cipso" file pointer
444 *
445 * Connect our cipso_seq_* operations with /smack/cipso
446 * file_operations
447 */
448static int smk_open_cipso(struct inode *inode, struct file *file)
449{
450 return seq_open(file, &cipso_seq_ops);
451}
452
453/**
454 * smk_write_cipso - write() for /smack/cipso
455 * @filp: file pointer, not actually used
456 * @buf: where to get the data from
457 * @count: bytes sent
458 * @ppos: where to start
459 *
460 * Accepts only one cipso rule per write call.
461 * Returns number of bytes written or error code, as appropriate
462 */
463static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
464 size_t count, loff_t *ppos)
465{
466 struct smack_known *skp;
467 struct smack_cipso *scp = NULL;
468 char mapcatset[SMK_LABELLEN];
469 int maplevel;
470 int cat;
471 int catlen;
472 ssize_t rc = -EINVAL;
473 char *data = NULL;
474 char *rule;
475 int ret;
476 int i;
477
478 /*
479 * Must have privilege.
480 * No partial writes.
481 * Enough data must be present.
482 */
483 if (!capable(CAP_MAC_ADMIN))
484 return -EPERM;
485 if (*ppos != 0)
486 return -EINVAL;
487 if (count <= SMK_CIPSOMIN)
488 return -EINVAL;
489
490 data = kzalloc(count + 1, GFP_KERNEL);
491 if (data == NULL)
492 return -ENOMEM;
493
494 if (copy_from_user(data, buf, count) != 0) {
495 rc = -EFAULT;
496 goto unlockedout;
497 }
498
499 data[count] = '\0';
500 rule = data;
501 /*
502 * Only allow one writer at a time. Writes should be
503 * quite rare and small in any case.
504 */
505 mutex_lock(&smack_cipso_lock);
506
507 skp = smk_import_entry(rule, 0);
508 if (skp == NULL)
509 goto out;
510
511 rule += SMK_LABELLEN;;
512 ret = sscanf(rule, "%d", &maplevel);
513 if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL)
514 goto out;
515
516 rule += SMK_DIGITLEN;
517 ret = sscanf(rule, "%d", &catlen);
518 if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
519 goto out;
520
521 if (count <= (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
522 goto out;
523
524 memset(mapcatset, 0, sizeof(mapcatset));
525
526 for (i = 0; i < catlen; i++) {
527 rule += SMK_DIGITLEN;
528 ret = sscanf(rule, "%d", &cat);
529 if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL)
530 goto out;
531
532 smack_catset_bit(cat, mapcatset);
533 }
534
535 if (skp->smk_cipso == NULL) {
536 scp = kzalloc(sizeof(struct smack_cipso), GFP_KERNEL);
537 if (scp == NULL) {
538 rc = -ENOMEM;
539 goto out;
540 }
541 }
542
543 spin_lock_bh(&skp->smk_cipsolock);
544
545 if (scp == NULL)
546 scp = skp->smk_cipso;
547 else
548 skp->smk_cipso = scp;
549
550 scp->smk_level = maplevel;
551 memcpy(scp->smk_catset, mapcatset, sizeof(mapcatset));
552
553 spin_unlock_bh(&skp->smk_cipsolock);
554
555 rc = count;
556out:
557 mutex_unlock(&smack_cipso_lock);
558unlockedout:
559 kfree(data);
560 return rc;
561}
562
563static const struct file_operations smk_cipso_ops = {
564 .open = smk_open_cipso,
565 .read = seq_read,
566 .llseek = seq_lseek,
567 .write = smk_write_cipso,
568 .release = seq_release,
569};
570
571/**
572 * smk_read_doi - read() for /smack/doi
573 * @filp: file pointer, not actually used
574 * @buf: where to put the result
575 * @count: maximum to send along
576 * @ppos: where to start
577 *
578 * Returns number of bytes read or error code, as appropriate
579 */
580static ssize_t smk_read_doi(struct file *filp, char __user *buf,
581 size_t count, loff_t *ppos)
582{
583 char temp[80];
584 ssize_t rc;
585
586 if (*ppos != 0)
587 return 0;
588
589 sprintf(temp, "%d", smk_cipso_doi_value);
590 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
591
592 return rc;
593}
594
595/**
596 * smk_write_doi - write() for /smack/doi
597 * @filp: file pointer, not actually used
598 * @buf: where to get the data from
599 * @count: bytes sent
600 * @ppos: where to start
601 *
602 * Returns number of bytes written or error code, as appropriate
603 */
604static ssize_t smk_write_doi(struct file *file, const char __user *buf,
605 size_t count, loff_t *ppos)
606{
607 char temp[80];
608 int i;
609
610 if (!capable(CAP_MAC_ADMIN))
611 return -EPERM;
612
613 if (count >= sizeof(temp) || count == 0)
614 return -EINVAL;
615
616 if (copy_from_user(temp, buf, count) != 0)
617 return -EFAULT;
618
619 temp[count] = '\0';
620
621 if (sscanf(temp, "%d", &i) != 1)
622 return -EINVAL;
623
624 smk_cipso_doi_value = i;
625
626 smk_cipso_doi();
627
628 return count;
629}
630
631static const struct file_operations smk_doi_ops = {
632 .read = smk_read_doi,
633 .write = smk_write_doi,
634};
635
636/**
637 * smk_read_direct - read() for /smack/direct
638 * @filp: file pointer, not actually used
639 * @buf: where to put the result
640 * @count: maximum to send along
641 * @ppos: where to start
642 *
643 * Returns number of bytes read or error code, as appropriate
644 */
645static ssize_t smk_read_direct(struct file *filp, char __user *buf,
646 size_t count, loff_t *ppos)
647{
648 char temp[80];
649 ssize_t rc;
650
651 if (*ppos != 0)
652 return 0;
653
654 sprintf(temp, "%d", smack_cipso_direct);
655 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
656
657 return rc;
658}
659
660/**
661 * smk_write_direct - write() for /smack/direct
662 * @filp: file pointer, not actually used
663 * @buf: where to get the data from
664 * @count: bytes sent
665 * @ppos: where to start
666 *
667 * Returns number of bytes written or error code, as appropriate
668 */
669static ssize_t smk_write_direct(struct file *file, const char __user *buf,
670 size_t count, loff_t *ppos)
671{
672 char temp[80];
673 int i;
674
675 if (!capable(CAP_MAC_ADMIN))
676 return -EPERM;
677
678 if (count >= sizeof(temp) || count == 0)
679 return -EINVAL;
680
681 if (copy_from_user(temp, buf, count) != 0)
682 return -EFAULT;
683
684 temp[count] = '\0';
685
686 if (sscanf(temp, "%d", &i) != 1)
687 return -EINVAL;
688
689 smack_cipso_direct = i;
690
691 return count;
692}
693
694static const struct file_operations smk_direct_ops = {
695 .read = smk_read_direct,
696 .write = smk_write_direct,
697};
698
699/**
700 * smk_read_ambient - read() for /smack/ambient
701 * @filp: file pointer, not actually used
702 * @buf: where to put the result
703 * @cn: maximum to send along
704 * @ppos: where to start
705 *
706 * Returns number of bytes read or error code, as appropriate
707 */
708static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
709 size_t cn, loff_t *ppos)
710{
711 ssize_t rc;
712 char out[SMK_LABELLEN];
713 int asize;
714
715 if (*ppos != 0)
716 return 0;
717 /*
718 * Being careful to avoid a problem in the case where
719 * smack_net_ambient gets changed in midstream.
720 * Since smack_net_ambient is always set with a value
721 * from the label list, including initially, and those
722 * never get freed, the worst case is that the pointer
723 * gets changed just after this strncpy, in which case
724 * the value passed up is incorrect. Locking around
725 * smack_net_ambient wouldn't be any better than this
726 * copy scheme as by the time the caller got to look
727 * at the ambient value it would have cleared the lock
728 * and been changed.
729 */
730 strncpy(out, smack_net_ambient, SMK_LABELLEN);
731 asize = strlen(out) + 1;
732
733 if (cn < asize)
734 return -EINVAL;
735
736 rc = simple_read_from_buffer(buf, cn, ppos, out, asize);
737
738 return rc;
739}
740
741/**
742 * smk_write_ambient - write() for /smack/ambient
743 * @filp: file pointer, not actually used
744 * @buf: where to get the data from
745 * @count: bytes sent
746 * @ppos: where to start
747 *
748 * Returns number of bytes written or error code, as appropriate
749 */
750static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
751 size_t count, loff_t *ppos)
752{
753 char in[SMK_LABELLEN];
754 char *smack;
755
756 if (!capable(CAP_MAC_ADMIN))
757 return -EPERM;
758
759 if (count >= SMK_LABELLEN)
760 return -EINVAL;
761
762 if (copy_from_user(in, buf, count) != 0)
763 return -EFAULT;
764
765 smack = smk_import(in, count);
766 if (smack == NULL)
767 return -EINVAL;
768
769 smack_net_ambient = smack;
770
771 return count;
772}
773
774static const struct file_operations smk_ambient_ops = {
775 .read = smk_read_ambient,
776 .write = smk_write_ambient,
777};
778
779struct option_names {
780 int o_number;
781 char *o_name;
782 char *o_alias;
783};
784
785static struct option_names netlbl_choices[] = {
786 { NETLBL_NLTYPE_RIPSO,
787 NETLBL_NLTYPE_RIPSO_NAME, "ripso" },
788 { NETLBL_NLTYPE_CIPSOV4,
789 NETLBL_NLTYPE_CIPSOV4_NAME, "cipsov4" },
790 { NETLBL_NLTYPE_CIPSOV4,
791 NETLBL_NLTYPE_CIPSOV4_NAME, "cipso" },
792 { NETLBL_NLTYPE_CIPSOV6,
793 NETLBL_NLTYPE_CIPSOV6_NAME, "cipsov6" },
794 { NETLBL_NLTYPE_UNLABELED,
795 NETLBL_NLTYPE_UNLABELED_NAME, "unlabeled" },
796};
797
798/**
799 * smk_read_nltype - read() for /smack/nltype
800 * @filp: file pointer, not actually used
801 * @buf: where to put the result
802 * @count: maximum to send along
803 * @ppos: where to start
804 *
805 * Returns number of bytes read or error code, as appropriate
806 */
807static ssize_t smk_read_nltype(struct file *filp, char __user *buf,
808 size_t count, loff_t *ppos)
809{
810 char bound[40];
811 ssize_t rc;
812 int i;
813
814 if (count < SMK_LABELLEN)
815 return -EINVAL;
816
817 if (*ppos != 0)
818 return 0;
819
820 sprintf(bound, "unknown");
821
822 for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++)
823 if (smack_net_nltype == netlbl_choices[i].o_number) {
824 sprintf(bound, "%s", netlbl_choices[i].o_name);
825 break;
826 }
827
828 rc = simple_read_from_buffer(buf, count, ppos, bound, strlen(bound));
829
830 return rc;
831}
832
833/**
834 * smk_write_nltype - write() for /smack/nltype
835 * @filp: file pointer, not actually used
836 * @buf: where to get the data from
837 * @count: bytes sent
838 * @ppos: where to start
839 *
840 * Returns number of bytes written or error code, as appropriate
841 */
842static ssize_t smk_write_nltype(struct file *file, const char __user *buf,
843 size_t count, loff_t *ppos)
844{
845 char bound[40];
846 char *cp;
847 int i;
848
849 if (!capable(CAP_MAC_ADMIN))
850 return -EPERM;
851
852 if (count >= 40)
853 return -EINVAL;
854
855 if (copy_from_user(bound, buf, count) != 0)
856 return -EFAULT;
857
858 bound[count] = '\0';
859 cp = strchr(bound, ' ');
860 if (cp != NULL)
861 *cp = '\0';
862 cp = strchr(bound, '\n');
863 if (cp != NULL)
864 *cp = '\0';
865
866 for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++)
867 if (strcmp(bound, netlbl_choices[i].o_name) == 0 ||
868 strcmp(bound, netlbl_choices[i].o_alias) == 0) {
869 smack_net_nltype = netlbl_choices[i].o_number;
870 return count;
871 }
872 /*
873 * Not a valid choice.
874 */
875 return -EINVAL;
876}
877
878static const struct file_operations smk_nltype_ops = {
879 .read = smk_read_nltype,
880 .write = smk_write_nltype,
881};
882
883/**
884 * smk_fill_super - fill the /smackfs superblock
885 * @sb: the empty superblock
886 * @data: unused
887 * @silent: unused
888 *
889 * Fill in the well known entries for /smack
890 *
891 * Returns 0 on success, an error code on failure
892 */
893static int smk_fill_super(struct super_block *sb, void *data, int silent)
894{
895 int rc;
896 struct inode *root_inode;
897
898 static struct tree_descr smack_files[] = {
899 [SMK_LOAD] =
900 {"load", &smk_load_ops, S_IRUGO|S_IWUSR},
901 [SMK_CIPSO] =
902 {"cipso", &smk_cipso_ops, S_IRUGO|S_IWUSR},
903 [SMK_DOI] =
904 {"doi", &smk_doi_ops, S_IRUGO|S_IWUSR},
905 [SMK_DIRECT] =
906 {"direct", &smk_direct_ops, S_IRUGO|S_IWUSR},
907 [SMK_AMBIENT] =
908 {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR},
909 [SMK_NLTYPE] =
910 {"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR},
911 /* last one */ {""}
912 };
913
914 rc = simple_fill_super(sb, SMACK_MAGIC, smack_files);
915 if (rc != 0) {
916 printk(KERN_ERR "%s failed %d while creating inodes\n",
917 __func__, rc);
918 return rc;
919 }
920
921 root_inode = sb->s_root->d_inode;
922 root_inode->i_security = new_inode_smack(smack_known_floor.smk_known);
923
924 return 0;
925}
926
927/**
928 * smk_get_sb - get the smackfs superblock
929 * @fs_type: passed along without comment
930 * @flags: passed along without comment
931 * @dev_name: passed along without comment
932 * @data: passed along without comment
933 * @mnt: passed along without comment
934 *
935 * Just passes everything along.
936 *
937 * Returns what the lower level code does.
938 */
939static int smk_get_sb(struct file_system_type *fs_type,
940 int flags, const char *dev_name, void *data,
941 struct vfsmount *mnt)
942{
943 return get_sb_single(fs_type, flags, data, smk_fill_super, mnt);
944}
945
946static struct file_system_type smk_fs_type = {
947 .name = "smackfs",
948 .get_sb = smk_get_sb,
949 .kill_sb = kill_litter_super,
950};
951
952static struct vfsmount *smackfs_mount;
953
954/**
955 * init_smk_fs - get the smackfs superblock
956 *
957 * register the smackfs
958 *
959 * Returns 0 unless the registration fails.
960 */
961static int __init init_smk_fs(void)
962{
963 int err;
964
965 err = register_filesystem(&smk_fs_type);
966 if (!err) {
967 smackfs_mount = kern_mount(&smk_fs_type);
968 if (IS_ERR(smackfs_mount)) {
969 printk(KERN_ERR "smackfs: could not mount!\n");
970 err = PTR_ERR(smackfs_mount);
971 smackfs_mount = NULL;
972 }
973 }
974
975 sema_init(&smack_write_sem, 1);
976 smk_cipso_doi();
977
978 return err;
979}
980
981__initcall(init_smk_fs);