aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /security/smack
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'security/smack')
-rw-r--r--security/smack/Kconfig6
-rw-r--r--security/smack/smack.h110
-rw-r--r--security/smack/smack_access.c358
-rw-r--r--security/smack/smack_lsm.c607
-rw-r--r--security/smack/smackfs.c1284
5 files changed, 807 insertions, 1558 deletions
diff --git a/security/smack/Kconfig b/security/smack/Kconfig
index e69de9c642b..603b0878434 100644
--- a/security/smack/Kconfig
+++ b/security/smack/Kconfig
@@ -1,10 +1,6 @@
1config SECURITY_SMACK 1config SECURITY_SMACK
2 bool "Simplified Mandatory Access Control Kernel Support" 2 bool "Simplified Mandatory Access Control Kernel Support"
3 depends on NET 3 depends on NETLABEL && SECURITY_NETWORK
4 depends on INET
5 depends on SECURITY
6 select NETLABEL
7 select SECURITY_NETWORK
8 default n 4 default n
9 help 5 help
10 This selects the Simplified Mandatory Access Control Kernel. 6 This selects the Simplified Mandatory Access Control Kernel.
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 99b36124f71..2b6c6a51612 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -23,19 +23,13 @@
23#include <linux/lsm_audit.h> 23#include <linux/lsm_audit.h>
24 24
25/* 25/*
26 * Smack labels were limited to 23 characters for a long time.
27 */
28#define SMK_LABELLEN 24
29#define SMK_LONGLABEL 256
30
31/*
32 * Maximum number of bytes for the levels in a CIPSO IP option.
33 * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is 26 * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
34 * bigger than can be used, and 24 is the next lower multiple 27 * bigger than can be used, and 24 is the next lower multiple
35 * of 8, and there are too many issues if there isn't space set 28 * of 8, and there are too many issues if there isn't space set
36 * aside for the terminating null byte. 29 * aside for the terminating null byte.
37 */ 30 */
38#define SMK_CIPSOLEN 24 31#define SMK_MAXLEN 23
32#define SMK_LABELLEN (SMK_MAXLEN+1)
39 33
40struct superblock_smack { 34struct superblock_smack {
41 char *smk_root; 35 char *smk_root;
@@ -43,12 +37,13 @@ struct superblock_smack {
43 char *smk_hat; 37 char *smk_hat;
44 char *smk_default; 38 char *smk_default;
45 int smk_initialized; 39 int smk_initialized;
40 spinlock_t smk_sblock; /* for initialization */
46}; 41};
47 42
48struct socket_smack { 43struct socket_smack {
49 char *smk_out; /* outbound label */ 44 char *smk_out; /* outbound label */
50 char *smk_in; /* inbound label */ 45 char *smk_in; /* inbound label */
51 char *smk_packet; /* TCP peer label */ 46 char smk_packet[SMK_LABELLEN]; /* TCP peer label */
52}; 47};
53 48
54/* 49/*
@@ -71,7 +66,6 @@ struct task_smack {
71 66
72#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */ 67#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */
73#define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */ 68#define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */
74#define SMK_INODE_CHANGED 0x04 /* smack was transmuted */
75 69
76/* 70/*
77 * A label access rule. 71 * A label access rule.
@@ -84,6 +78,15 @@ struct smack_rule {
84}; 78};
85 79
86/* 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/*
87 * An entry in the table identifying hosts. 90 * An entry in the table identifying hosts.
88 */ 91 */
89struct smk_netlbladdr { 92struct smk_netlbladdr {
@@ -110,19 +113,16 @@ struct smk_netlbladdr {
110 * interfaces don't. The secid should go away when all of 113 * interfaces don't. The secid should go away when all of
111 * these components have been repaired. 114 * these components have been repaired.
112 * 115 *
113 * The cipso value associated with the label gets stored here, too. 116 * If there is a cipso value associated with the label it
114 * 117 * gets stored here, too. This will most likely be rare as
115 * Keep the access rules for this subject label here so that 118 * the cipso direct mapping in used internally.
116 * the entire set of rules does not need to be examined every
117 * time.
118 */ 119 */
119struct smack_known { 120struct smack_known {
120 struct list_head list; 121 struct list_head list;
121 char *smk_known; 122 char smk_known[SMK_LABELLEN];
122 u32 smk_secid; 123 u32 smk_secid;
123 struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */ 124 struct smack_cipso *smk_cipso;
124 struct list_head smk_rules; /* access rules */ 125 spinlock_t smk_cipsolock; /* for changing cipso map */
125 struct mutex smk_rules_lock; /* lock for rules */
126}; 126};
127 127
128/* 128/*
@@ -150,6 +150,7 @@ struct smack_known {
150 150
151/* 151/*
152 * smackfs magic number 152 * smackfs magic number
153 * smackfs macic number
153 */ 154 */
154#define SMACK_MAGIC 0x43415d53 /* "SMAC" */ 155#define SMACK_MAGIC 0x43415d53 /* "SMAC" */
155 156
@@ -159,7 +160,6 @@ struct smack_known {
159#define SMACK_CIPSO_DOI_DEFAULT 3 /* Historical */ 160#define SMACK_CIPSO_DOI_DEFAULT 3 /* Historical */
160#define SMACK_CIPSO_DOI_INVALID -1 /* Not a DOI */ 161#define SMACK_CIPSO_DOI_INVALID -1 /* Not a DOI */
161#define SMACK_CIPSO_DIRECT_DEFAULT 250 /* Arbitrary */ 162#define SMACK_CIPSO_DIRECT_DEFAULT 250 /* Arbitrary */
162#define SMACK_CIPSO_MAPPED_DEFAULT 251 /* Also arbitrary */
163#define SMACK_CIPSO_MAXCATVAL 63 /* Bigger gets harder */ 163#define SMACK_CIPSO_MAXCATVAL 63 /* Bigger gets harder */
164#define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */ 164#define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */
165#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */ 165#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */
@@ -176,18 +176,9 @@ struct smack_known {
176#define MAY_NOT 0 176#define MAY_NOT 0
177 177
178/* 178/*
179 * Number of access types used by Smack (rwxat) 179 * Number of access types used by Smack (rwxa)
180 */ 180 */
181#define SMK_NUM_ACCESS_TYPE 5 181#define SMK_NUM_ACCESS_TYPE 4
182
183/* SMACK data */
184struct smack_audit_data {
185 const char *function;
186 char *subject;
187 char *object;
188 char *request;
189 int result;
190};
191 182
192/* 183/*
193 * Smack audit data; is empty if CONFIG_AUDIT not set 184 * Smack audit data; is empty if CONFIG_AUDIT not set
@@ -196,7 +187,6 @@ struct smack_audit_data {
196struct smk_audit_info { 187struct smk_audit_info {
197#ifdef CONFIG_AUDIT 188#ifdef CONFIG_AUDIT
198 struct common_audit_data a; 189 struct common_audit_data a;
199 struct smack_audit_data sad;
200#endif 190#endif
201}; 191};
202/* 192/*
@@ -210,19 +200,17 @@ struct inode_smack *new_inode_smack(char *);
210int smk_access_entry(char *, char *, struct list_head *); 200int smk_access_entry(char *, char *, struct list_head *);
211int smk_access(char *, char *, int, struct smk_audit_info *); 201int smk_access(char *, char *, int, struct smk_audit_info *);
212int smk_curacc(char *, u32, struct smk_audit_info *); 202int smk_curacc(char *, u32, struct smk_audit_info *);
203int smack_to_cipso(const char *, struct smack_cipso *);
204void smack_from_cipso(u32, char *, char *);
213char *smack_from_secid(const u32); 205char *smack_from_secid(const u32);
214char *smk_parse_smack(const char *string, int len);
215int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
216char *smk_import(const char *, int); 206char *smk_import(const char *, int);
217struct smack_known *smk_import_entry(const char *, int); 207struct smack_known *smk_import_entry(const char *, int);
218struct smack_known *smk_find_entry(const char *);
219u32 smack_to_secid(const char *); 208u32 smack_to_secid(const char *);
220 209
221/* 210/*
222 * Shared data. 211 * Shared data.
223 */ 212 */
224extern int smack_cipso_direct; 213extern int smack_cipso_direct;
225extern int smack_cipso_mapped;
226extern char *smack_net_ambient; 214extern char *smack_net_ambient;
227extern char *smack_onlycap; 215extern char *smack_onlycap;
228extern const char *smack_cipso_option; 216extern const char *smack_cipso_option;
@@ -234,13 +222,25 @@ extern struct smack_known smack_known_invalid;
234extern struct smack_known smack_known_star; 222extern struct smack_known smack_known_star;
235extern struct smack_known smack_known_web; 223extern struct smack_known smack_known_web;
236 224
237extern struct mutex smack_known_lock;
238extern struct list_head smack_known_list; 225extern struct list_head smack_known_list;
226extern struct list_head smack_rule_list;
239extern struct list_head smk_netlbladdr_list; 227extern struct list_head smk_netlbladdr_list;
240 228
241extern struct security_operations smack_ops; 229extern struct security_operations smack_ops;
242 230
243/* 231/*
232 * Stricly for CIPSO level manipulation.
233 * Set the category bit number in a smack label sized buffer.
234 */
235static inline void smack_catset_bit(int cat, char *catsetp)
236{
237 if (cat > SMK_LABELLEN * 8)
238 return;
239
240 catsetp[(cat - 1) / 8] |= 0x80 >> ((cat - 1) % 8);
241}
242
243/*
244 * Is the directory transmuting? 244 * Is the directory transmuting?
245 */ 245 */
246static inline int smk_inode_transmutable(const struct inode *isp) 246static inline int smk_inode_transmutable(const struct inode *isp)
@@ -283,19 +283,6 @@ static inline char *smk_of_current(void)
283} 283}
284 284
285/* 285/*
286 * Is the task privileged and allowed to be privileged
287 * by the onlycap rule.
288 */
289static inline int smack_privileged(int cap)
290{
291 if (!capable(cap))
292 return 0;
293 if (smack_onlycap == NULL || smack_onlycap == smk_of_current())
294 return 1;
295 return 0;
296}
297
298/*
299 * logging functions 286 * logging functions
300 */ 287 */
301#define SMACK_AUDIT_DENIED 0x1 288#define SMACK_AUDIT_DENIED 0x1
@@ -316,18 +303,9 @@ void smack_log(char *subject_label, char *object_label,
316static inline void smk_ad_init(struct smk_audit_info *a, const char *func, 303static inline void smk_ad_init(struct smk_audit_info *a, const char *func,
317 char type) 304 char type)
318{ 305{
319 memset(&a->sad, 0, sizeof(a->sad)); 306 memset(a, 0, sizeof(*a));
320 a->a.type = type; 307 a->a.type = type;
321 a->a.smack_audit_data = &a->sad; 308 a->a.smack_audit_data.function = func;
322 a->a.smack_audit_data->function = func;
323}
324
325static inline void smk_ad_init_net(struct smk_audit_info *a, const char *func,
326 char type, struct lsm_network_audit *net)
327{
328 smk_ad_init(a, func, type);
329 memset(net, 0, sizeof(*net));
330 a->a.u.net = net;
331} 309}
332 310
333static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, 311static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a,
@@ -353,7 +331,7 @@ static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
353static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, 331static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
354 struct sock *sk) 332 struct sock *sk)
355{ 333{
356 a->a.u.net->sk = sk; 334 a->a.u.net.sk = sk;
357} 335}
358 336
359#else /* no AUDIT */ 337#else /* no AUDIT */
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index db14689a21e..9637e107f7e 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -19,31 +19,37 @@
19struct smack_known smack_known_huh = { 19struct smack_known smack_known_huh = {
20 .smk_known = "?", 20 .smk_known = "?",
21 .smk_secid = 2, 21 .smk_secid = 2,
22 .smk_cipso = NULL,
22}; 23};
23 24
24struct smack_known smack_known_hat = { 25struct smack_known smack_known_hat = {
25 .smk_known = "^", 26 .smk_known = "^",
26 .smk_secid = 3, 27 .smk_secid = 3,
28 .smk_cipso = NULL,
27}; 29};
28 30
29struct smack_known smack_known_star = { 31struct smack_known smack_known_star = {
30 .smk_known = "*", 32 .smk_known = "*",
31 .smk_secid = 4, 33 .smk_secid = 4,
34 .smk_cipso = NULL,
32}; 35};
33 36
34struct smack_known smack_known_floor = { 37struct smack_known smack_known_floor = {
35 .smk_known = "_", 38 .smk_known = "_",
36 .smk_secid = 5, 39 .smk_secid = 5,
40 .smk_cipso = NULL,
37}; 41};
38 42
39struct smack_known smack_known_invalid = { 43struct smack_known smack_known_invalid = {
40 .smk_known = "", 44 .smk_known = "",
41 .smk_secid = 6, 45 .smk_secid = 6,
46 .smk_cipso = NULL,
42}; 47};
43 48
44struct smack_known smack_known_web = { 49struct smack_known smack_known_web = {
45 .smk_known = "@", 50 .smk_known = "@",
46 .smk_secid = 7, 51 .smk_secid = 7,
52 .smk_cipso = NULL,
47}; 53};
48 54
49LIST_HEAD(smack_known_list); 55LIST_HEAD(smack_known_list);
@@ -71,19 +77,14 @@ int log_policy = SMACK_AUDIT_DENIED;
71 * entry is found returns -ENOENT. 77 * entry is found returns -ENOENT.
72 * 78 *
73 * NOTE: 79 * NOTE:
80 * Even though Smack labels are usually shared on smack_list
81 * labels that come in off the network can't be imported
82 * and added to the list for locking reasons.
74 * 83 *
75 * Earlier versions of this function allowed for labels that 84 * Therefore, it is necessary to check the contents of the labels,
76 * were not on the label list. This was done to allow for 85 * not just the pointer values. Of course, in most cases the labels
77 * labels to come over the network that had never been seen 86 * will be on the list, so checking the pointers may be a worthwhile
78 * before on this host. Unless the receiving socket has the 87 * optimization.
79 * star label this will always result in a failure check. The
80 * star labeled socket case is now handled in the networking
81 * hooks so there is no case where the label is not on the
82 * label list. Checking to see if the address of two labels
83 * is the same is now a reliable test.
84 *
85 * Do the object check first because that is more
86 * likely to differ.
87 */ 88 */
88int smk_access_entry(char *subject_label, char *object_label, 89int smk_access_entry(char *subject_label, char *object_label,
89 struct list_head *rule_list) 90 struct list_head *rule_list)
@@ -92,10 +93,13 @@ int smk_access_entry(char *subject_label, char *object_label,
92 struct smack_rule *srp; 93 struct smack_rule *srp;
93 94
94 list_for_each_entry_rcu(srp, rule_list, list) { 95 list_for_each_entry_rcu(srp, rule_list, list) {
95 if (srp->smk_object == object_label && 96 if (srp->smk_subject == subject_label ||
96 srp->smk_subject == subject_label) { 97 strcmp(srp->smk_subject, subject_label) == 0) {
97 may = srp->smk_access; 98 if (srp->smk_object == object_label ||
98 break; 99 strcmp(srp->smk_object, object_label) == 0) {
100 may = srp->smk_access;
101 break;
102 }
99 } 103 }
100 } 104 }
101 105
@@ -113,12 +117,18 @@ int smk_access_entry(char *subject_label, char *object_label,
113 * access rule list and returns 0 if the access is permitted, 117 * access rule list and returns 0 if the access is permitted,
114 * non zero otherwise. 118 * non zero otherwise.
115 * 119 *
116 * Smack labels are shared on smack_list 120 * Even though Smack labels are usually shared on smack_list
121 * labels that come in off the network can't be imported
122 * and added to the list for locking reasons.
123 *
124 * Therefore, it is necessary to check the contents of the labels,
125 * not just the pointer values. Of course, in most cases the labels
126 * will be on the list, so checking the pointers may be a worthwhile
127 * optimization.
117 */ 128 */
118int smk_access(char *subject_label, char *object_label, int request, 129int smk_access(char *subject_label, char *object_label, int request,
119 struct smk_audit_info *a) 130 struct smk_audit_info *a)
120{ 131{
121 struct smack_known *skp;
122 int may = MAY_NOT; 132 int may = MAY_NOT;
123 int rc = 0; 133 int rc = 0;
124 134
@@ -127,7 +137,8 @@ int smk_access(char *subject_label, char *object_label, int request,
127 * 137 *
128 * A star subject can't access any object. 138 * A star subject can't access any object.
129 */ 139 */
130 if (subject_label == smack_known_star.smk_known) { 140 if (subject_label == smack_known_star.smk_known ||
141 strcmp(subject_label, smack_known_star.smk_known) == 0) {
131 rc = -EACCES; 142 rc = -EACCES;
132 goto out_audit; 143 goto out_audit;
133 } 144 }
@@ -137,27 +148,33 @@ int smk_access(char *subject_label, char *object_label, int request,
137 * An internet subject can access any object. 148 * An internet subject can access any object.
138 */ 149 */
139 if (object_label == smack_known_web.smk_known || 150 if (object_label == smack_known_web.smk_known ||
140 subject_label == smack_known_web.smk_known) 151 subject_label == smack_known_web.smk_known ||
152 strcmp(object_label, smack_known_web.smk_known) == 0 ||
153 strcmp(subject_label, smack_known_web.smk_known) == 0)
141 goto out_audit; 154 goto out_audit;
142 /* 155 /*
143 * A star object can be accessed by any subject. 156 * A star object can be accessed by any subject.
144 */ 157 */
145 if (object_label == smack_known_star.smk_known) 158 if (object_label == smack_known_star.smk_known ||
159 strcmp(object_label, smack_known_star.smk_known) == 0)
146 goto out_audit; 160 goto out_audit;
147 /* 161 /*
148 * An object can be accessed in any way by a subject 162 * An object can be accessed in any way by a subject
149 * with the same label. 163 * with the same label.
150 */ 164 */
151 if (subject_label == object_label) 165 if (subject_label == object_label ||
166 strcmp(subject_label, object_label) == 0)
152 goto out_audit; 167 goto out_audit;
153 /* 168 /*
154 * A hat subject can read any object. 169 * A hat subject can read any object.
155 * A floor object can be read by any subject. 170 * A floor object can be read by any subject.
156 */ 171 */
157 if ((request & MAY_ANYREAD) == request) { 172 if ((request & MAY_ANYREAD) == request) {
158 if (object_label == smack_known_floor.smk_known) 173 if (object_label == smack_known_floor.smk_known ||
174 strcmp(object_label, smack_known_floor.smk_known) == 0)
159 goto out_audit; 175 goto out_audit;
160 if (subject_label == smack_known_hat.smk_known) 176 if (subject_label == smack_known_hat.smk_known ||
177 strcmp(subject_label, smack_known_hat.smk_known) == 0)
161 goto out_audit; 178 goto out_audit;
162 } 179 }
163 /* 180 /*
@@ -167,9 +184,8 @@ int smk_access(char *subject_label, char *object_label, int request,
167 * good. A negative response from smk_access_entry() 184 * good. A negative response from smk_access_entry()
168 * indicates there is no entry for this pair. 185 * indicates there is no entry for this pair.
169 */ 186 */
170 skp = smk_find_entry(subject_label);
171 rcu_read_lock(); 187 rcu_read_lock();
172 may = smk_access_entry(subject_label, object_label, &skp->smk_rules); 188 may = smk_access_entry(subject_label, object_label, &smack_rule_list);
173 rcu_read_unlock(); 189 rcu_read_unlock();
174 190
175 if (may > 0 && (request & may) == request) 191 if (may > 0 && (request & may) == request)
@@ -220,9 +236,14 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
220 } 236 }
221 237
222 /* 238 /*
223 * Allow for priviliged to override policy. 239 * Return if a specific label has been designated as the
240 * only one that gets privilege and current does not
241 * have that label.
224 */ 242 */
225 if (rc != 0 && smack_privileged(CAP_MAC_OVERRIDE)) 243 if (smack_onlycap != NULL && smack_onlycap != sp)
244 goto out_audit;
245
246 if (capable(CAP_MAC_OVERRIDE))
226 rc = 0; 247 rc = 0;
227 248
228out_audit: 249out_audit:
@@ -264,9 +285,9 @@ static inline void smack_str_from_perm(char *string, int access)
264static void smack_log_callback(struct audit_buffer *ab, void *a) 285static void smack_log_callback(struct audit_buffer *ab, void *a)
265{ 286{
266 struct common_audit_data *ad = a; 287 struct common_audit_data *ad = a;
267 struct smack_audit_data *sad = ad->smack_audit_data; 288 struct smack_audit_data *sad = &ad->smack_audit_data;
268 audit_log_format(ab, "lsm=SMACK fn=%s action=%s", 289 audit_log_format(ab, "lsm=SMACK fn=%s action=%s",
269 ad->smack_audit_data->function, 290 ad->smack_audit_data.function,
270 sad->result ? "denied" : "granted"); 291 sad->result ? "denied" : "granted");
271 audit_log_format(ab, " subject="); 292 audit_log_format(ab, " subject=");
272 audit_log_untrustedstring(ab, sad->subject); 293 audit_log_untrustedstring(ab, sad->subject);
@@ -299,19 +320,19 @@ void smack_log(char *subject_label, char *object_label, int request,
299 if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) 320 if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0)
300 return; 321 return;
301 322
302 sad = a->smack_audit_data; 323 if (a->smack_audit_data.function == NULL)
303 324 a->smack_audit_data.function = "unknown";
304 if (sad->function == NULL)
305 sad->function = "unknown";
306 325
307 /* end preparing the audit data */ 326 /* end preparing the audit data */
327 sad = &a->smack_audit_data;
308 smack_str_from_perm(request_buffer, request); 328 smack_str_from_perm(request_buffer, request);
309 sad->subject = subject_label; 329 sad->subject = subject_label;
310 sad->object = object_label; 330 sad->object = object_label;
311 sad->request = request_buffer; 331 sad->request = request_buffer;
312 sad->result = result; 332 sad->result = result;
333 a->lsm_pre_audit = smack_log_callback;
313 334
314 common_lsm_audit(a, smack_log_callback, NULL); 335 common_lsm_audit(a);
315} 336}
316#else /* #ifdef CONFIG_AUDIT */ 337#else /* #ifdef CONFIG_AUDIT */
317void smack_log(char *subject_label, char *object_label, int request, 338void smack_log(char *subject_label, char *object_label, int request,
@@ -320,102 +341,7 @@ void smack_log(char *subject_label, char *object_label, int request,
320} 341}
321#endif 342#endif
322 343
323DEFINE_MUTEX(smack_known_lock); 344static DEFINE_MUTEX(smack_known_lock);
324
325/**
326 * smk_find_entry - find a label on the list, return the list entry
327 * @string: a text string that might be a Smack label
328 *
329 * Returns a pointer to the entry in the label list that
330 * matches the passed string.
331 */
332struct smack_known *smk_find_entry(const char *string)
333{
334 struct smack_known *skp;
335
336 list_for_each_entry_rcu(skp, &smack_known_list, list) {
337 if (strcmp(skp->smk_known, string) == 0)
338 return skp;
339 }
340
341 return NULL;
342}
343
344/**
345 * smk_parse_smack - parse smack label from a text string
346 * @string: a text string that might contain a Smack label
347 * @len: the maximum size, or zero if it is NULL terminated.
348 *
349 * Returns a pointer to the clean label, or NULL
350 */
351char *smk_parse_smack(const char *string, int len)
352{
353 char *smack;
354 int i;
355
356 if (len <= 0)
357 len = strlen(string) + 1;
358
359 /*
360 * Reserve a leading '-' as an indicator that
361 * this isn't a label, but an option to interfaces
362 * including /smack/cipso and /smack/cipso2
363 */
364 if (string[0] == '-')
365 return NULL;
366
367 for (i = 0; i < len; i++)
368 if (string[i] > '~' || string[i] <= ' ' || string[i] == '/' ||
369 string[i] == '"' || string[i] == '\\' || string[i] == '\'')
370 break;
371
372 if (i == 0 || i >= SMK_LONGLABEL)
373 return NULL;
374
375 smack = kzalloc(i + 1, GFP_KERNEL);
376 if (smack != NULL) {
377 strncpy(smack, string, i + 1);
378 smack[i] = '\0';
379 }
380 return smack;
381}
382
383/**
384 * smk_netlbl_mls - convert a catset to netlabel mls categories
385 * @catset: the Smack categories
386 * @sap: where to put the netlabel categories
387 *
388 * Allocates and fills attr.mls
389 * Returns 0 on success, error code on failure.
390 */
391int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
392 int len)
393{
394 unsigned char *cp;
395 unsigned char m;
396 int cat;
397 int rc;
398 int byte;
399
400 sap->flags |= NETLBL_SECATTR_MLS_CAT;
401 sap->attr.mls.lvl = level;
402 sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
403 sap->attr.mls.cat->startbit = 0;
404
405 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++)
406 for (m = 0x80; m != 0; m >>= 1, cat++) {
407 if ((m & *cp) == 0)
408 continue;
409 rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat,
410 cat, GFP_ATOMIC);
411 if (rc < 0) {
412 netlbl_secattr_catmap_free(sap->attr.mls.cat);
413 return rc;
414 }
415 }
416
417 return 0;
418}
419 345
420/** 346/**
421 * smk_import_entry - import a label, return the list entry 347 * smk_import_entry - import a label, return the list entry
@@ -428,59 +354,53 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
428struct smack_known *smk_import_entry(const char *string, int len) 354struct smack_known *smk_import_entry(const char *string, int len)
429{ 355{
430 struct smack_known *skp; 356 struct smack_known *skp;
431 char *smack; 357 char smack[SMK_LABELLEN];
432 int slen; 358 int found;
433 int rc; 359 int i;
434 360
435 smack = smk_parse_smack(string, len); 361 if (len <= 0 || len > SMK_MAXLEN)
436 if (smack == NULL) 362 len = SMK_MAXLEN;
363
364 for (i = 0, found = 0; i < SMK_LABELLEN; i++) {
365 if (found)
366 smack[i] = '\0';
367 else if (i >= len || string[i] > '~' || string[i] <= ' ' ||
368 string[i] == '/' || string[i] == '"' ||
369 string[i] == '\\' || string[i] == '\'') {
370 smack[i] = '\0';
371 found = 1;
372 } else
373 smack[i] = string[i];
374 }
375
376 if (smack[0] == '\0')
437 return NULL; 377 return NULL;
438 378
439 mutex_lock(&smack_known_lock); 379 mutex_lock(&smack_known_lock);
440 380
441 skp = smk_find_entry(smack); 381 found = 0;
442 if (skp != NULL) 382 list_for_each_entry_rcu(skp, &smack_known_list, list) {
443 goto freeout; 383 if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) {
444 384 found = 1;
445 skp = kzalloc(sizeof(*skp), GFP_KERNEL); 385 break;
446 if (skp == NULL) 386 }
447 goto freeout; 387 }
448 388
449 skp->smk_known = smack; 389 if (found == 0) {
450 skp->smk_secid = smack_next_secid++; 390 skp = kzalloc(sizeof(struct smack_known), GFP_KERNEL);
451 skp->smk_netlabel.domain = skp->smk_known; 391 if (skp != NULL) {
452 skp->smk_netlabel.flags = 392 strncpy(skp->smk_known, smack, SMK_MAXLEN);
453 NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; 393 skp->smk_secid = smack_next_secid++;
454 /* 394 skp->smk_cipso = NULL;
455 * If direct labeling works use it. 395 spin_lock_init(&skp->smk_cipsolock);
456 * Otherwise use mapped labeling. 396 /*
457 */ 397 * Make sure that the entry is actually
458 slen = strlen(smack); 398 * filled before putting it on the list.
459 if (slen < SMK_CIPSOLEN) 399 */
460 rc = smk_netlbl_mls(smack_cipso_direct, skp->smk_known, 400 list_add_rcu(&skp->list, &smack_known_list);
461 &skp->smk_netlabel, slen); 401 }
462 else
463 rc = smk_netlbl_mls(smack_cipso_mapped, (char *)&skp->smk_secid,
464 &skp->smk_netlabel, sizeof(skp->smk_secid));
465
466 if (rc >= 0) {
467 INIT_LIST_HEAD(&skp->smk_rules);
468 mutex_init(&skp->smk_rules_lock);
469 /*
470 * Make sure that the entry is actually
471 * filled before putting it on the list.
472 */
473 list_add_rcu(&skp->list, &smack_known_list);
474 goto unlockout;
475 } 402 }
476 /* 403
477 * smk_netlbl_mls failed.
478 */
479 kfree(skp);
480 skp = NULL;
481freeout:
482 kfree(smack);
483unlockout:
484 mutex_unlock(&smack_known_lock); 404 mutex_unlock(&smack_known_lock);
485 405
486 return skp; 406 return skp;
@@ -543,9 +463,85 @@ char *smack_from_secid(const u32 secid)
543 */ 463 */
544u32 smack_to_secid(const char *smack) 464u32 smack_to_secid(const char *smack)
545{ 465{
546 struct smack_known *skp = smk_find_entry(smack); 466 struct smack_known *skp;
547 467
548 if (skp == NULL) 468 rcu_read_lock();
549 return 0; 469 list_for_each_entry_rcu(skp, &smack_known_list, list) {
550 return skp->smk_secid; 470 if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) {
471 rcu_read_unlock();
472 return skp->smk_secid;
473 }
474 }
475 rcu_read_unlock();
476 return 0;
477}
478
479/**
480 * smack_from_cipso - find the Smack label associated with a CIPSO option
481 * @level: Bell & LaPadula level from the network
482 * @cp: Bell & LaPadula categories from the network
483 * @result: where to put the Smack value
484 *
485 * This is a simple lookup in the label table.
486 *
487 * This is an odd duck as far as smack handling goes in that
488 * it sends back a copy of the smack label rather than a pointer
489 * to the master list. This is done because it is possible for
490 * a foreign host to send a smack label that is new to this
491 * machine and hence not on the list. That would not be an
492 * issue except that adding an entry to the master list can't
493 * be done at that point.
494 */
495void smack_from_cipso(u32 level, char *cp, char *result)
496{
497 struct smack_known *kp;
498 char *final = NULL;
499
500 rcu_read_lock();
501 list_for_each_entry(kp, &smack_known_list, list) {
502 if (kp->smk_cipso == NULL)
503 continue;
504
505 spin_lock_bh(&kp->smk_cipsolock);
506
507 if (kp->smk_cipso->smk_level == level &&
508 memcmp(kp->smk_cipso->smk_catset, cp, SMK_LABELLEN) == 0)
509 final = kp->smk_known;
510
511 spin_unlock_bh(&kp->smk_cipsolock);
512 }
513 rcu_read_unlock();
514 if (final == NULL)
515 final = smack_known_huh.smk_known;
516 strncpy(result, final, SMK_MAXLEN);
517 return;
518}
519
520/**
521 * smack_to_cipso - find the CIPSO option to go with a Smack label
522 * @smack: a pointer to the smack label in question
523 * @cp: where to put the result
524 *
525 * Returns zero if a value is available, non-zero otherwise.
526 */
527int smack_to_cipso(const char *smack, struct smack_cipso *cp)
528{
529 struct smack_known *kp;
530 int found = 0;
531
532 rcu_read_lock();
533 list_for_each_entry_rcu(kp, &smack_known_list, list) {
534 if (kp->smk_known == smack ||
535 strcmp(kp->smk_known, smack) == 0) {
536 found = 1;
537 break;
538 }
539 }
540 rcu_read_unlock();
541
542 if (found == 0 || kp->smk_cipso == NULL)
543 return -ENOENT;
544
545 memcpy(cp, kp->smk_cipso, sizeof(struct smack_cipso));
546 return 0;
551} 547}
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 38be92ce901..b9c5e149903 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -5,13 +5,12 @@
5 * 5 *
6 * Authors: 6 * Authors:
7 * Casey Schaufler <casey@schaufler-ca.com> 7 * Casey Schaufler <casey@schaufler-ca.com>
8 * Jarkko Sakkinen <jarkko.sakkinen@intel.com> 8 * Jarkko Sakkinen <ext-jarkko.2.sakkinen@nokia.com>
9 * 9 *
10 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> 10 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
11 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. 11 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
12 * Paul Moore <paul@paul-moore.com> 12 * Paul Moore <paul@paul-moore.com>
13 * Copyright (C) 2010 Nokia Corporation 13 * Copyright (C) 2010 Nokia Corporation
14 * Copyright (C) 2011 Intel Corporation.
15 * 14 *
16 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2, 16 * it under the terms of the GNU General Public License version 2,
@@ -30,14 +29,11 @@
30#include <linux/slab.h> 29#include <linux/slab.h>
31#include <linux/mutex.h> 30#include <linux/mutex.h>
32#include <linux/pipe_fs_i.h> 31#include <linux/pipe_fs_i.h>
32#include <net/netlabel.h>
33#include <net/cipso_ipv4.h> 33#include <net/cipso_ipv4.h>
34#include <linux/audit.h> 34#include <linux/audit.h>
35#include <linux/magic.h> 35#include <linux/magic.h>
36#include <linux/dcache.h> 36#include <linux/dcache.h>
37#include <linux/personality.h>
38#include <linux/msg.h>
39#include <linux/shm.h>
40#include <linux/binfmts.h>
41#include "smack.h" 37#include "smack.h"
42 38
43#define task_security(task) (task_cred_xxx((task), security)) 39#define task_security(task) (task_cred_xxx((task), security))
@@ -56,23 +52,16 @@
56static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp) 52static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp)
57{ 53{
58 int rc; 54 int rc;
59 char *buffer; 55 char in[SMK_LABELLEN];
60 char *result = NULL;
61 56
62 if (ip->i_op->getxattr == NULL) 57 if (ip->i_op->getxattr == NULL)
63 return NULL; 58 return NULL;
64 59
65 buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL); 60 rc = ip->i_op->getxattr(dp, name, in, SMK_LABELLEN);
66 if (buffer == NULL) 61 if (rc < 0)
67 return NULL; 62 return NULL;
68 63
69 rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL); 64 return smk_import(in, rc);
70 if (rc > 0)
71 result = smk_import(buffer, rc);
72
73 kfree(buffer);
74
75 return result;
76} 65}
77 66
78/** 67/**
@@ -85,7 +74,7 @@ struct inode_smack *new_inode_smack(char *smack)
85{ 74{
86 struct inode_smack *isp; 75 struct inode_smack *isp;
87 76
88 isp = kzalloc(sizeof(struct inode_smack), GFP_NOFS); 77 isp = kzalloc(sizeof(struct inode_smack), GFP_KERNEL);
89 if (isp == NULL) 78 if (isp == NULL)
90 return NULL; 79 return NULL;
91 80
@@ -217,7 +206,7 @@ static int smack_syslog(int typefrom_file)
217 int rc = 0; 206 int rc = 0;
218 char *sp = smk_of_current(); 207 char *sp = smk_of_current();
219 208
220 if (smack_privileged(CAP_MAC_OVERRIDE)) 209 if (capable(CAP_MAC_OVERRIDE))
221 return 0; 210 return 0;
222 211
223 if (sp != smack_known_floor.smk_known) 212 if (sp != smack_known_floor.smk_known)
@@ -251,6 +240,7 @@ static int smack_sb_alloc_security(struct super_block *sb)
251 sbsp->smk_floor = smack_known_floor.smk_known; 240 sbsp->smk_floor = smack_known_floor.smk_known;
252 sbsp->smk_hat = smack_known_hat.smk_known; 241 sbsp->smk_hat = smack_known_hat.smk_known;
253 sbsp->smk_initialized = 0; 242 sbsp->smk_initialized = 0;
243 spin_lock_init(&sbsp->smk_sblock);
254 244
255 sb->s_security = sbsp; 245 sb->s_security = sbsp;
256 246
@@ -331,10 +321,13 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
331 char *commap; 321 char *commap;
332 char *nsp; 322 char *nsp;
333 323
334 if (sp->smk_initialized != 0) 324 spin_lock(&sp->smk_sblock);
325 if (sp->smk_initialized != 0) {
326 spin_unlock(&sp->smk_sblock);
335 return 0; 327 return 0;
336 328 }
337 sp->smk_initialized = 1; 329 sp->smk_initialized = 1;
330 spin_unlock(&sp->smk_sblock);
338 331
339 for (op = data; op != NULL; op = commap) { 332 for (op = data; op != NULL; op = commap) {
340 commap = strchr(op, ','); 333 commap = strchr(op, ',');
@@ -408,10 +401,10 @@ static int smack_sb_statfs(struct dentry *dentry)
408 * Returns 0 if current can write the floor of the filesystem 401 * Returns 0 if current can write the floor of the filesystem
409 * being mounted on, an error code otherwise. 402 * being mounted on, an error code otherwise.
410 */ 403 */
411static int smack_sb_mount(const char *dev_name, struct path *path, 404static int smack_sb_mount(char *dev_name, struct path *path,
412 const char *type, unsigned long flags, void *data) 405 char *type, unsigned long flags, void *data)
413{ 406{
414 struct superblock_smack *sbp = path->dentry->d_sb->s_security; 407 struct superblock_smack *sbp = path->mnt->mnt_sb->s_security;
415 struct smk_audit_info ad; 408 struct smk_audit_info ad;
416 409
417 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); 410 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
@@ -440,7 +433,7 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
440 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); 433 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
441 smk_ad_setfield_u_fs_path(&ad, path); 434 smk_ad_setfield_u_fs_path(&ad, path);
442 435
443 sbp = path.dentry->d_sb->s_security; 436 sbp = mnt->mnt_sb->s_security;
444 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); 437 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
445} 438}
446 439
@@ -448,17 +441,11 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
448 * BPRM hooks 441 * BPRM hooks
449 */ 442 */
450 443
451/**
452 * smack_bprm_set_creds - set creds for exec
453 * @bprm: the exec information
454 *
455 * Returns 0 if it gets a blob, -ENOMEM otherwise
456 */
457static int smack_bprm_set_creds(struct linux_binprm *bprm) 444static int smack_bprm_set_creds(struct linux_binprm *bprm)
458{ 445{
459 struct inode *inode = bprm->file->f_path.dentry->d_inode; 446 struct task_smack *tsp = bprm->cred->security;
460 struct task_smack *bsp = bprm->cred->security;
461 struct inode_smack *isp; 447 struct inode_smack *isp;
448 struct dentry *dp;
462 int rc; 449 int rc;
463 450
464 rc = cap_bprm_set_creds(bprm); 451 rc = cap_bprm_set_creds(bprm);
@@ -468,48 +455,20 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm)
468 if (bprm->cred_prepared) 455 if (bprm->cred_prepared)
469 return 0; 456 return 0;
470 457
471 isp = inode->i_security; 458 if (bprm->file == NULL || bprm->file->f_dentry == NULL)
472 if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
473 return 0; 459 return 0;
474 460
475 if (bprm->unsafe) 461 dp = bprm->file->f_dentry;
476 return -EPERM;
477
478 bsp->smk_task = isp->smk_task;
479 bprm->per_clear |= PER_CLEAR_ON_SETID;
480
481 return 0;
482}
483 462
484/** 463 if (dp->d_inode == NULL)
485 * smack_bprm_committing_creds - Prepare to install the new credentials 464 return 0;
486 * from bprm.
487 *
488 * @bprm: binprm for exec
489 */
490static void smack_bprm_committing_creds(struct linux_binprm *bprm)
491{
492 struct task_smack *bsp = bprm->cred->security;
493
494 if (bsp->smk_task != bsp->smk_forked)
495 current->pdeath_signal = 0;
496}
497 465
498/** 466 isp = dp->d_inode->i_security;
499 * smack_bprm_secureexec - Return the decision to use secureexec.
500 * @bprm: binprm for exec
501 *
502 * Returns 0 on success.
503 */
504static int smack_bprm_secureexec(struct linux_binprm *bprm)
505{
506 struct task_smack *tsp = current_security();
507 int ret = cap_bprm_secureexec(bprm);
508 467
509 if (!ret && (tsp->smk_task != tsp->smk_forked)) 468 if (isp->smk_task != NULL)
510 ret = 1; 469 tsp->smk_task = isp->smk_task;
511 470
512 return ret; 471 return 0;
513} 472}
514 473
515/* 474/*
@@ -557,38 +516,31 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
557 const struct qstr *qstr, char **name, 516 const struct qstr *qstr, char **name,
558 void **value, size_t *len) 517 void **value, size_t *len)
559{ 518{
560 struct smack_known *skp;
561 struct inode_smack *issp = inode->i_security;
562 char *csp = smk_of_current();
563 char *isp = smk_of_inode(inode); 519 char *isp = smk_of_inode(inode);
564 char *dsp = smk_of_inode(dir); 520 char *dsp = smk_of_inode(dir);
565 int may; 521 int may;
566 522
567 if (name) { 523 if (name) {
568 *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_NOFS); 524 *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL);
569 if (*name == NULL) 525 if (*name == NULL)
570 return -ENOMEM; 526 return -ENOMEM;
571 } 527 }
572 528
573 if (value) { 529 if (value) {
574 skp = smk_find_entry(csp);
575 rcu_read_lock(); 530 rcu_read_lock();
576 may = smk_access_entry(csp, dsp, &skp->smk_rules); 531 may = smk_access_entry(smk_of_current(), dsp, &smack_rule_list);
577 rcu_read_unlock(); 532 rcu_read_unlock();
578 533
579 /* 534 /*
580 * If the access rule allows transmutation and 535 * If the access rule allows transmutation and
581 * the directory requests transmutation then 536 * the directory requests transmutation then
582 * by all means transmute. 537 * by all means transmute.
583 * Mark the inode as changed.
584 */ 538 */
585 if (may > 0 && ((may & MAY_TRANSMUTE) != 0) && 539 if (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
586 smk_inode_transmutable(dir)) { 540 smk_inode_transmutable(dir))
587 isp = dsp; 541 isp = dsp;
588 issp->smk_flags |= SMK_INODE_CHANGED;
589 }
590 542
591 *value = kstrdup(isp, GFP_NOFS); 543 *value = kstrdup(isp, GFP_KERNEL);
592 if (*value == NULL) 544 if (*value == NULL)
593 return -ENOMEM; 545 return -ENOMEM;
594 } 546 }
@@ -821,17 +773,17 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
821 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || 773 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
822 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || 774 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
823 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { 775 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
824 if (!smack_privileged(CAP_MAC_ADMIN)) 776 if (!capable(CAP_MAC_ADMIN))
825 rc = -EPERM; 777 rc = -EPERM;
826 /* 778 /*
827 * check label validity here so import wont fail on 779 * check label validity here so import wont fail on
828 * post_setxattr 780 * post_setxattr
829 */ 781 */
830 if (size == 0 || size >= SMK_LONGLABEL || 782 if (size == 0 || size >= SMK_LABELLEN ||
831 smk_import(value, size) == NULL) 783 smk_import(value, size) == NULL)
832 rc = -EINVAL; 784 rc = -EINVAL;
833 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { 785 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
834 if (!smack_privileged(CAP_MAC_ADMIN)) 786 if (!capable(CAP_MAC_ADMIN))
835 rc = -EPERM; 787 rc = -EPERM;
836 if (size != TRANS_TRUE_SIZE || 788 if (size != TRANS_TRUE_SIZE ||
837 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) 789 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
@@ -889,7 +841,7 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
889 return; 841 return;
890} 842}
891 843
892/** 844/*
893 * smack_inode_getxattr - Smack check on getxattr 845 * smack_inode_getxattr - Smack check on getxattr
894 * @dentry: the object 846 * @dentry: the object
895 * @name: unused 847 * @name: unused
@@ -906,7 +858,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
906 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); 858 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
907} 859}
908 860
909/** 861/*
910 * smack_inode_removexattr - Smack check on removexattr 862 * smack_inode_removexattr - Smack check on removexattr
911 * @dentry: the object 863 * @dentry: the object
912 * @name: name of the attribute 864 * @name: name of the attribute
@@ -927,7 +879,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
927 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || 879 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
928 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || 880 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
929 strcmp(name, XATTR_NAME_SMACKMMAP)) { 881 strcmp(name, XATTR_NAME_SMACKMMAP)) {
930 if (!smack_privileged(CAP_MAC_ADMIN)) 882 if (!capable(CAP_MAC_ADMIN))
931 rc = -EPERM; 883 rc = -EPERM;
932 } else 884 } else
933 rc = cap_inode_removexattr(dentry, name); 885 rc = cap_inode_removexattr(dentry, name);
@@ -1136,38 +1088,43 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
1136 * @cmd: what action to check 1088 * @cmd: what action to check
1137 * @arg: unused 1089 * @arg: unused
1138 * 1090 *
1139 * Generally these operations are harmless.
1140 * File locking operations present an obvious mechanism
1141 * for passing information, so they require write access.
1142 *
1143 * Returns 0 if current has access, error code otherwise 1091 * Returns 0 if current has access, error code otherwise
1144 */ 1092 */
1145static int smack_file_fcntl(struct file *file, unsigned int cmd, 1093static int smack_file_fcntl(struct file *file, unsigned int cmd,
1146 unsigned long arg) 1094 unsigned long arg)
1147{ 1095{
1148 struct smk_audit_info ad; 1096 struct smk_audit_info ad;
1149 int rc = 0; 1097 int rc;
1150 1098
1099 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1100 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1151 1101
1152 switch (cmd) { 1102 switch (cmd) {
1103 case F_DUPFD:
1104 case F_GETFD:
1105 case F_GETFL:
1153 case F_GETLK: 1106 case F_GETLK:
1107 case F_GETOWN:
1108 case F_GETSIG:
1109 rc = smk_curacc(file->f_security, MAY_READ, &ad);
1110 break;
1111 case F_SETFD:
1112 case F_SETFL:
1154 case F_SETLK: 1113 case F_SETLK:
1155 case F_SETLKW: 1114 case F_SETLKW:
1156 case F_SETOWN: 1115 case F_SETOWN:
1157 case F_SETSIG: 1116 case F_SETSIG:
1158 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1159 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1160 rc = smk_curacc(file->f_security, MAY_WRITE, &ad); 1117 rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
1161 break; 1118 break;
1162 default: 1119 default:
1163 break; 1120 rc = smk_curacc(file->f_security, MAY_READWRITE, &ad);
1164 } 1121 }
1165 1122
1166 return rc; 1123 return rc;
1167} 1124}
1168 1125
1169/** 1126/**
1170 * smack_mmap_file : 1127 * smack_file_mmap :
1171 * Check permissions for a mmap operation. The @file may be NULL, e.g. 1128 * Check permissions for a mmap operation. The @file may be NULL, e.g.
1172 * if mapping anonymous memory. 1129 * if mapping anonymous memory.
1173 * @file contains the file structure for file to map (may be NULL). 1130 * @file contains the file structure for file to map (may be NULL).
@@ -1176,11 +1133,11 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
1176 * @flags contains the operational flags. 1133 * @flags contains the operational flags.
1177 * Return 0 if permission is granted. 1134 * Return 0 if permission is granted.
1178 */ 1135 */
1179static int smack_mmap_file(struct file *file, 1136static int smack_file_mmap(struct file *file,
1180 unsigned long reqprot, unsigned long prot, 1137 unsigned long reqprot, unsigned long prot,
1181 unsigned long flags) 1138 unsigned long flags, unsigned long addr,
1139 unsigned long addr_only)
1182{ 1140{
1183 struct smack_known *skp;
1184 struct smack_rule *srp; 1141 struct smack_rule *srp;
1185 struct task_smack *tsp; 1142 struct task_smack *tsp;
1186 char *sp; 1143 char *sp;
@@ -1193,6 +1150,11 @@ static int smack_mmap_file(struct file *file,
1193 int tmay; 1150 int tmay;
1194 int rc; 1151 int rc;
1195 1152
1153 /* do DAC check on address space usage */
1154 rc = cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);
1155 if (rc || addr_only)
1156 return rc;
1157
1196 if (file == NULL || file->f_dentry == NULL) 1158 if (file == NULL || file->f_dentry == NULL)
1197 return 0; 1159 return 0;
1198 1160
@@ -1208,7 +1170,6 @@ static int smack_mmap_file(struct file *file,
1208 1170
1209 tsp = current_security(); 1171 tsp = current_security();
1210 sp = smk_of_current(); 1172 sp = smk_of_current();
1211 skp = smk_find_entry(sp);
1212 rc = 0; 1173 rc = 0;
1213 1174
1214 rcu_read_lock(); 1175 rcu_read_lock();
@@ -1216,8 +1177,15 @@ static int smack_mmap_file(struct file *file,
1216 * For each Smack rule associated with the subject 1177 * For each Smack rule associated with the subject
1217 * label verify that the SMACK64MMAP also has access 1178 * label verify that the SMACK64MMAP also has access
1218 * to that rule's object label. 1179 * to that rule's object label.
1180 *
1181 * Because neither of the labels comes
1182 * from the networking code it is sufficient
1183 * to compare pointers.
1219 */ 1184 */
1220 list_for_each_entry_rcu(srp, &skp->smk_rules, list) { 1185 list_for_each_entry_rcu(srp, &smack_rule_list, list) {
1186 if (srp->smk_subject != sp)
1187 continue;
1188
1221 osmack = srp->smk_object; 1189 osmack = srp->smk_object;
1222 /* 1190 /*
1223 * Matching labels always allows access. 1191 * Matching labels always allows access.
@@ -1246,8 +1214,7 @@ static int smack_mmap_file(struct file *file,
1246 * If there isn't one a SMACK64MMAP subject 1214 * If there isn't one a SMACK64MMAP subject
1247 * can't have as much access as current. 1215 * can't have as much access as current.
1248 */ 1216 */
1249 skp = smk_find_entry(msmack); 1217 mmay = smk_access_entry(msmack, osmack, &smack_rule_list);
1250 mmay = smk_access_entry(msmack, osmack, &skp->smk_rules);
1251 if (mmay == -ENOENT) { 1218 if (mmay == -ENOENT) {
1252 rc = -EACCES; 1219 rc = -EACCES;
1253 break; 1220 break;
@@ -1348,24 +1315,6 @@ static int smack_file_receive(struct file *file)
1348 return smk_curacc(file->f_security, may, &ad); 1315 return smk_curacc(file->f_security, may, &ad);
1349} 1316}
1350 1317
1351/**
1352 * smack_file_open - Smack dentry open processing
1353 * @file: the object
1354 * @cred: unused
1355 *
1356 * Set the security blob in the file structure.
1357 *
1358 * Returns 0
1359 */
1360static int smack_file_open(struct file *file, const struct cred *cred)
1361{
1362 struct inode_smack *isp = file->f_path.dentry->d_inode->i_security;
1363
1364 file->f_security = isp->smk_inode;
1365
1366 return 0;
1367}
1368
1369/* 1318/*
1370 * Task hooks 1319 * Task hooks
1371 */ 1320 */
@@ -1506,17 +1455,15 @@ static int smack_kernel_create_files_as(struct cred *new,
1506/** 1455/**
1507 * smk_curacc_on_task - helper to log task related access 1456 * smk_curacc_on_task - helper to log task related access
1508 * @p: the task object 1457 * @p: the task object
1509 * @access: the access requested 1458 * @access : the access requested
1510 * @caller: name of the calling function for audit
1511 * 1459 *
1512 * Return 0 if access is permitted 1460 * Return 0 if access is permitted
1513 */ 1461 */
1514static int smk_curacc_on_task(struct task_struct *p, int access, 1462static int smk_curacc_on_task(struct task_struct *p, int access)
1515 const char *caller)
1516{ 1463{
1517 struct smk_audit_info ad; 1464 struct smk_audit_info ad;
1518 1465
1519 smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); 1466 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1520 smk_ad_setfield_u_tsk(&ad, p); 1467 smk_ad_setfield_u_tsk(&ad, p);
1521 return smk_curacc(smk_of_task(task_security(p)), access, &ad); 1468 return smk_curacc(smk_of_task(task_security(p)), access, &ad);
1522} 1469}
@@ -1530,7 +1477,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access,
1530 */ 1477 */
1531static int smack_task_setpgid(struct task_struct *p, pid_t pgid) 1478static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
1532{ 1479{
1533 return smk_curacc_on_task(p, MAY_WRITE, __func__); 1480 return smk_curacc_on_task(p, MAY_WRITE);
1534} 1481}
1535 1482
1536/** 1483/**
@@ -1541,7 +1488,7 @@ static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
1541 */ 1488 */
1542static int smack_task_getpgid(struct task_struct *p) 1489static int smack_task_getpgid(struct task_struct *p)
1543{ 1490{
1544 return smk_curacc_on_task(p, MAY_READ, __func__); 1491 return smk_curacc_on_task(p, MAY_READ);
1545} 1492}
1546 1493
1547/** 1494/**
@@ -1552,7 +1499,7 @@ static int smack_task_getpgid(struct task_struct *p)
1552 */ 1499 */
1553static int smack_task_getsid(struct task_struct *p) 1500static int smack_task_getsid(struct task_struct *p)
1554{ 1501{
1555 return smk_curacc_on_task(p, MAY_READ, __func__); 1502 return smk_curacc_on_task(p, MAY_READ);
1556} 1503}
1557 1504
1558/** 1505/**
@@ -1580,7 +1527,7 @@ static int smack_task_setnice(struct task_struct *p, int nice)
1580 1527
1581 rc = cap_task_setnice(p, nice); 1528 rc = cap_task_setnice(p, nice);
1582 if (rc == 0) 1529 if (rc == 0)
1583 rc = smk_curacc_on_task(p, MAY_WRITE, __func__); 1530 rc = smk_curacc_on_task(p, MAY_WRITE);
1584 return rc; 1531 return rc;
1585} 1532}
1586 1533
@@ -1597,7 +1544,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
1597 1544
1598 rc = cap_task_setioprio(p, ioprio); 1545 rc = cap_task_setioprio(p, ioprio);
1599 if (rc == 0) 1546 if (rc == 0)
1600 rc = smk_curacc_on_task(p, MAY_WRITE, __func__); 1547 rc = smk_curacc_on_task(p, MAY_WRITE);
1601 return rc; 1548 return rc;
1602} 1549}
1603 1550
@@ -1609,7 +1556,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
1609 */ 1556 */
1610static int smack_task_getioprio(struct task_struct *p) 1557static int smack_task_getioprio(struct task_struct *p)
1611{ 1558{
1612 return smk_curacc_on_task(p, MAY_READ, __func__); 1559 return smk_curacc_on_task(p, MAY_READ);
1613} 1560}
1614 1561
1615/** 1562/**
@@ -1626,7 +1573,7 @@ static int smack_task_setscheduler(struct task_struct *p)
1626 1573
1627 rc = cap_task_setscheduler(p); 1574 rc = cap_task_setscheduler(p);
1628 if (rc == 0) 1575 if (rc == 0)
1629 rc = smk_curacc_on_task(p, MAY_WRITE, __func__); 1576 rc = smk_curacc_on_task(p, MAY_WRITE);
1630 return rc; 1577 return rc;
1631} 1578}
1632 1579
@@ -1638,7 +1585,7 @@ static int smack_task_setscheduler(struct task_struct *p)
1638 */ 1585 */
1639static int smack_task_getscheduler(struct task_struct *p) 1586static int smack_task_getscheduler(struct task_struct *p)
1640{ 1587{
1641 return smk_curacc_on_task(p, MAY_READ, __func__); 1588 return smk_curacc_on_task(p, MAY_READ);
1642} 1589}
1643 1590
1644/** 1591/**
@@ -1649,7 +1596,7 @@ static int smack_task_getscheduler(struct task_struct *p)
1649 */ 1596 */
1650static int smack_task_movememory(struct task_struct *p) 1597static int smack_task_movememory(struct task_struct *p)
1651{ 1598{
1652 return smk_curacc_on_task(p, MAY_WRITE, __func__); 1599 return smk_curacc_on_task(p, MAY_WRITE);
1653} 1600}
1654 1601
1655/** 1602/**
@@ -1691,19 +1638,39 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1691 * smack_task_wait - Smack access check for waiting 1638 * smack_task_wait - Smack access check for waiting
1692 * @p: task to wait for 1639 * @p: task to wait for
1693 * 1640 *
1694 * Returns 0 1641 * Returns 0 if current can wait for p, error code otherwise
1695 */ 1642 */
1696static int smack_task_wait(struct task_struct *p) 1643static int smack_task_wait(struct task_struct *p)
1697{ 1644{
1645 struct smk_audit_info ad;
1646 char *sp = smk_of_current();
1647 char *tsp = smk_of_forked(task_security(p));
1648 int rc;
1649
1650 /* we don't log here, we can be overriden */
1651 rc = smk_access(tsp, sp, MAY_WRITE, NULL);
1652 if (rc == 0)
1653 goto out_log;
1654
1698 /* 1655 /*
1699 * Allow the operation to succeed. 1656 * Allow the operation to succeed if either task
1700 * Zombies are bad. 1657 * has privilege to perform operations that might
1701 * In userless environments (e.g. phones) programs 1658 * account for the smack labels having gotten to
1702 * get marked with SMACK64EXEC and even if the parent 1659 * be different in the first place.
1703 * and child shouldn't be talking the parent still 1660 *
1704 * may expect to know when the child exits. 1661 * This breaks the strict subject/object access
1662 * control ideal, taking the object's privilege
1663 * state into account in the decision as well as
1664 * the smack value.
1705 */ 1665 */
1706 return 0; 1666 if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE))
1667 rc = 0;
1668 /* we log only if we didn't get overriden */
1669 out_log:
1670 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1671 smk_ad_setfield_u_tsk(&ad, p);
1672 smack_log(tsp, sp, MAY_WRITE, rc, &ad);
1673 return rc;
1707} 1674}
1708 1675
1709/** 1676/**
@@ -1744,7 +1711,7 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1744 1711
1745 ssp->smk_in = csp; 1712 ssp->smk_in = csp;
1746 ssp->smk_out = csp; 1713 ssp->smk_out = csp;
1747 ssp->smk_packet = NULL; 1714 ssp->smk_packet[0] = '\0';
1748 1715
1749 sk->sk_security = ssp; 1716 sk->sk_security = ssp;
1750 1717
@@ -1800,6 +1767,65 @@ static char *smack_host_label(struct sockaddr_in *sip)
1800} 1767}
1801 1768
1802/** 1769/**
1770 * smack_set_catset - convert a capset to netlabel mls categories
1771 * @catset: the Smack categories
1772 * @sap: where to put the netlabel categories
1773 *
1774 * Allocates and fills attr.mls.cat
1775 */
1776static void smack_set_catset(char *catset, struct netlbl_lsm_secattr *sap)
1777{
1778 unsigned char *cp;
1779 unsigned char m;
1780 int cat;
1781 int rc;
1782 int byte;
1783
1784 if (!catset)
1785 return;
1786
1787 sap->flags |= NETLBL_SECATTR_MLS_CAT;
1788 sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1789 sap->attr.mls.cat->startbit = 0;
1790
1791 for (cat = 1, cp = catset, byte = 0; byte < SMK_LABELLEN; cp++, byte++)
1792 for (m = 0x80; m != 0; m >>= 1, cat++) {
1793 if ((m & *cp) == 0)
1794 continue;
1795 rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat,
1796 cat, GFP_ATOMIC);
1797 }
1798}
1799
1800/**
1801 * smack_to_secattr - fill a secattr from a smack value
1802 * @smack: the smack value
1803 * @nlsp: where the result goes
1804 *
1805 * Casey says that CIPSO is good enough for now.
1806 * It can be used to effect.
1807 * It can also be abused to effect when necessary.
1808 * Apologies to the TSIG group in general and GW in particular.
1809 */
1810static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp)
1811{
1812 struct smack_cipso cipso;
1813 int rc;
1814
1815 nlsp->domain = smack;
1816 nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
1817
1818 rc = smack_to_cipso(smack, &cipso);
1819 if (rc == 0) {
1820 nlsp->attr.mls.lvl = cipso.smk_level;
1821 smack_set_catset(cipso.smk_catset, nlsp);
1822 } else {
1823 nlsp->attr.mls.lvl = smack_cipso_direct;
1824 smack_set_catset(smack, nlsp);
1825 }
1826}
1827
1828/**
1803 * smack_netlabel - Set the secattr on a socket 1829 * smack_netlabel - Set the secattr on a socket
1804 * @sk: the socket 1830 * @sk: the socket
1805 * @labeled: socket label scheme 1831 * @labeled: socket label scheme
@@ -1811,8 +1837,8 @@ static char *smack_host_label(struct sockaddr_in *sip)
1811 */ 1837 */
1812static int smack_netlabel(struct sock *sk, int labeled) 1838static int smack_netlabel(struct sock *sk, int labeled)
1813{ 1839{
1814 struct smack_known *skp;
1815 struct socket_smack *ssp = sk->sk_security; 1840 struct socket_smack *ssp = sk->sk_security;
1841 struct netlbl_lsm_secattr secattr;
1816 int rc = 0; 1842 int rc = 0;
1817 1843
1818 /* 1844 /*
@@ -1830,8 +1856,10 @@ static int smack_netlabel(struct sock *sk, int labeled)
1830 labeled == SMACK_UNLABELED_SOCKET) 1856 labeled == SMACK_UNLABELED_SOCKET)
1831 netlbl_sock_delattr(sk); 1857 netlbl_sock_delattr(sk);
1832 else { 1858 else {
1833 skp = smk_find_entry(ssp->smk_out); 1859 netlbl_secattr_init(&secattr);
1834 rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel); 1860 smack_to_secattr(ssp->smk_out, &secattr);
1861 rc = netlbl_sock_setattr(sk, sk->sk_family, &secattr);
1862 netlbl_secattr_destroy(&secattr);
1835 } 1863 }
1836 1864
1837 bh_unlock_sock(sk); 1865 bh_unlock_sock(sk);
@@ -1862,15 +1890,13 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1862 rcu_read_lock(); 1890 rcu_read_lock();
1863 hostsp = smack_host_label(sap); 1891 hostsp = smack_host_label(sap);
1864 if (hostsp != NULL) { 1892 if (hostsp != NULL) {
1893 sk_lbl = SMACK_UNLABELED_SOCKET;
1865#ifdef CONFIG_AUDIT 1894#ifdef CONFIG_AUDIT
1866 struct lsm_network_audit net; 1895 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
1867 1896 ad.a.u.net.family = sap->sin_family;
1868 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); 1897 ad.a.u.net.dport = sap->sin_port;
1869 ad.a.u.net->family = sap->sin_family; 1898 ad.a.u.net.v4info.daddr = sap->sin_addr.s_addr;
1870 ad.a.u.net->dport = sap->sin_port;
1871 ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
1872#endif 1899#endif
1873 sk_lbl = SMACK_UNLABELED_SOCKET;
1874 rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); 1900 rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad);
1875 } else { 1901 } else {
1876 sk_lbl = SMACK_CIPSO_SOCKET; 1902 sk_lbl = SMACK_CIPSO_SOCKET;
@@ -1904,7 +1930,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1904 struct socket *sock; 1930 struct socket *sock;
1905 int rc = 0; 1931 int rc = 0;
1906 1932
1907 if (value == NULL || size > SMK_LONGLABEL || size == 0) 1933 if (value == NULL || size > SMK_LABELLEN || size == 0)
1908 return -EACCES; 1934 return -EACCES;
1909 1935
1910 sp = smk_import(value, size); 1936 sp = smk_import(value, size);
@@ -2471,7 +2497,6 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2471 char *final; 2497 char *final;
2472 char trattr[TRANS_TRUE_SIZE]; 2498 char trattr[TRANS_TRUE_SIZE];
2473 int transflag = 0; 2499 int transflag = 0;
2474 int rc;
2475 struct dentry *dp; 2500 struct dentry *dp;
2476 2501
2477 if (inode == NULL) 2502 if (inode == NULL)
@@ -2590,38 +2615,17 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2590 */ 2615 */
2591 dp = dget(opt_dentry); 2616 dp = dget(opt_dentry);
2592 fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp); 2617 fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp);
2593 if (fetched != NULL) 2618 if (fetched != NULL) {
2594 final = fetched; 2619 final = fetched;
2595 2620 if (S_ISDIR(inode->i_mode)) {
2596 /* 2621 trattr[0] = '\0';
2597 * Transmuting directory 2622 inode->i_op->getxattr(dp,
2598 */
2599 if (S_ISDIR(inode->i_mode)) {
2600 /*
2601 * If this is a new directory and the label was
2602 * transmuted when the inode was initialized
2603 * set the transmute attribute on the directory
2604 * and mark the inode.
2605 *
2606 * If there is a transmute attribute on the
2607 * directory mark the inode.
2608 */
2609 if (isp->smk_flags & SMK_INODE_CHANGED) {
2610 isp->smk_flags &= ~SMK_INODE_CHANGED;
2611 rc = inode->i_op->setxattr(dp,
2612 XATTR_NAME_SMACKTRANSMUTE, 2623 XATTR_NAME_SMACKTRANSMUTE,
2613 TRANS_TRUE, TRANS_TRUE_SIZE, 2624 trattr, TRANS_TRUE_SIZE);
2614 0); 2625 if (strncmp(trattr, TRANS_TRUE,
2615 } else { 2626 TRANS_TRUE_SIZE) == 0)
2616 rc = inode->i_op->getxattr(dp, 2627 transflag = SMK_INODE_TRANSMUTE;
2617 XATTR_NAME_SMACKTRANSMUTE, trattr,
2618 TRANS_TRUE_SIZE);
2619 if (rc >= 0 && strncmp(trattr, TRANS_TRUE,
2620 TRANS_TRUE_SIZE) != 0)
2621 rc = -EINVAL;
2622 } 2628 }
2623 if (rc >= 0)
2624 transflag = SMK_INODE_TRANSMUTE;
2625 } 2629 }
2626 isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); 2630 isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
2627 isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); 2631 isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
@@ -2684,7 +2688,9 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
2684static int smack_setprocattr(struct task_struct *p, char *name, 2688static int smack_setprocattr(struct task_struct *p, char *name,
2685 void *value, size_t size) 2689 void *value, size_t size)
2686{ 2690{
2691 int rc;
2687 struct task_smack *tsp; 2692 struct task_smack *tsp;
2693 struct task_smack *oldtsp;
2688 struct cred *new; 2694 struct cred *new;
2689 char *newsmack; 2695 char *newsmack;
2690 2696
@@ -2695,10 +2701,10 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2695 if (p != current) 2701 if (p != current)
2696 return -EPERM; 2702 return -EPERM;
2697 2703
2698 if (!smack_privileged(CAP_MAC_ADMIN)) 2704 if (!capable(CAP_MAC_ADMIN))
2699 return -EPERM; 2705 return -EPERM;
2700 2706
2701 if (value == NULL || size == 0 || size >= SMK_LONGLABEL) 2707 if (value == NULL || size == 0 || size >= SMK_LABELLEN)
2702 return -EINVAL; 2708 return -EINVAL;
2703 2709
2704 if (strcmp(name, "current") != 0) 2710 if (strcmp(name, "current") != 0)
@@ -2714,13 +2720,21 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2714 if (newsmack == smack_known_web.smk_known) 2720 if (newsmack == smack_known_web.smk_known)
2715 return -EPERM; 2721 return -EPERM;
2716 2722
2723 oldtsp = p->cred->security;
2717 new = prepare_creds(); 2724 new = prepare_creds();
2718 if (new == NULL) 2725 if (new == NULL)
2719 return -ENOMEM; 2726 return -ENOMEM;
2720 2727
2721 tsp = new->security; 2728 tsp = new_task_smack(newsmack, oldtsp->smk_forked, GFP_KERNEL);
2722 tsp->smk_task = newsmack; 2729 if (tsp == NULL) {
2730 kfree(new);
2731 return -ENOMEM;
2732 }
2733 rc = smk_copy_rules(&tsp->smk_rules, &oldtsp->smk_rules, GFP_KERNEL);
2734 if (rc != 0)
2735 return rc;
2723 2736
2737 new->security = tsp;
2724 commit_creds(new); 2738 commit_creds(new);
2725 return size; 2739 return size;
2726} 2740}
@@ -2739,28 +2753,15 @@ static int smack_unix_stream_connect(struct sock *sock,
2739{ 2753{
2740 struct socket_smack *ssp = sock->sk_security; 2754 struct socket_smack *ssp = sock->sk_security;
2741 struct socket_smack *osp = other->sk_security; 2755 struct socket_smack *osp = other->sk_security;
2742 struct socket_smack *nsp = newsk->sk_security;
2743 struct smk_audit_info ad; 2756 struct smk_audit_info ad;
2744 int rc = 0; 2757 int rc = 0;
2745 2758
2746#ifdef CONFIG_AUDIT 2759 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2747 struct lsm_network_audit net;
2748
2749 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2750 smk_ad_setfield_u_net_sk(&ad, other); 2760 smk_ad_setfield_u_net_sk(&ad, other);
2751#endif
2752 2761
2753 if (!smack_privileged(CAP_MAC_OVERRIDE)) 2762 if (!capable(CAP_MAC_OVERRIDE))
2754 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 2763 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2755 2764
2756 /*
2757 * Cross reference the peer labels for SO_PEERSEC.
2758 */
2759 if (rc == 0) {
2760 nsp->smk_packet = ssp->smk_out;
2761 ssp->smk_packet = osp->smk_out;
2762 }
2763
2764 return rc; 2765 return rc;
2765} 2766}
2766 2767
@@ -2779,14 +2780,10 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2779 struct smk_audit_info ad; 2780 struct smk_audit_info ad;
2780 int rc = 0; 2781 int rc = 0;
2781 2782
2782#ifdef CONFIG_AUDIT 2783 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2783 struct lsm_network_audit net;
2784
2785 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2786 smk_ad_setfield_u_net_sk(&ad, other->sk); 2784 smk_ad_setfield_u_net_sk(&ad, other->sk);
2787#endif
2788 2785
2789 if (!smack_privileged(CAP_MAC_OVERRIDE)) 2786 if (!capable(CAP_MAC_OVERRIDE))
2790 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 2787 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2791 2788
2792 return rc; 2789 return rc;
@@ -2816,19 +2813,19 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
2816 return smack_netlabel_send(sock->sk, sip); 2813 return smack_netlabel_send(sock->sk, sip);
2817} 2814}
2818 2815
2816
2819/** 2817/**
2820 * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack 2818 * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack
2821 * @sap: netlabel secattr 2819 * @sap: netlabel secattr
2822 * @ssp: socket security information 2820 * @sip: where to put the result
2823 * 2821 *
2824 * Returns a pointer to a Smack label found on the label list. 2822 * Copies a smack label into sip
2825 */ 2823 */
2826static char *smack_from_secattr(struct netlbl_lsm_secattr *sap, 2824static void smack_from_secattr(struct netlbl_lsm_secattr *sap, char *sip)
2827 struct socket_smack *ssp)
2828{ 2825{
2829 struct smack_known *kp; 2826 char smack[SMK_LABELLEN];
2830 char *sp; 2827 char *sp;
2831 int found = 0; 2828 int pcat;
2832 2829
2833 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { 2830 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
2834 /* 2831 /*
@@ -2836,30 +2833,34 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2836 * If there are flags but no level netlabel isn't 2833 * If there are flags but no level netlabel isn't
2837 * behaving the way we expect it to. 2834 * behaving the way we expect it to.
2838 * 2835 *
2839 * Look it up in the label table 2836 * Get the categories, if any
2840 * Without guidance regarding the smack value 2837 * Without guidance regarding the smack value
2841 * for the packet fall back on the network 2838 * for the packet fall back on the network
2842 * ambient value. 2839 * ambient value.
2843 */ 2840 */
2844 rcu_read_lock(); 2841 memset(smack, '\0', SMK_LABELLEN);
2845 list_for_each_entry(kp, &smack_known_list, list) { 2842 if ((sap->flags & NETLBL_SECATTR_MLS_CAT) != 0)
2846 if (sap->attr.mls.lvl != kp->smk_netlabel.attr.mls.lvl) 2843 for (pcat = -1;;) {
2847 continue; 2844 pcat = netlbl_secattr_catmap_walk(
2848 if (memcmp(sap->attr.mls.cat, 2845 sap->attr.mls.cat, pcat + 1);
2849 kp->smk_netlabel.attr.mls.cat, 2846 if (pcat < 0)
2850 SMK_CIPSOLEN) != 0) 2847 break;
2851 continue; 2848 smack_catset_bit(pcat, smack);
2852 found = 1; 2849 }
2853 break; 2850 /*
2851 * If it is CIPSO using smack direct mapping
2852 * we are already done. WeeHee.
2853 */
2854 if (sap->attr.mls.lvl == smack_cipso_direct) {
2855 memcpy(sip, smack, SMK_MAXLEN);
2856 return;
2854 } 2857 }
2855 rcu_read_unlock(); 2858 /*
2856 2859 * Look it up in the supplied table if it is not
2857 if (found) 2860 * a direct mapping.
2858 return kp->smk_known; 2861 */
2859 2862 smack_from_cipso(sap->attr.mls.lvl, smack, sip);
2860 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known) 2863 return;
2861 return smack_known_web.smk_known;
2862 return smack_known_star.smk_known;
2863 } 2864 }
2864 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) { 2865 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
2865 /* 2866 /*
@@ -2874,14 +2875,16 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2874 * secid is from a fallback. 2875 * secid is from a fallback.
2875 */ 2876 */
2876 BUG_ON(sp == NULL); 2877 BUG_ON(sp == NULL);
2877 return sp; 2878 strncpy(sip, sp, SMK_MAXLEN);
2879 return;
2878 } 2880 }
2879 /* 2881 /*
2880 * Without guidance regarding the smack value 2882 * Without guidance regarding the smack value
2881 * for the packet fall back on the network 2883 * for the packet fall back on the network
2882 * ambient value. 2884 * ambient value.
2883 */ 2885 */
2884 return smack_net_ambient; 2886 strncpy(sip, smack_net_ambient, SMK_MAXLEN);
2887 return;
2885} 2888}
2886 2889
2887/** 2890/**
@@ -2895,12 +2898,10 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2895{ 2898{
2896 struct netlbl_lsm_secattr secattr; 2899 struct netlbl_lsm_secattr secattr;
2897 struct socket_smack *ssp = sk->sk_security; 2900 struct socket_smack *ssp = sk->sk_security;
2901 char smack[SMK_LABELLEN];
2898 char *csp; 2902 char *csp;
2899 int rc; 2903 int rc;
2900 struct smk_audit_info ad; 2904 struct smk_audit_info ad;
2901#ifdef CONFIG_AUDIT
2902 struct lsm_network_audit net;
2903#endif
2904 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) 2905 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
2905 return 0; 2906 return 0;
2906 2907
@@ -2910,17 +2911,18 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2910 netlbl_secattr_init(&secattr); 2911 netlbl_secattr_init(&secattr);
2911 2912
2912 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); 2913 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
2913 if (rc == 0) 2914 if (rc == 0) {
2914 csp = smack_from_secattr(&secattr, ssp); 2915 smack_from_secattr(&secattr, smack);
2915 else 2916 csp = smack;
2917 } else
2916 csp = smack_net_ambient; 2918 csp = smack_net_ambient;
2917 2919
2918 netlbl_secattr_destroy(&secattr); 2920 netlbl_secattr_destroy(&secattr);
2919 2921
2920#ifdef CONFIG_AUDIT 2922#ifdef CONFIG_AUDIT
2921 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); 2923 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2922 ad.a.u.net->family = sk->sk_family; 2924 ad.a.u.net.family = sk->sk_family;
2923 ad.a.u.net->netif = skb->skb_iif; 2925 ad.a.u.net.netif = skb->skb_iif;
2924 ipv4_skb_to_auditdata(skb, &ad.a, NULL); 2926 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
2925#endif 2927#endif
2926 /* 2928 /*
@@ -2949,19 +2951,15 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
2949 int __user *optlen, unsigned len) 2951 int __user *optlen, unsigned len)
2950{ 2952{
2951 struct socket_smack *ssp; 2953 struct socket_smack *ssp;
2952 char *rcp = ""; 2954 int slen;
2953 int slen = 1;
2954 int rc = 0; 2955 int rc = 0;
2955 2956
2956 ssp = sock->sk->sk_security; 2957 ssp = sock->sk->sk_security;
2957 if (ssp->smk_packet != NULL) { 2958 slen = strlen(ssp->smk_packet) + 1;
2958 rcp = ssp->smk_packet;
2959 slen = strlen(rcp) + 1;
2960 }
2961 2959
2962 if (slen > len) 2960 if (slen > len)
2963 rc = -ERANGE; 2961 rc = -ERANGE;
2964 else if (copy_to_user(optval, rcp, slen) != 0) 2962 else if (copy_to_user(optval, ssp->smk_packet, slen) != 0)
2965 rc = -EFAULT; 2963 rc = -EFAULT;
2966 2964
2967 if (put_user(slen, optlen) != 0) 2965 if (put_user(slen, optlen) != 0)
@@ -2984,8 +2982,8 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2984 2982
2985{ 2983{
2986 struct netlbl_lsm_secattr secattr; 2984 struct netlbl_lsm_secattr secattr;
2987 struct socket_smack *ssp = NULL; 2985 struct socket_smack *sp;
2988 char *sp; 2986 char smack[SMK_LABELLEN];
2989 int family = PF_UNSPEC; 2987 int family = PF_UNSPEC;
2990 u32 s = 0; /* 0 is the invalid secid */ 2988 u32 s = 0; /* 0 is the invalid secid */
2991 int rc; 2989 int rc;
@@ -3000,19 +2998,17 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
3000 family = sock->sk->sk_family; 2998 family = sock->sk->sk_family;
3001 2999
3002 if (family == PF_UNIX) { 3000 if (family == PF_UNIX) {
3003 ssp = sock->sk->sk_security; 3001 sp = sock->sk->sk_security;
3004 s = smack_to_secid(ssp->smk_out); 3002 s = smack_to_secid(sp->smk_out);
3005 } else if (family == PF_INET || family == PF_INET6) { 3003 } else if (family == PF_INET || family == PF_INET6) {
3006 /* 3004 /*
3007 * Translate what netlabel gave us. 3005 * Translate what netlabel gave us.
3008 */ 3006 */
3009 if (sock != NULL && sock->sk != NULL)
3010 ssp = sock->sk->sk_security;
3011 netlbl_secattr_init(&secattr); 3007 netlbl_secattr_init(&secattr);
3012 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3008 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3013 if (rc == 0) { 3009 if (rc == 0) {
3014 sp = smack_from_secattr(&secattr, ssp); 3010 smack_from_secattr(&secattr, smack);
3015 s = smack_to_secid(sp); 3011 s = smack_to_secid(smack);
3016 } 3012 }
3017 netlbl_secattr_destroy(&secattr); 3013 netlbl_secattr_destroy(&secattr);
3018 } 3014 }
@@ -3056,18 +3052,13 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3056 struct request_sock *req) 3052 struct request_sock *req)
3057{ 3053{
3058 u16 family = sk->sk_family; 3054 u16 family = sk->sk_family;
3059 struct smack_known *skp;
3060 struct socket_smack *ssp = sk->sk_security; 3055 struct socket_smack *ssp = sk->sk_security;
3061 struct netlbl_lsm_secattr secattr; 3056 struct netlbl_lsm_secattr secattr;
3062 struct sockaddr_in addr; 3057 struct sockaddr_in addr;
3063 struct iphdr *hdr; 3058 struct iphdr *hdr;
3064 char *sp; 3059 char smack[SMK_LABELLEN];
3065 char *hsp;
3066 int rc; 3060 int rc;
3067 struct smk_audit_info ad; 3061 struct smk_audit_info ad;
3068#ifdef CONFIG_AUDIT
3069 struct lsm_network_audit net;
3070#endif
3071 3062
3072 /* handle mapped IPv4 packets arriving via IPv6 sockets */ 3063 /* handle mapped IPv4 packets arriving via IPv6 sockets */
3073 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) 3064 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
@@ -3076,22 +3067,22 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3076 netlbl_secattr_init(&secattr); 3067 netlbl_secattr_init(&secattr);
3077 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3068 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3078 if (rc == 0) 3069 if (rc == 0)
3079 sp = smack_from_secattr(&secattr, ssp); 3070 smack_from_secattr(&secattr, smack);
3080 else 3071 else
3081 sp = smack_known_huh.smk_known; 3072 strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN);
3082 netlbl_secattr_destroy(&secattr); 3073 netlbl_secattr_destroy(&secattr);
3083 3074
3084#ifdef CONFIG_AUDIT 3075#ifdef CONFIG_AUDIT
3085 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); 3076 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
3086 ad.a.u.net->family = family; 3077 ad.a.u.net.family = family;
3087 ad.a.u.net->netif = skb->skb_iif; 3078 ad.a.u.net.netif = skb->skb_iif;
3088 ipv4_skb_to_auditdata(skb, &ad.a, NULL); 3079 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
3089#endif 3080#endif
3090 /* 3081 /*
3091 * Receiving a packet requires that the other end be able to write 3082 * Receiving a packet requires that the other end be able to write
3092 * here. Read access is not required. 3083 * here. Read access is not required.
3093 */ 3084 */
3094 rc = smk_access(sp, ssp->smk_in, MAY_WRITE, &ad); 3085 rc = smk_access(smack, ssp->smk_in, MAY_WRITE, &ad);
3095 if (rc != 0) 3086 if (rc != 0)
3096 return rc; 3087 return rc;
3097 3088
@@ -3099,7 +3090,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3099 * Save the peer's label in the request_sock so we can later setup 3090 * Save the peer's label in the request_sock so we can later setup
3100 * smk_packet in the child socket so that SO_PEERCRED can report it. 3091 * smk_packet in the child socket so that SO_PEERCRED can report it.
3101 */ 3092 */
3102 req->peer_secid = smack_to_secid(sp); 3093 req->peer_secid = smack_to_secid(smack);
3103 3094
3104 /* 3095 /*
3105 * We need to decide if we want to label the incoming connection here 3096 * We need to decide if we want to label the incoming connection here
@@ -3109,14 +3100,16 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3109 hdr = ip_hdr(skb); 3100 hdr = ip_hdr(skb);
3110 addr.sin_addr.s_addr = hdr->saddr; 3101 addr.sin_addr.s_addr = hdr->saddr;
3111 rcu_read_lock(); 3102 rcu_read_lock();
3112 hsp = smack_host_label(&addr); 3103 if (smack_host_label(&addr) == NULL) {
3113 rcu_read_unlock(); 3104 rcu_read_unlock();
3114 3105 netlbl_secattr_init(&secattr);
3115 if (hsp == NULL) { 3106 smack_to_secattr(smack, &secattr);
3116 skp = smk_find_entry(sp); 3107 rc = netlbl_req_setattr(req, &secattr);
3117 rc = netlbl_req_setattr(req, &skp->smk_netlabel); 3108 netlbl_secattr_destroy(&secattr);
3118 } else 3109 } else {
3110 rcu_read_unlock();
3119 netlbl_req_delattr(req); 3111 netlbl_req_delattr(req);
3112 }
3120 3113
3121 return rc; 3114 return rc;
3122} 3115}
@@ -3132,11 +3125,13 @@ static void smack_inet_csk_clone(struct sock *sk,
3132 const struct request_sock *req) 3125 const struct request_sock *req)
3133{ 3126{
3134 struct socket_smack *ssp = sk->sk_security; 3127 struct socket_smack *ssp = sk->sk_security;
3128 char *smack;
3135 3129
3136 if (req->peer_secid != 0) 3130 if (req->peer_secid != 0) {
3137 ssp->smk_packet = smack_from_secid(req->peer_secid); 3131 smack = smack_from_secid(req->peer_secid);
3138 else 3132 strncpy(ssp->smk_packet, smack, SMK_MAXLEN);
3139 ssp->smk_packet = NULL; 3133 } else
3134 ssp->smk_packet[0] = '\0';
3140} 3135}
3141 3136
3142/* 3137/*
@@ -3298,7 +3293,7 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3298 char *rule = vrule; 3293 char *rule = vrule;
3299 3294
3300 if (!rule) { 3295 if (!rule) {
3301 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 3296 audit_log(actx, GFP_KERNEL, AUDIT_SELINUX_ERR,
3302 "Smack: missing rule\n"); 3297 "Smack: missing rule\n");
3303 return -ENOENT; 3298 return -ENOENT;
3304 } 3299 }
@@ -3414,8 +3409,6 @@ struct security_operations smack_ops = {
3414 .sb_umount = smack_sb_umount, 3409 .sb_umount = smack_sb_umount,
3415 3410
3416 .bprm_set_creds = smack_bprm_set_creds, 3411 .bprm_set_creds = smack_bprm_set_creds,
3417 .bprm_committing_creds = smack_bprm_committing_creds,
3418 .bprm_secureexec = smack_bprm_secureexec,
3419 3412
3420 .inode_alloc_security = smack_inode_alloc_security, 3413 .inode_alloc_security = smack_inode_alloc_security,
3421 .inode_free_security = smack_inode_free_security, 3414 .inode_free_security = smack_inode_free_security,
@@ -3442,14 +3435,11 @@ struct security_operations smack_ops = {
3442 .file_ioctl = smack_file_ioctl, 3435 .file_ioctl = smack_file_ioctl,
3443 .file_lock = smack_file_lock, 3436 .file_lock = smack_file_lock,
3444 .file_fcntl = smack_file_fcntl, 3437 .file_fcntl = smack_file_fcntl,
3445 .mmap_file = smack_mmap_file, 3438 .file_mmap = smack_file_mmap,
3446 .mmap_addr = cap_mmap_addr,
3447 .file_set_fowner = smack_file_set_fowner, 3439 .file_set_fowner = smack_file_set_fowner,
3448 .file_send_sigiotask = smack_file_send_sigiotask, 3440 .file_send_sigiotask = smack_file_send_sigiotask,
3449 .file_receive = smack_file_receive, 3441 .file_receive = smack_file_receive,
3450 3442
3451 .file_open = smack_file_open,
3452
3453 .cred_alloc_blank = smack_cred_alloc_blank, 3443 .cred_alloc_blank = smack_cred_alloc_blank,
3454 .cred_free = smack_cred_free, 3444 .cred_free = smack_cred_free,
3455 .cred_prepare = smack_cred_prepare, 3445 .cred_prepare = smack_cred_prepare,
@@ -3539,29 +3529,8 @@ struct security_operations smack_ops = {
3539}; 3529};
3540 3530
3541 3531
3542static __init void init_smack_known_list(void) 3532static __init void init_smack_know_list(void)
3543{ 3533{
3544 /*
3545 * Initialize rule list locks
3546 */
3547 mutex_init(&smack_known_huh.smk_rules_lock);
3548 mutex_init(&smack_known_hat.smk_rules_lock);
3549 mutex_init(&smack_known_floor.smk_rules_lock);
3550 mutex_init(&smack_known_star.smk_rules_lock);
3551 mutex_init(&smack_known_invalid.smk_rules_lock);
3552 mutex_init(&smack_known_web.smk_rules_lock);
3553 /*
3554 * Initialize rule lists
3555 */
3556 INIT_LIST_HEAD(&smack_known_huh.smk_rules);
3557 INIT_LIST_HEAD(&smack_known_hat.smk_rules);
3558 INIT_LIST_HEAD(&smack_known_star.smk_rules);
3559 INIT_LIST_HEAD(&smack_known_floor.smk_rules);
3560 INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
3561 INIT_LIST_HEAD(&smack_known_web.smk_rules);
3562 /*
3563 * Create the known labels list
3564 */
3565 list_add(&smack_known_huh.list, &smack_known_list); 3534 list_add(&smack_known_huh.list, &smack_known_list);
3566 list_add(&smack_known_hat.list, &smack_known_list); 3535 list_add(&smack_known_hat.list, &smack_known_list);
3567 list_add(&smack_known_star.list, &smack_known_list); 3536 list_add(&smack_known_star.list, &smack_known_list);
@@ -3596,8 +3565,16 @@ static __init int smack_init(void)
3596 cred = (struct cred *) current->cred; 3565 cred = (struct cred *) current->cred;
3597 cred->security = tsp; 3566 cred->security = tsp;
3598 3567
3599 /* initialize the smack_known_list */ 3568 /* initialize the smack_know_list */
3600 init_smack_known_list(); 3569 init_smack_know_list();
3570 /*
3571 * Initialize locks
3572 */
3573 spin_lock_init(&smack_known_huh.smk_cipsolock);
3574 spin_lock_init(&smack_known_hat.smk_cipsolock);
3575 spin_lock_init(&smack_known_star.smk_cipsolock);
3576 spin_lock_init(&smack_known_floor.smk_cipsolock);
3577 spin_lock_init(&smack_known_invalid.smk_cipsolock);
3601 3578
3602 /* 3579 /*
3603 * Register with LSM 3580 * Register with LSM
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 76a5dca4640..f93460156dc 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -22,6 +22,7 @@
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <net/net_namespace.h> 24#include <net/net_namespace.h>
25#include <net/netlabel.h>
25#include <net/cipso_ipv4.h> 26#include <net/cipso_ipv4.h>
26#include <linux/seq_file.h> 27#include <linux/seq_file.h>
27#include <linux/ctype.h> 28#include <linux/ctype.h>
@@ -43,13 +44,6 @@ enum smk_inos {
43 SMK_ONLYCAP = 9, /* the only "capable" label */ 44 SMK_ONLYCAP = 9, /* the only "capable" label */
44 SMK_LOGGING = 10, /* logging */ 45 SMK_LOGGING = 10, /* logging */
45 SMK_LOAD_SELF = 11, /* task specific rules */ 46 SMK_LOAD_SELF = 11, /* task specific rules */
46 SMK_ACCESSES = 12, /* access policy */
47 SMK_MAPPED = 13, /* CIPSO level indicating mapped label */
48 SMK_LOAD2 = 14, /* load policy with long labels */
49 SMK_LOAD_SELF2 = 15, /* load task specific rules with long labels */
50 SMK_ACCESS2 = 16, /* make an access check with long labels */
51 SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */
52 SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */
53}; 47};
54 48
55/* 49/*
@@ -65,7 +59,7 @@ static DEFINE_MUTEX(smk_netlbladdr_lock);
65 * If it isn't somehow marked, use this. 59 * If it isn't somehow marked, use this.
66 * It can be reset via smackfs/ambient 60 * It can be reset via smackfs/ambient
67 */ 61 */
68char *smack_net_ambient; 62char *smack_net_ambient = smack_known_floor.smk_known;
69 63
70/* 64/*
71 * This is the level in a CIPSO header that indicates a 65 * This is the level in a CIPSO header that indicates a
@@ -75,13 +69,6 @@ char *smack_net_ambient;
75int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT; 69int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;
76 70
77/* 71/*
78 * This is the level in a CIPSO header that indicates a
79 * secid is contained directly in the category set.
80 * It can be reset via smackfs/mapped
81 */
82int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
83
84/*
85 * Unless a process is running with this label even 72 * Unless a process is running with this label even
86 * having CAP_MAC_OVERRIDE isn't enough to grant 73 * having CAP_MAC_OVERRIDE isn't enough to grant
87 * privilege to violate MAC policy. If no label is 74 * privilege to violate MAC policy. If no label is
@@ -98,22 +85,15 @@ char *smack_onlycap;
98 */ 85 */
99 86
100LIST_HEAD(smk_netlbladdr_list); 87LIST_HEAD(smk_netlbladdr_list);
101
102/*
103 * Rule lists are maintained for each label.
104 * This master list is just for reading /smack/load and /smack/load2.
105 */
106struct smack_master_list {
107 struct list_head list;
108 struct smack_rule *smk_rule;
109};
110
111LIST_HEAD(smack_rule_list); 88LIST_HEAD(smack_rule_list);
112 89
113static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; 90static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
114 91
115const char *smack_cipso_option = SMACK_CIPSO_OPTION; 92const char *smack_cipso_option = SMACK_CIPSO_OPTION;
116 93
94
95#define SEQ_READ_FINISHED 1
96
117/* 97/*
118 * Values for parsing cipso rules 98 * Values for parsing cipso rules
119 * SMK_DIGITLEN: Length of a digit field in a rule. 99 * SMK_DIGITLEN: Length of a digit field in a rule.
@@ -137,18 +117,6 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION;
137#define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN) 117#define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN)
138#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) 118#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
139 119
140/*
141 * Stricly for CIPSO level manipulation.
142 * Set the category bit number in a smack label sized buffer.
143 */
144static inline void smack_catset_bit(unsigned int cat, char *catsetp)
145{
146 if (cat == 0 || cat > (SMK_CIPSOLEN * 8))
147 return;
148
149 catsetp[(cat - 1) / 8] |= 0x80 >> ((cat - 1) % 8);
150}
151
152/** 120/**
153 * smk_netlabel_audit_set - fill a netlbl_audit struct 121 * smk_netlabel_audit_set - fill a netlbl_audit struct
154 * @nap: structure to fill 122 * @nap: structure to fill
@@ -161,10 +129,12 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap)
161} 129}
162 130
163/* 131/*
164 * Value for parsing single label host rules 132 * Values for parsing single label host rules
165 * "1.2.3.4 X" 133 * "1.2.3.4 X"
134 * "192.168.138.129/32 abcdefghijklmnopqrstuvw"
166 */ 135 */
167#define SMK_NETLBLADDRMIN 9 136#define SMK_NETLBLADDRMIN 9
137#define SMK_NETLBLADDRMAX 42
168 138
169/** 139/**
170 * smk_set_access - add a rule to the rule list 140 * smk_set_access - add a rule to the rule list
@@ -189,13 +159,9 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list,
189 159
190 mutex_lock(rule_lock); 160 mutex_lock(rule_lock);
191 161
192 /*
193 * Because the object label is less likely to match
194 * than the subject label check it first
195 */
196 list_for_each_entry_rcu(sp, rule_list, list) { 162 list_for_each_entry_rcu(sp, rule_list, list) {
197 if (sp->smk_object == srp->smk_object && 163 if (sp->smk_subject == srp->smk_subject &&
198 sp->smk_subject == srp->smk_subject) { 164 sp->smk_object == srp->smk_object) {
199 found = 1; 165 found = 1;
200 sp->smk_access = srp->smk_access; 166 sp->smk_access = srp->smk_access;
201 break; 167 break;
@@ -210,175 +176,30 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list,
210} 176}
211 177
212/** 178/**
213 * smk_fill_rule - Fill Smack rule from strings 179 * smk_write_load_list - write() for any /smack/load
214 * @subject: subject label string
215 * @object: object label string
216 * @access: access string
217 * @rule: Smack rule
218 * @import: if non-zero, import labels
219 * @len: label length limit
220 *
221 * Returns 0 on success, -1 on failure
222 */
223static int smk_fill_rule(const char *subject, const char *object,
224 const char *access, struct smack_rule *rule,
225 int import, int len)
226{
227 const char *cp;
228 struct smack_known *skp;
229
230 if (import) {
231 rule->smk_subject = smk_import(subject, len);
232 if (rule->smk_subject == NULL)
233 return -1;
234
235 rule->smk_object = smk_import(object, len);
236 if (rule->smk_object == NULL)
237 return -1;
238 } else {
239 cp = smk_parse_smack(subject, len);
240 if (cp == NULL)
241 return -1;
242 skp = smk_find_entry(cp);
243 kfree(cp);
244 if (skp == NULL)
245 return -1;
246 rule->smk_subject = skp->smk_known;
247
248 cp = smk_parse_smack(object, len);
249 if (cp == NULL)
250 return -1;
251 skp = smk_find_entry(cp);
252 kfree(cp);
253 if (skp == NULL)
254 return -1;
255 rule->smk_object = skp->smk_known;
256 }
257
258 rule->smk_access = 0;
259
260 for (cp = access; *cp != '\0'; cp++) {
261 switch (*cp) {
262 case '-':
263 break;
264 case 'r':
265 case 'R':
266 rule->smk_access |= MAY_READ;
267 break;
268 case 'w':
269 case 'W':
270 rule->smk_access |= MAY_WRITE;
271 break;
272 case 'x':
273 case 'X':
274 rule->smk_access |= MAY_EXEC;
275 break;
276 case 'a':
277 case 'A':
278 rule->smk_access |= MAY_APPEND;
279 break;
280 case 't':
281 case 'T':
282 rule->smk_access |= MAY_TRANSMUTE;
283 break;
284 default:
285 return 0;
286 }
287 }
288
289 return 0;
290}
291
292/**
293 * smk_parse_rule - parse Smack rule from load string
294 * @data: string to be parsed whose size is SMK_LOADLEN
295 * @rule: Smack rule
296 * @import: if non-zero, import labels
297 *
298 * Returns 0 on success, -1 on errors.
299 */
300static int smk_parse_rule(const char *data, struct smack_rule *rule, int import)
301{
302 int rc;
303
304 rc = smk_fill_rule(data, data + SMK_LABELLEN,
305 data + SMK_LABELLEN + SMK_LABELLEN, rule, import,
306 SMK_LABELLEN);
307 return rc;
308}
309
310/**
311 * smk_parse_long_rule - parse Smack rule from rule string
312 * @data: string to be parsed, null terminated
313 * @rule: Smack rule
314 * @import: if non-zero, import labels
315 *
316 * Returns 0 on success, -1 on failure
317 */
318static int smk_parse_long_rule(const char *data, struct smack_rule *rule,
319 int import)
320{
321 char *subject;
322 char *object;
323 char *access;
324 int datalen;
325 int rc = -1;
326
327 /* This is inefficient */
328 datalen = strlen(data);
329
330 /* Our first element can be 64 + \0 with no spaces */
331 subject = kzalloc(datalen + 1, GFP_KERNEL);
332 if (subject == NULL)
333 return -1;
334 object = kzalloc(datalen, GFP_KERNEL);
335 if (object == NULL)
336 goto free_out_s;
337 access = kzalloc(datalen, GFP_KERNEL);
338 if (access == NULL)
339 goto free_out_o;
340
341 if (sscanf(data, "%s %s %s", subject, object, access) == 3)
342 rc = smk_fill_rule(subject, object, access, rule, import, 0);
343
344 kfree(access);
345free_out_o:
346 kfree(object);
347free_out_s:
348 kfree(subject);
349 return rc;
350}
351
352#define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */
353#define SMK_LONG_FMT 1 /* Variable long label format */
354/**
355 * smk_write_rules_list - write() for any /smack rule file
356 * @file: file pointer, not actually used 180 * @file: file pointer, not actually used
357 * @buf: where to get the data from 181 * @buf: where to get the data from
358 * @count: bytes sent 182 * @count: bytes sent
359 * @ppos: where to start - must be 0 183 * @ppos: where to start - must be 0
360 * @rule_list: the list of rules to write to 184 * @rule_list: the list of rules to write to
361 * @rule_lock: lock for the rule list 185 * @rule_lock: lock for the rule list
362 * @format: /smack/load or /smack/load2 format.
363 * 186 *
364 * Get one smack access rule from above. 187 * Get one smack access rule from above.
365 * The format for SMK_LONG_FMT is: 188 * The format is exactly:
366 * "subject<whitespace>object<whitespace>access[<whitespace>...]" 189 * char subject[SMK_LABELLEN]
367 * The format for SMK_FIXED24_FMT is exactly: 190 * char object[SMK_LABELLEN]
368 * "subject object rwxat" 191 * char access[SMK_ACCESSLEN]
192 *
193 * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes.
369 */ 194 */
370static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, 195static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
371 size_t count, loff_t *ppos, 196 size_t count, loff_t *ppos,
372 struct list_head *rule_list, 197 struct list_head *rule_list,
373 struct mutex *rule_lock, int format) 198 struct mutex *rule_lock)
374{ 199{
375 struct smack_master_list *smlp;
376 struct smack_known *skp;
377 struct smack_rule *rule; 200 struct smack_rule *rule;
378 char *data; 201 char *data;
379 int datalen;
380 int rc = -EINVAL; 202 int rc = -EINVAL;
381 int load = 0;
382 203
383 /* 204 /*
384 * No partial writes. 205 * No partial writes.
@@ -386,18 +207,13 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
386 */ 207 */
387 if (*ppos != 0) 208 if (*ppos != 0)
388 return -EINVAL; 209 return -EINVAL;
210 /*
211 * Minor hack for backward compatibility
212 */
213 if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN)
214 return -EINVAL;
389 215
390 if (format == SMK_FIXED24_FMT) { 216 data = kzalloc(SMK_LOADLEN, GFP_KERNEL);
391 /*
392 * Minor hack for backward compatibility
393 */
394 if (count != SMK_OLOADLEN && count != SMK_LOADLEN)
395 return -EINVAL;
396 datalen = SMK_LOADLEN;
397 } else
398 datalen = count + 1;
399
400 data = kzalloc(datalen, GFP_KERNEL);
401 if (data == NULL) 217 if (data == NULL)
402 return -ENOMEM; 218 return -ENOMEM;
403 219
@@ -406,55 +222,90 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
406 goto out; 222 goto out;
407 } 223 }
408 224
225 /*
226 * More on the minor hack for backward compatibility
227 */
228 if (count == (SMK_OLOADLEN))
229 data[SMK_OLOADLEN] = '-';
230
409 rule = kzalloc(sizeof(*rule), GFP_KERNEL); 231 rule = kzalloc(sizeof(*rule), GFP_KERNEL);
410 if (rule == NULL) { 232 if (rule == NULL) {
411 rc = -ENOMEM; 233 rc = -ENOMEM;
412 goto out; 234 goto out;
413 } 235 }
414 236
415 if (format == SMK_LONG_FMT) { 237 rule->smk_subject = smk_import(data, 0);
416 /* 238 if (rule->smk_subject == NULL)
417 * Be sure the data string is terminated. 239 goto out_free_rule;
418 */ 240
419 data[count] = '\0'; 241 rule->smk_object = smk_import(data + SMK_LABELLEN, 0);
420 if (smk_parse_long_rule(data, rule, 1)) 242 if (rule->smk_object == NULL)
421 goto out_free_rule; 243 goto out_free_rule;
422 } else { 244
423 /* 245 rule->smk_access = 0;
424 * More on the minor hack for backward compatibility 246
425 */ 247 switch (data[SMK_LABELLEN + SMK_LABELLEN]) {
426 if (count == (SMK_OLOADLEN)) 248 case '-':
427 data[SMK_OLOADLEN] = '-'; 249 break;
428 if (smk_parse_rule(data, rule, 1)) 250 case 'r':
429 goto out_free_rule; 251 case 'R':
252 rule->smk_access |= MAY_READ;
253 break;
254 default:
255 goto out_free_rule;
256 }
257
258 switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) {
259 case '-':
260 break;
261 case 'w':
262 case 'W':
263 rule->smk_access |= MAY_WRITE;
264 break;
265 default:
266 goto out_free_rule;
267 }
268
269 switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) {
270 case '-':
271 break;
272 case 'x':
273 case 'X':
274 rule->smk_access |= MAY_EXEC;
275 break;
276 default:
277 goto out_free_rule;
430 } 278 }
431 279
280 switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) {
281 case '-':
282 break;
283 case 'a':
284 case 'A':
285 rule->smk_access |= MAY_APPEND;
286 break;
287 default:
288 goto out_free_rule;
289 }
432 290
433 if (rule_list == NULL) { 291 switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) {
434 load = 1; 292 case '-':
435 skp = smk_find_entry(rule->smk_subject); 293 break;
436 rule_list = &skp->smk_rules; 294 case 't':
437 rule_lock = &skp->smk_rules_lock; 295 case 'T':
296 rule->smk_access |= MAY_TRANSMUTE;
297 break;
298 default:
299 goto out_free_rule;
438 } 300 }
439 301
440 rc = count; 302 rc = count;
441 /* 303 /*
442 * If this is a global as opposed to self and a new rule
443 * it needs to get added for reporting.
444 * smk_set_access returns true if there was already a rule 304 * smk_set_access returns true if there was already a rule
445 * for the subject/object pair, and false if it was new. 305 * for the subject/object pair, and false if it was new.
446 */ 306 */
447 if (!smk_set_access(rule, rule_list, rule_lock)) { 307 if (!smk_set_access(rule, rule_list, rule_lock))
448 if (load) {
449 smlp = kzalloc(sizeof(*smlp), GFP_KERNEL);
450 if (smlp != NULL) {
451 smlp->smk_rule = rule;
452 list_add_rcu(&smlp->list, &smack_rule_list);
453 } else
454 rc = -ENOMEM;
455 }
456 goto out; 308 goto out;
457 }
458 309
459out_free_rule: 310out_free_rule:
460 kfree(rule); 311 kfree(rule);
@@ -463,66 +314,39 @@ out:
463 return rc; 314 return rc;
464} 315}
465 316
317
466/* 318/*
467 * Core logic for smackfs seq list operations. 319 * Seq_file read operations for /smack/load
468 */ 320 */
469 321
470static void *smk_seq_start(struct seq_file *s, loff_t *pos, 322static void *load_seq_start(struct seq_file *s, loff_t *pos)
471 struct list_head *head)
472{ 323{
473 struct list_head *list; 324 if (*pos == SEQ_READ_FINISHED)
474
475 /*
476 * This is 0 the first time through.
477 */
478 if (s->index == 0)
479 s->private = head;
480
481 if (s->private == NULL)
482 return NULL; 325 return NULL;
483 326 if (list_empty(&smack_rule_list))
484 list = s->private;
485 if (list_empty(list))
486 return NULL; 327 return NULL;
487 328 return smack_rule_list.next;
488 if (s->index == 0)
489 return list->next;
490 return list;
491} 329}
492 330
493static void *smk_seq_next(struct seq_file *s, void *v, loff_t *pos, 331static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
494 struct list_head *head)
495{ 332{
496 struct list_head *list = v; 333 struct list_head *list = v;
497 334
498 if (list_is_last(list, head)) { 335 if (list_is_last(list, &smack_rule_list)) {
499 s->private = NULL; 336 *pos = SEQ_READ_FINISHED;
500 return NULL; 337 return NULL;
501 } 338 }
502 s->private = list->next;
503 return list->next; 339 return list->next;
504} 340}
505 341
506static void smk_seq_stop(struct seq_file *s, void *v) 342static int load_seq_show(struct seq_file *s, void *v)
507{
508 /* No-op */
509}
510
511static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
512{ 343{
513 /* 344 struct list_head *list = v;
514 * Don't show any rules with label names too long for 345 struct smack_rule *srp =
515 * interface file (/smack/load or /smack/load2) 346 list_entry(list, struct smack_rule, list);
516 * because you should expect to be able to write
517 * anything you read back.
518 */
519 if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max)
520 return;
521
522 if (srp->smk_access == 0)
523 return;
524 347
525 seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); 348 seq_printf(s, "%s %s", (char *)srp->smk_subject,
349 (char *)srp->smk_object);
526 350
527 seq_putc(s, ' '); 351 seq_putc(s, ' ');
528 352
@@ -536,40 +360,24 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
536 seq_putc(s, 'a'); 360 seq_putc(s, 'a');
537 if (srp->smk_access & MAY_TRANSMUTE) 361 if (srp->smk_access & MAY_TRANSMUTE)
538 seq_putc(s, 't'); 362 seq_putc(s, 't');
363 if (srp->smk_access == 0)
364 seq_putc(s, '-');
539 365
540 seq_putc(s, '\n'); 366 seq_putc(s, '\n');
541}
542 367
543/* 368 return 0;
544 * Seq_file read operations for /smack/load
545 */
546
547static void *load2_seq_start(struct seq_file *s, loff_t *pos)
548{
549 return smk_seq_start(s, pos, &smack_rule_list);
550}
551
552static void *load2_seq_next(struct seq_file *s, void *v, loff_t *pos)
553{
554 return smk_seq_next(s, v, pos, &smack_rule_list);
555} 369}
556 370
557static int load_seq_show(struct seq_file *s, void *v) 371static void load_seq_stop(struct seq_file *s, void *v)
558{ 372{
559 struct list_head *list = v; 373 /* No-op */
560 struct smack_master_list *smlp =
561 list_entry(list, struct smack_master_list, list);
562
563 smk_rule_show(s, smlp->smk_rule, SMK_LABELLEN);
564
565 return 0;
566} 374}
567 375
568static const struct seq_operations load_seq_ops = { 376static const struct seq_operations load_seq_ops = {
569 .start = load2_seq_start, 377 .start = load_seq_start,
570 .next = load2_seq_next, 378 .next = load_seq_next,
571 .show = load_seq_show, 379 .show = load_seq_show,
572 .stop = smk_seq_stop, 380 .stop = load_seq_stop,
573}; 381};
574 382
575/** 383/**
@@ -595,16 +403,17 @@ static int smk_open_load(struct inode *inode, struct file *file)
595static ssize_t smk_write_load(struct file *file, const char __user *buf, 403static ssize_t smk_write_load(struct file *file, const char __user *buf,
596 size_t count, loff_t *ppos) 404 size_t count, loff_t *ppos)
597{ 405{
406
598 /* 407 /*
599 * Must have privilege. 408 * Must have privilege.
600 * No partial writes. 409 * No partial writes.
601 * Enough data must be present. 410 * Enough data must be present.
602 */ 411 */
603 if (!smack_privileged(CAP_MAC_ADMIN)) 412 if (!capable(CAP_MAC_ADMIN))
604 return -EPERM; 413 return -EPERM;
605 414
606 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, 415 return smk_write_load_list(file, buf, count, ppos, &smack_rule_list,
607 SMK_FIXED24_FMT); 416 &smack_list_lock);
608} 417}
609 418
610static const struct file_operations smk_load_ops = { 419static const struct file_operations smk_load_ops = {
@@ -674,8 +483,6 @@ static void smk_unlbl_ambient(char *oldambient)
674 printk(KERN_WARNING "%s:%d remove rc = %d\n", 483 printk(KERN_WARNING "%s:%d remove rc = %d\n",
675 __func__, __LINE__, rc); 484 __func__, __LINE__, rc);
676 } 485 }
677 if (smack_net_ambient == NULL)
678 smack_net_ambient = smack_known_floor.smk_known;
679 486
680 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, 487 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET,
681 NULL, NULL, &nai); 488 NULL, NULL, &nai);
@@ -690,12 +497,28 @@ static void smk_unlbl_ambient(char *oldambient)
690 497
691static void *cipso_seq_start(struct seq_file *s, loff_t *pos) 498static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
692{ 499{
693 return smk_seq_start(s, pos, &smack_known_list); 500 if (*pos == SEQ_READ_FINISHED)
501 return NULL;
502 if (list_empty(&smack_known_list))
503 return NULL;
504
505 return smack_known_list.next;
694} 506}
695 507
696static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos) 508static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
697{ 509{
698 return smk_seq_next(s, v, pos, &smack_known_list); 510 struct list_head *list = v;
511
512 /*
513 * labels with no associated cipso value wont be printed
514 * in cipso_seq_show
515 */
516 if (list_is_last(list, &smack_known_list)) {
517 *pos = SEQ_READ_FINISHED;
518 return NULL;
519 }
520
521 return list->next;
699} 522}
700 523
701/* 524/*
@@ -707,39 +530,43 @@ static int cipso_seq_show(struct seq_file *s, void *v)
707 struct list_head *list = v; 530 struct list_head *list = v;
708 struct smack_known *skp = 531 struct smack_known *skp =
709 list_entry(list, struct smack_known, list); 532 list_entry(list, struct smack_known, list);
710 struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat; 533 struct smack_cipso *scp = skp->smk_cipso;
534 char *cbp;
711 char sep = '/'; 535 char sep = '/';
536 int cat = 1;
712 int i; 537 int i;
538 unsigned char m;
713 539
714 /* 540 if (scp == NULL)
715 * Don't show a label that could not have been set using
716 * /smack/cipso. This is in support of the notion that
717 * anything read from /smack/cipso ought to be writeable
718 * to /smack/cipso.
719 *
720 * /smack/cipso2 should be used instead.
721 */
722 if (strlen(skp->smk_known) >= SMK_LABELLEN)
723 return 0; 541 return 0;
724 542
725 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl); 543 seq_printf(s, "%s %3d", (char *)&skp->smk_known, scp->smk_level);
726 544
727 for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0; 545 cbp = scp->smk_catset;
728 i = netlbl_secattr_catmap_walk(cmp, i + 1)) { 546 for (i = 0; i < SMK_LABELLEN; i++)
729 seq_printf(s, "%c%d", sep, i); 547 for (m = 0x80; m != 0; m >>= 1) {
730 sep = ','; 548 if (m & cbp[i]) {
731 } 549 seq_printf(s, "%c%d", sep, cat);
550 sep = ',';
551 }
552 cat++;
553 }
732 554
733 seq_putc(s, '\n'); 555 seq_putc(s, '\n');
734 556
735 return 0; 557 return 0;
736} 558}
737 559
560static void cipso_seq_stop(struct seq_file *s, void *v)
561{
562 /* No-op */
563}
564
738static const struct seq_operations cipso_seq_ops = { 565static const struct seq_operations cipso_seq_ops = {
739 .start = cipso_seq_start, 566 .start = cipso_seq_start,
567 .stop = cipso_seq_stop,
740 .next = cipso_seq_next, 568 .next = cipso_seq_next,
741 .show = cipso_seq_show, 569 .show = cipso_seq_show,
742 .stop = smk_seq_stop,
743}; 570};
744 571
745/** 572/**
@@ -756,24 +583,23 @@ static int smk_open_cipso(struct inode *inode, struct file *file)
756} 583}
757 584
758/** 585/**
759 * smk_set_cipso - do the work for write() for cipso and cipso2 586 * smk_write_cipso - write() for /smack/cipso
760 * @file: file pointer, not actually used 587 * @file: file pointer, not actually used
761 * @buf: where to get the data from 588 * @buf: where to get the data from
762 * @count: bytes sent 589 * @count: bytes sent
763 * @ppos: where to start 590 * @ppos: where to start
764 * @format: /smack/cipso or /smack/cipso2
765 * 591 *
766 * Accepts only one cipso rule per write call. 592 * Accepts only one cipso rule per write call.
767 * Returns number of bytes written or error code, as appropriate 593 * Returns number of bytes written or error code, as appropriate
768 */ 594 */
769static ssize_t smk_set_cipso(struct file *file, const char __user *buf, 595static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
770 size_t count, loff_t *ppos, int format) 596 size_t count, loff_t *ppos)
771{ 597{
772 struct smack_known *skp; 598 struct smack_known *skp;
773 struct netlbl_lsm_secattr ncats; 599 struct smack_cipso *scp = NULL;
774 char mapcatset[SMK_CIPSOLEN]; 600 char mapcatset[SMK_LABELLEN];
775 int maplevel; 601 int maplevel;
776 unsigned int cat; 602 int cat;
777 int catlen; 603 int catlen;
778 ssize_t rc = -EINVAL; 604 ssize_t rc = -EINVAL;
779 char *data = NULL; 605 char *data = NULL;
@@ -786,12 +612,11 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
786 * No partial writes. 612 * No partial writes.
787 * Enough data must be present. 613 * Enough data must be present.
788 */ 614 */
789 if (!smack_privileged(CAP_MAC_ADMIN)) 615 if (!capable(CAP_MAC_ADMIN))
790 return -EPERM; 616 return -EPERM;
791 if (*ppos != 0) 617 if (*ppos != 0)
792 return -EINVAL; 618 return -EINVAL;
793 if (format == SMK_FIXED24_FMT && 619 if (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX)
794 (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX))
795 return -EINVAL; 620 return -EINVAL;
796 621
797 data = kzalloc(count + 1, GFP_KERNEL); 622 data = kzalloc(count + 1, GFP_KERNEL);
@@ -803,6 +628,11 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
803 goto unlockedout; 628 goto unlockedout;
804 } 629 }
805 630
631 /* labels cannot begin with a '-' */
632 if (data[0] == '-') {
633 rc = -EINVAL;
634 goto unlockedout;
635 }
806 data[count] = '\0'; 636 data[count] = '\0';
807 rule = data; 637 rule = data;
808 /* 638 /*
@@ -815,11 +645,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
815 if (skp == NULL) 645 if (skp == NULL)
816 goto out; 646 goto out;
817 647
818 if (format == SMK_FIXED24_FMT) 648 rule += SMK_LABELLEN;
819 rule += SMK_LABELLEN;
820 else
821 rule += strlen(skp->smk_known);
822
823 ret = sscanf(rule, "%d", &maplevel); 649 ret = sscanf(rule, "%d", &maplevel);
824 if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) 650 if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL)
825 goto out; 651 goto out;
@@ -829,29 +655,41 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
829 if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) 655 if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
830 goto out; 656 goto out;
831 657
832 if (format == SMK_FIXED24_FMT && 658 if (count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
833 count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
834 goto out; 659 goto out;
835 660
836 memset(mapcatset, 0, sizeof(mapcatset)); 661 memset(mapcatset, 0, sizeof(mapcatset));
837 662
838 for (i = 0; i < catlen; i++) { 663 for (i = 0; i < catlen; i++) {
839 rule += SMK_DIGITLEN; 664 rule += SMK_DIGITLEN;
840 ret = sscanf(rule, "%u", &cat); 665 ret = sscanf(rule, "%d", &cat);
841 if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL) 666 if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL)
842 goto out; 667 goto out;
843 668
844 smack_catset_bit(cat, mapcatset); 669 smack_catset_bit(cat, mapcatset);
845 } 670 }
846 671
847 rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN); 672 if (skp->smk_cipso == NULL) {
848 if (rc >= 0) { 673 scp = kzalloc(sizeof(struct smack_cipso), GFP_KERNEL);
849 netlbl_secattr_catmap_free(skp->smk_netlabel.attr.mls.cat); 674 if (scp == NULL) {
850 skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat; 675 rc = -ENOMEM;
851 skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl; 676 goto out;
852 rc = count; 677 }
853 } 678 }
854 679
680 spin_lock_bh(&skp->smk_cipsolock);
681
682 if (scp == NULL)
683 scp = skp->smk_cipso;
684 else
685 skp->smk_cipso = scp;
686
687 scp->smk_level = maplevel;
688 memcpy(scp->smk_catset, mapcatset, sizeof(mapcatset));
689
690 spin_unlock_bh(&skp->smk_cipsolock);
691
692 rc = count;
855out: 693out:
856 mutex_unlock(&smack_cipso_lock); 694 mutex_unlock(&smack_cipso_lock);
857unlockedout: 695unlockedout:
@@ -859,22 +697,6 @@ unlockedout:
859 return rc; 697 return rc;
860} 698}
861 699
862/**
863 * smk_write_cipso - write() for /smack/cipso
864 * @file: file pointer, not actually used
865 * @buf: where to get the data from
866 * @count: bytes sent
867 * @ppos: where to start
868 *
869 * Accepts only one cipso rule per write call.
870 * Returns number of bytes written or error code, as appropriate
871 */
872static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
873 size_t count, loff_t *ppos)
874{
875 return smk_set_cipso(file, buf, count, ppos, SMK_FIXED24_FMT);
876}
877
878static const struct file_operations smk_cipso_ops = { 700static const struct file_operations smk_cipso_ops = {
879 .open = smk_open_cipso, 701 .open = smk_open_cipso,
880 .read = seq_read, 702 .read = seq_read,
@@ -884,91 +706,28 @@ static const struct file_operations smk_cipso_ops = {
884}; 706};
885 707
886/* 708/*
887 * Seq_file read operations for /smack/cipso2
888 */
889
890/*
891 * Print cipso labels in format:
892 * label level[/cat[,cat]]
893 */
894static int cipso2_seq_show(struct seq_file *s, void *v)
895{
896 struct list_head *list = v;
897 struct smack_known *skp =
898 list_entry(list, struct smack_known, list);
899 struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
900 char sep = '/';
901 int i;
902
903 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
904
905 for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0;
906 i = netlbl_secattr_catmap_walk(cmp, i + 1)) {
907 seq_printf(s, "%c%d", sep, i);
908 sep = ',';
909 }
910
911 seq_putc(s, '\n');
912
913 return 0;
914}
915
916static const struct seq_operations cipso2_seq_ops = {
917 .start = cipso_seq_start,
918 .next = cipso_seq_next,
919 .show = cipso2_seq_show,
920 .stop = smk_seq_stop,
921};
922
923/**
924 * smk_open_cipso2 - open() for /smack/cipso2
925 * @inode: inode structure representing file
926 * @file: "cipso2" file pointer
927 *
928 * Connect our cipso_seq_* operations with /smack/cipso2
929 * file_operations
930 */
931static int smk_open_cipso2(struct inode *inode, struct file *file)
932{
933 return seq_open(file, &cipso2_seq_ops);
934}
935
936/**
937 * smk_write_cipso2 - write() for /smack/cipso2
938 * @file: file pointer, not actually used
939 * @buf: where to get the data from
940 * @count: bytes sent
941 * @ppos: where to start
942 *
943 * Accepts only one cipso rule per write call.
944 * Returns number of bytes written or error code, as appropriate
945 */
946static ssize_t smk_write_cipso2(struct file *file, const char __user *buf,
947 size_t count, loff_t *ppos)
948{
949 return smk_set_cipso(file, buf, count, ppos, SMK_LONG_FMT);
950}
951
952static const struct file_operations smk_cipso2_ops = {
953 .open = smk_open_cipso2,
954 .read = seq_read,
955 .llseek = seq_lseek,
956 .write = smk_write_cipso2,
957 .release = seq_release,
958};
959
960/*
961 * Seq_file read operations for /smack/netlabel 709 * Seq_file read operations for /smack/netlabel
962 */ 710 */
963 711
964static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos) 712static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos)
965{ 713{
966 return smk_seq_start(s, pos, &smk_netlbladdr_list); 714 if (*pos == SEQ_READ_FINISHED)
715 return NULL;
716 if (list_empty(&smk_netlbladdr_list))
717 return NULL;
718 return smk_netlbladdr_list.next;
967} 719}
968 720
969static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos) 721static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
970{ 722{
971 return smk_seq_next(s, v, pos, &smk_netlbladdr_list); 723 struct list_head *list = v;
724
725 if (list_is_last(list, &smk_netlbladdr_list)) {
726 *pos = SEQ_READ_FINISHED;
727 return NULL;
728 }
729
730 return list->next;
972} 731}
973#define BEBITS (sizeof(__be32) * 8) 732#define BEBITS (sizeof(__be32) * 8)
974 733
@@ -992,11 +751,16 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v)
992 return 0; 751 return 0;
993} 752}
994 753
754static void netlbladdr_seq_stop(struct seq_file *s, void *v)
755{
756 /* No-op */
757}
758
995static const struct seq_operations netlbladdr_seq_ops = { 759static const struct seq_operations netlbladdr_seq_ops = {
996 .start = netlbladdr_seq_start, 760 .start = netlbladdr_seq_start,
761 .stop = netlbladdr_seq_stop,
997 .next = netlbladdr_seq_next, 762 .next = netlbladdr_seq_next,
998 .show = netlbladdr_seq_show, 763 .show = netlbladdr_seq_show,
999 .stop = smk_seq_stop,
1000}; 764};
1001 765
1002/** 766/**
@@ -1069,9 +833,9 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1069{ 833{
1070 struct smk_netlbladdr *skp; 834 struct smk_netlbladdr *skp;
1071 struct sockaddr_in newname; 835 struct sockaddr_in newname;
1072 char *smack; 836 char smack[SMK_LABELLEN];
1073 char *sp; 837 char *sp;
1074 char *data; 838 char data[SMK_NETLBLADDRMAX + 1];
1075 char *host = (char *)&newname.sin_addr.s_addr; 839 char *host = (char *)&newname.sin_addr.s_addr;
1076 int rc; 840 int rc;
1077 struct netlbl_audit audit_info; 841 struct netlbl_audit audit_info;
@@ -1089,27 +853,14 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1089 * "<addr/mask, as a.b.c.d/e><space><label>" 853 * "<addr/mask, as a.b.c.d/e><space><label>"
1090 * "<addr, as a.b.c.d><space><label>" 854 * "<addr, as a.b.c.d><space><label>"
1091 */ 855 */
1092 if (!smack_privileged(CAP_MAC_ADMIN)) 856 if (!capable(CAP_MAC_ADMIN))
1093 return -EPERM; 857 return -EPERM;
1094 if (*ppos != 0) 858 if (*ppos != 0)
1095 return -EINVAL; 859 return -EINVAL;
1096 if (count < SMK_NETLBLADDRMIN) 860 if (count < SMK_NETLBLADDRMIN || count > SMK_NETLBLADDRMAX)
1097 return -EINVAL; 861 return -EINVAL;
1098 862 if (copy_from_user(data, buf, count) != 0)
1099 data = kzalloc(count + 1, GFP_KERNEL); 863 return -EFAULT;
1100 if (data == NULL)
1101 return -ENOMEM;
1102
1103 if (copy_from_user(data, buf, count) != 0) {
1104 rc = -EFAULT;
1105 goto free_data_out;
1106 }
1107
1108 smack = kzalloc(count + 1, GFP_KERNEL);
1109 if (smack == NULL) {
1110 rc = -ENOMEM;
1111 goto free_data_out;
1112 }
1113 864
1114 data[count] = '\0'; 865 data[count] = '\0';
1115 866
@@ -1118,34 +869,24 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1118 if (rc != 6) { 869 if (rc != 6) {
1119 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", 870 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s",
1120 &host[0], &host[1], &host[2], &host[3], smack); 871 &host[0], &host[1], &host[2], &host[3], smack);
1121 if (rc != 5) { 872 if (rc != 5)
1122 rc = -EINVAL; 873 return -EINVAL;
1123 goto free_out;
1124 }
1125 m = BEBITS; 874 m = BEBITS;
1126 } 875 }
1127 if (m > BEBITS) { 876 if (m > BEBITS)
1128 rc = -EINVAL; 877 return -EINVAL;
1129 goto free_out;
1130 }
1131 878
1132 /* 879 /* if smack begins with '-', its an option, don't import it */
1133 * If smack begins with '-', it is an option, don't import it
1134 */
1135 if (smack[0] != '-') { 880 if (smack[0] != '-') {
1136 sp = smk_import(smack, 0); 881 sp = smk_import(smack, 0);
1137 if (sp == NULL) { 882 if (sp == NULL)
1138 rc = -EINVAL; 883 return -EINVAL;
1139 goto free_out;
1140 }
1141 } else { 884 } else {
1142 /* check known options */ 885 /* check known options */
1143 if (strcmp(smack, smack_cipso_option) == 0) 886 if (strcmp(smack, smack_cipso_option) == 0)
1144 sp = (char *)smack_cipso_option; 887 sp = (char *)smack_cipso_option;
1145 else { 888 else
1146 rc = -EINVAL; 889 return -EINVAL;
1147 goto free_out;
1148 }
1149 } 890 }
1150 891
1151 for (temp_mask = 0; m > 0; m--) { 892 for (temp_mask = 0; m > 0; m--) {
@@ -1211,11 +952,6 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1211 952
1212 mutex_unlock(&smk_netlbladdr_lock); 953 mutex_unlock(&smk_netlbladdr_lock);
1213 954
1214free_out:
1215 kfree(smack);
1216free_data_out:
1217 kfree(data);
1218
1219 return rc; 955 return rc;
1220} 956}
1221 957
@@ -1266,7 +1002,7 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf,
1266 char temp[80]; 1002 char temp[80];
1267 int i; 1003 int i;
1268 1004
1269 if (!smack_privileged(CAP_MAC_ADMIN)) 1005 if (!capable(CAP_MAC_ADMIN))
1270 return -EPERM; 1006 return -EPERM;
1271 1007
1272 if (count >= sizeof(temp) || count == 0) 1008 if (count >= sizeof(temp) || count == 0)
@@ -1329,11 +1065,10 @@ static ssize_t smk_read_direct(struct file *filp, char __user *buf,
1329static ssize_t smk_write_direct(struct file *file, const char __user *buf, 1065static ssize_t smk_write_direct(struct file *file, const char __user *buf,
1330 size_t count, loff_t *ppos) 1066 size_t count, loff_t *ppos)
1331{ 1067{
1332 struct smack_known *skp;
1333 char temp[80]; 1068 char temp[80];
1334 int i; 1069 int i;
1335 1070
1336 if (!smack_privileged(CAP_MAC_ADMIN)) 1071 if (!capable(CAP_MAC_ADMIN))
1337 return -EPERM; 1072 return -EPERM;
1338 1073
1339 if (count >= sizeof(temp) || count == 0) 1074 if (count >= sizeof(temp) || count == 0)
@@ -1347,20 +1082,7 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf,
1347 if (sscanf(temp, "%d", &i) != 1) 1082 if (sscanf(temp, "%d", &i) != 1)
1348 return -EINVAL; 1083 return -EINVAL;
1349 1084
1350 /* 1085 smack_cipso_direct = i;
1351 * Don't do anything if the value hasn't actually changed.
1352 * If it is changing reset the level on entries that were
1353 * set up to be direct when they were created.
1354 */
1355 if (smack_cipso_direct != i) {
1356 mutex_lock(&smack_known_lock);
1357 list_for_each_entry_rcu(skp, &smack_known_list, list)
1358 if (skp->smk_netlabel.attr.mls.lvl ==
1359 smack_cipso_direct)
1360 skp->smk_netlabel.attr.mls.lvl = i;
1361 smack_cipso_direct = i;
1362 mutex_unlock(&smack_known_lock);
1363 }
1364 1086
1365 return count; 1087 return count;
1366} 1088}
@@ -1372,84 +1094,6 @@ static const struct file_operations smk_direct_ops = {
1372}; 1094};
1373 1095
1374/** 1096/**
1375 * smk_read_mapped - read() for /smack/mapped
1376 * @filp: file pointer, not actually used
1377 * @buf: where to put the result
1378 * @count: maximum to send along
1379 * @ppos: where to start
1380 *
1381 * Returns number of bytes read or error code, as appropriate
1382 */
1383static ssize_t smk_read_mapped(struct file *filp, char __user *buf,
1384 size_t count, loff_t *ppos)
1385{
1386 char temp[80];
1387 ssize_t rc;
1388
1389 if (*ppos != 0)
1390 return 0;
1391
1392 sprintf(temp, "%d", smack_cipso_mapped);
1393 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1394
1395 return rc;
1396}
1397
1398/**
1399 * smk_write_mapped - write() for /smack/mapped
1400 * @file: file pointer, not actually used
1401 * @buf: where to get the data from
1402 * @count: bytes sent
1403 * @ppos: where to start
1404 *
1405 * Returns number of bytes written or error code, as appropriate
1406 */
1407static ssize_t smk_write_mapped(struct file *file, const char __user *buf,
1408 size_t count, loff_t *ppos)
1409{
1410 struct smack_known *skp;
1411 char temp[80];
1412 int i;
1413
1414 if (!smack_privileged(CAP_MAC_ADMIN))
1415 return -EPERM;
1416
1417 if (count >= sizeof(temp) || count == 0)
1418 return -EINVAL;
1419
1420 if (copy_from_user(temp, buf, count) != 0)
1421 return -EFAULT;
1422
1423 temp[count] = '\0';
1424
1425 if (sscanf(temp, "%d", &i) != 1)
1426 return -EINVAL;
1427
1428 /*
1429 * Don't do anything if the value hasn't actually changed.
1430 * If it is changing reset the level on entries that were
1431 * set up to be mapped when they were created.
1432 */
1433 if (smack_cipso_mapped != i) {
1434 mutex_lock(&smack_known_lock);
1435 list_for_each_entry_rcu(skp, &smack_known_list, list)
1436 if (skp->smk_netlabel.attr.mls.lvl ==
1437 smack_cipso_mapped)
1438 skp->smk_netlabel.attr.mls.lvl = i;
1439 smack_cipso_mapped = i;
1440 mutex_unlock(&smack_known_lock);
1441 }
1442
1443 return count;
1444}
1445
1446static const struct file_operations smk_mapped_ops = {
1447 .read = smk_read_mapped,
1448 .write = smk_write_mapped,
1449 .llseek = default_llseek,
1450};
1451
1452/**
1453 * smk_read_ambient - read() for /smack/ambient 1097 * smk_read_ambient - read() for /smack/ambient
1454 * @filp: file pointer, not actually used 1098 * @filp: file pointer, not actually used
1455 * @buf: where to put the result 1099 * @buf: where to put the result
@@ -1497,28 +1141,22 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1497static ssize_t smk_write_ambient(struct file *file, const char __user *buf, 1141static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1498 size_t count, loff_t *ppos) 1142 size_t count, loff_t *ppos)
1499{ 1143{
1144 char in[SMK_LABELLEN];
1500 char *oldambient; 1145 char *oldambient;
1501 char *smack = NULL; 1146 char *smack;
1502 char *data;
1503 int rc = count;
1504 1147
1505 if (!smack_privileged(CAP_MAC_ADMIN)) 1148 if (!capable(CAP_MAC_ADMIN))
1506 return -EPERM; 1149 return -EPERM;
1507 1150
1508 data = kzalloc(count + 1, GFP_KERNEL); 1151 if (count >= SMK_LABELLEN)
1509 if (data == NULL) 1152 return -EINVAL;
1510 return -ENOMEM;
1511 1153
1512 if (copy_from_user(data, buf, count) != 0) { 1154 if (copy_from_user(in, buf, count) != 0)
1513 rc = -EFAULT; 1155 return -EFAULT;
1514 goto out;
1515 }
1516 1156
1517 smack = smk_import(data, count); 1157 smack = smk_import(in, count);
1518 if (smack == NULL) { 1158 if (smack == NULL)
1519 rc = -EINVAL; 1159 return -EINVAL;
1520 goto out;
1521 }
1522 1160
1523 mutex_lock(&smack_ambient_lock); 1161 mutex_lock(&smack_ambient_lock);
1524 1162
@@ -1528,9 +1166,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1528 1166
1529 mutex_unlock(&smack_ambient_lock); 1167 mutex_unlock(&smack_ambient_lock);
1530 1168
1531out: 1169 return count;
1532 kfree(data);
1533 return rc;
1534} 1170}
1535 1171
1536static const struct file_operations smk_ambient_ops = { 1172static const struct file_operations smk_ambient_ops = {
@@ -1581,11 +1217,10 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
1581static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, 1217static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1582 size_t count, loff_t *ppos) 1218 size_t count, loff_t *ppos)
1583{ 1219{
1584 char *data; 1220 char in[SMK_LABELLEN];
1585 char *sp = smk_of_task(current->cred->security); 1221 char *sp = smk_of_task(current->cred->security);
1586 int rc = count;
1587 1222
1588 if (!smack_privileged(CAP_MAC_ADMIN)) 1223 if (!capable(CAP_MAC_ADMIN))
1589 return -EPERM; 1224 return -EPERM;
1590 1225
1591 /* 1226 /*
@@ -1596,9 +1231,11 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1596 if (smack_onlycap != NULL && smack_onlycap != sp) 1231 if (smack_onlycap != NULL && smack_onlycap != sp)
1597 return -EPERM; 1232 return -EPERM;
1598 1233
1599 data = kzalloc(count, GFP_KERNEL); 1234 if (count >= SMK_LABELLEN)
1600 if (data == NULL) 1235 return -EINVAL;
1601 return -ENOMEM; 1236
1237 if (copy_from_user(in, buf, count) != 0)
1238 return -EFAULT;
1602 1239
1603 /* 1240 /*
1604 * Should the null string be passed in unset the onlycap value. 1241 * Should the null string be passed in unset the onlycap value.
@@ -1606,17 +1243,10 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1606 * smk_import only expects to return NULL for errors. It 1243 * smk_import only expects to return NULL for errors. It
1607 * is usually the case that a nullstring or "\n" would be 1244 * is usually the case that a nullstring or "\n" would be
1608 * bad to pass to smk_import but in fact this is useful here. 1245 * bad to pass to smk_import but in fact this is useful here.
1609 *
1610 * smk_import will also reject a label beginning with '-',
1611 * so "-usecapabilities" will also work.
1612 */ 1246 */
1613 if (copy_from_user(data, buf, count) != 0) 1247 smack_onlycap = smk_import(in, count);
1614 rc = -EFAULT;
1615 else
1616 smack_onlycap = smk_import(data, count);
1617 1248
1618 kfree(data); 1249 return count;
1619 return rc;
1620} 1250}
1621 1251
1622static const struct file_operations smk_onlycap_ops = { 1252static const struct file_operations smk_onlycap_ops = {
@@ -1663,7 +1293,7 @@ static ssize_t smk_write_logging(struct file *file, const char __user *buf,
1663 char temp[32]; 1293 char temp[32];
1664 int i; 1294 int i;
1665 1295
1666 if (!smack_privileged(CAP_MAC_ADMIN)) 1296 if (!capable(CAP_MAC_ADMIN))
1667 return -EPERM; 1297 return -EPERM;
1668 1298
1669 if (count >= sizeof(temp) || count == 0) 1299 if (count >= sizeof(temp) || count == 0)
@@ -1698,14 +1328,23 @@ static void *load_self_seq_start(struct seq_file *s, loff_t *pos)
1698{ 1328{
1699 struct task_smack *tsp = current_security(); 1329 struct task_smack *tsp = current_security();
1700 1330
1701 return smk_seq_start(s, pos, &tsp->smk_rules); 1331 if (*pos == SEQ_READ_FINISHED)
1332 return NULL;
1333 if (list_empty(&tsp->smk_rules))
1334 return NULL;
1335 return tsp->smk_rules.next;
1702} 1336}
1703 1337
1704static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos) 1338static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos)
1705{ 1339{
1706 struct task_smack *tsp = current_security(); 1340 struct task_smack *tsp = current_security();
1341 struct list_head *list = v;
1707 1342
1708 return smk_seq_next(s, v, pos, &tsp->smk_rules); 1343 if (list_is_last(list, &tsp->smk_rules)) {
1344 *pos = SEQ_READ_FINISHED;
1345 return NULL;
1346 }
1347 return list->next;
1709} 1348}
1710 1349
1711static int load_self_seq_show(struct seq_file *s, void *v) 1350static int load_self_seq_show(struct seq_file *s, void *v)
@@ -1714,21 +1353,44 @@ static int load_self_seq_show(struct seq_file *s, void *v)
1714 struct smack_rule *srp = 1353 struct smack_rule *srp =
1715 list_entry(list, struct smack_rule, list); 1354 list_entry(list, struct smack_rule, list);
1716 1355
1717 smk_rule_show(s, srp, SMK_LABELLEN); 1356 seq_printf(s, "%s %s", (char *)srp->smk_subject,
1357 (char *)srp->smk_object);
1358
1359 seq_putc(s, ' ');
1360
1361 if (srp->smk_access & MAY_READ)
1362 seq_putc(s, 'r');
1363 if (srp->smk_access & MAY_WRITE)
1364 seq_putc(s, 'w');
1365 if (srp->smk_access & MAY_EXEC)
1366 seq_putc(s, 'x');
1367 if (srp->smk_access & MAY_APPEND)
1368 seq_putc(s, 'a');
1369 if (srp->smk_access & MAY_TRANSMUTE)
1370 seq_putc(s, 't');
1371 if (srp->smk_access == 0)
1372 seq_putc(s, '-');
1373
1374 seq_putc(s, '\n');
1718 1375
1719 return 0; 1376 return 0;
1720} 1377}
1721 1378
1379static void load_self_seq_stop(struct seq_file *s, void *v)
1380{
1381 /* No-op */
1382}
1383
1722static const struct seq_operations load_self_seq_ops = { 1384static const struct seq_operations load_self_seq_ops = {
1723 .start = load_self_seq_start, 1385 .start = load_self_seq_start,
1724 .next = load_self_seq_next, 1386 .next = load_self_seq_next,
1725 .show = load_self_seq_show, 1387 .show = load_self_seq_show,
1726 .stop = smk_seq_stop, 1388 .stop = load_self_seq_stop,
1727}; 1389};
1728 1390
1729 1391
1730/** 1392/**
1731 * smk_open_load_self - open() for /smack/load-self2 1393 * smk_open_load_self - open() for /smack/load-self
1732 * @inode: inode structure representing file 1394 * @inode: inode structure representing file
1733 * @file: "load" file pointer 1395 * @file: "load" file pointer
1734 * 1396 *
@@ -1752,8 +1414,8 @@ static ssize_t smk_write_load_self(struct file *file, const char __user *buf,
1752{ 1414{
1753 struct task_smack *tsp = current_security(); 1415 struct task_smack *tsp = current_security();
1754 1416
1755 return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules, 1417 return smk_write_load_list(file, buf, count, ppos, &tsp->smk_rules,
1756 &tsp->smk_rules_lock, SMK_FIXED24_FMT); 1418 &tsp->smk_rules_lock);
1757} 1419}
1758 1420
1759static const struct file_operations smk_load_self_ops = { 1421static const struct file_operations smk_load_self_ops = {
@@ -1763,319 +1425,6 @@ static const struct file_operations smk_load_self_ops = {
1763 .write = smk_write_load_self, 1425 .write = smk_write_load_self,
1764 .release = seq_release, 1426 .release = seq_release,
1765}; 1427};
1766
1767/**
1768 * smk_user_access - handle access check transaction
1769 * @file: file pointer
1770 * @buf: data from user space
1771 * @count: bytes sent
1772 * @ppos: where to start - must be 0
1773 */
1774static ssize_t smk_user_access(struct file *file, const char __user *buf,
1775 size_t count, loff_t *ppos, int format)
1776{
1777 struct smack_rule rule;
1778 char *data;
1779 char *cod;
1780 int res;
1781
1782 data = simple_transaction_get(file, buf, count);
1783 if (IS_ERR(data))
1784 return PTR_ERR(data);
1785
1786 if (format == SMK_FIXED24_FMT) {
1787 if (count < SMK_LOADLEN)
1788 return -EINVAL;
1789 res = smk_parse_rule(data, &rule, 0);
1790 } else {
1791 /*
1792 * Copy the data to make sure the string is terminated.
1793 */
1794 cod = kzalloc(count + 1, GFP_KERNEL);
1795 if (cod == NULL)
1796 return -ENOMEM;
1797 memcpy(cod, data, count);
1798 cod[count] = '\0';
1799 res = smk_parse_long_rule(cod, &rule, 0);
1800 kfree(cod);
1801 }
1802
1803 if (res)
1804 return -EINVAL;
1805
1806 res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access,
1807 NULL);
1808 data[0] = res == 0 ? '1' : '0';
1809 data[1] = '\0';
1810
1811 simple_transaction_set(file, 2);
1812
1813 if (format == SMK_FIXED24_FMT)
1814 return SMK_LOADLEN;
1815 return count;
1816}
1817
1818/**
1819 * smk_write_access - handle access check transaction
1820 * @file: file pointer
1821 * @buf: data from user space
1822 * @count: bytes sent
1823 * @ppos: where to start - must be 0
1824 */
1825static ssize_t smk_write_access(struct file *file, const char __user *buf,
1826 size_t count, loff_t *ppos)
1827{
1828 return smk_user_access(file, buf, count, ppos, SMK_FIXED24_FMT);
1829}
1830
1831static const struct file_operations smk_access_ops = {
1832 .write = smk_write_access,
1833 .read = simple_transaction_read,
1834 .release = simple_transaction_release,
1835 .llseek = generic_file_llseek,
1836};
1837
1838
1839/*
1840 * Seq_file read operations for /smack/load2
1841 */
1842
1843static int load2_seq_show(struct seq_file *s, void *v)
1844{
1845 struct list_head *list = v;
1846 struct smack_master_list *smlp =
1847 list_entry(list, struct smack_master_list, list);
1848
1849 smk_rule_show(s, smlp->smk_rule, SMK_LONGLABEL);
1850
1851 return 0;
1852}
1853
1854static const struct seq_operations load2_seq_ops = {
1855 .start = load2_seq_start,
1856 .next = load2_seq_next,
1857 .show = load2_seq_show,
1858 .stop = smk_seq_stop,
1859};
1860
1861/**
1862 * smk_open_load2 - open() for /smack/load2
1863 * @inode: inode structure representing file
1864 * @file: "load2" file pointer
1865 *
1866 * For reading, use load2_seq_* seq_file reading operations.
1867 */
1868static int smk_open_load2(struct inode *inode, struct file *file)
1869{
1870 return seq_open(file, &load2_seq_ops);
1871}
1872
1873/**
1874 * smk_write_load2 - write() for /smack/load2
1875 * @file: file pointer, not actually used
1876 * @buf: where to get the data from
1877 * @count: bytes sent
1878 * @ppos: where to start - must be 0
1879 *
1880 */
1881static ssize_t smk_write_load2(struct file *file, const char __user *buf,
1882 size_t count, loff_t *ppos)
1883{
1884 /*
1885 * Must have privilege.
1886 */
1887 if (!smack_privileged(CAP_MAC_ADMIN))
1888 return -EPERM;
1889
1890 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
1891 SMK_LONG_FMT);
1892}
1893
1894static const struct file_operations smk_load2_ops = {
1895 .open = smk_open_load2,
1896 .read = seq_read,
1897 .llseek = seq_lseek,
1898 .write = smk_write_load2,
1899 .release = seq_release,
1900};
1901
1902/*
1903 * Seq_file read operations for /smack/load-self2
1904 */
1905
1906static void *load_self2_seq_start(struct seq_file *s, loff_t *pos)
1907{
1908 struct task_smack *tsp = current_security();
1909
1910 return smk_seq_start(s, pos, &tsp->smk_rules);
1911}
1912
1913static void *load_self2_seq_next(struct seq_file *s, void *v, loff_t *pos)
1914{
1915 struct task_smack *tsp = current_security();
1916
1917 return smk_seq_next(s, v, pos, &tsp->smk_rules);
1918}
1919
1920static int load_self2_seq_show(struct seq_file *s, void *v)
1921{
1922 struct list_head *list = v;
1923 struct smack_rule *srp =
1924 list_entry(list, struct smack_rule, list);
1925
1926 smk_rule_show(s, srp, SMK_LONGLABEL);
1927
1928 return 0;
1929}
1930
1931static const struct seq_operations load_self2_seq_ops = {
1932 .start = load_self2_seq_start,
1933 .next = load_self2_seq_next,
1934 .show = load_self2_seq_show,
1935 .stop = smk_seq_stop,
1936};
1937
1938/**
1939 * smk_open_load_self2 - open() for /smack/load-self2
1940 * @inode: inode structure representing file
1941 * @file: "load" file pointer
1942 *
1943 * For reading, use load_seq_* seq_file reading operations.
1944 */
1945static int smk_open_load_self2(struct inode *inode, struct file *file)
1946{
1947 return seq_open(file, &load_self2_seq_ops);
1948}
1949
1950/**
1951 * smk_write_load_self2 - write() for /smack/load-self2
1952 * @file: file pointer, not actually used
1953 * @buf: where to get the data from
1954 * @count: bytes sent
1955 * @ppos: where to start - must be 0
1956 *
1957 */
1958static ssize_t smk_write_load_self2(struct file *file, const char __user *buf,
1959 size_t count, loff_t *ppos)
1960{
1961 struct task_smack *tsp = current_security();
1962
1963 return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules,
1964 &tsp->smk_rules_lock, SMK_LONG_FMT);
1965}
1966
1967static const struct file_operations smk_load_self2_ops = {
1968 .open = smk_open_load_self2,
1969 .read = seq_read,
1970 .llseek = seq_lseek,
1971 .write = smk_write_load_self2,
1972 .release = seq_release,
1973};
1974
1975/**
1976 * smk_write_access2 - handle access check transaction
1977 * @file: file pointer
1978 * @buf: data from user space
1979 * @count: bytes sent
1980 * @ppos: where to start - must be 0
1981 */
1982static ssize_t smk_write_access2(struct file *file, const char __user *buf,
1983 size_t count, loff_t *ppos)
1984{
1985 return smk_user_access(file, buf, count, ppos, SMK_LONG_FMT);
1986}
1987
1988static const struct file_operations smk_access2_ops = {
1989 .write = smk_write_access2,
1990 .read = simple_transaction_read,
1991 .release = simple_transaction_release,
1992 .llseek = generic_file_llseek,
1993};
1994
1995/**
1996 * smk_write_revoke_subj - write() for /smack/revoke-subject
1997 * @file: file pointer
1998 * @buf: data from user space
1999 * @count: bytes sent
2000 * @ppos: where to start - must be 0
2001 */
2002static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf,
2003 size_t count, loff_t *ppos)
2004{
2005 char *data = NULL;
2006 const char *cp = NULL;
2007 struct smack_known *skp;
2008 struct smack_rule *sp;
2009 struct list_head *rule_list;
2010 struct mutex *rule_lock;
2011 int rc = count;
2012
2013 if (*ppos != 0)
2014 return -EINVAL;
2015
2016 if (!smack_privileged(CAP_MAC_ADMIN))
2017 return -EPERM;
2018
2019 if (count == 0 || count > SMK_LONGLABEL)
2020 return -EINVAL;
2021
2022 data = kzalloc(count, GFP_KERNEL);
2023 if (data == NULL)
2024 return -ENOMEM;
2025
2026 if (copy_from_user(data, buf, count) != 0) {
2027 rc = -EFAULT;
2028 goto free_out;
2029 }
2030
2031 cp = smk_parse_smack(data, count);
2032 if (cp == NULL) {
2033 rc = -EINVAL;
2034 goto free_out;
2035 }
2036
2037 skp = smk_find_entry(cp);
2038 if (skp == NULL) {
2039 rc = -EINVAL;
2040 goto free_out;
2041 }
2042
2043 rule_list = &skp->smk_rules;
2044 rule_lock = &skp->smk_rules_lock;
2045
2046 mutex_lock(rule_lock);
2047
2048 list_for_each_entry_rcu(sp, rule_list, list)
2049 sp->smk_access = 0;
2050
2051 mutex_unlock(rule_lock);
2052
2053free_out:
2054 kfree(data);
2055 kfree(cp);
2056 return rc;
2057}
2058
2059static const struct file_operations smk_revoke_subj_ops = {
2060 .write = smk_write_revoke_subj,
2061 .read = simple_transaction_read,
2062 .release = simple_transaction_release,
2063 .llseek = generic_file_llseek,
2064};
2065
2066static struct kset *smackfs_kset;
2067/**
2068 * smk_init_sysfs - initialize /sys/fs/smackfs
2069 *
2070 */
2071static int smk_init_sysfs(void)
2072{
2073 smackfs_kset = kset_create_and_add("smackfs", NULL, fs_kobj);
2074 if (!smackfs_kset)
2075 return -ENOMEM;
2076 return 0;
2077}
2078
2079/** 1428/**
2080 * smk_fill_super - fill the /smackfs superblock 1429 * smk_fill_super - fill the /smackfs superblock
2081 * @sb: the empty superblock 1430 * @sb: the empty superblock
@@ -2110,21 +1459,6 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
2110 "logging", &smk_logging_ops, S_IRUGO|S_IWUSR}, 1459 "logging", &smk_logging_ops, S_IRUGO|S_IWUSR},
2111 [SMK_LOAD_SELF] = { 1460 [SMK_LOAD_SELF] = {
2112 "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO}, 1461 "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO},
2113 [SMK_ACCESSES] = {
2114 "access", &smk_access_ops, S_IRUGO|S_IWUGO},
2115 [SMK_MAPPED] = {
2116 "mapped", &smk_mapped_ops, S_IRUGO|S_IWUSR},
2117 [SMK_LOAD2] = {
2118 "load2", &smk_load2_ops, S_IRUGO|S_IWUSR},
2119 [SMK_LOAD_SELF2] = {
2120 "load-self2", &smk_load_self2_ops, S_IRUGO|S_IWUGO},
2121 [SMK_ACCESS2] = {
2122 "access2", &smk_access2_ops, S_IRUGO|S_IWUGO},
2123 [SMK_CIPSO2] = {
2124 "cipso2", &smk_cipso2_ops, S_IRUGO|S_IWUSR},
2125 [SMK_REVOKE_SUBJ] = {
2126 "revoke-subject", &smk_revoke_subj_ops,
2127 S_IRUGO|S_IWUSR},
2128 /* last one */ 1462 /* last one */
2129 {""} 1463 {""}
2130 }; 1464 };
@@ -2137,6 +1471,7 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
2137 } 1471 }
2138 1472
2139 root_inode = sb->s_root->d_inode; 1473 root_inode = sb->s_root->d_inode;
1474 root_inode->i_security = new_inode_smack(smack_known_floor.smk_known);
2140 1475
2141 return 0; 1476 return 0;
2142} 1477}
@@ -2166,15 +1501,6 @@ static struct file_system_type smk_fs_type = {
2166 1501
2167static struct vfsmount *smackfs_mount; 1502static struct vfsmount *smackfs_mount;
2168 1503
2169static int __init smk_preset_netlabel(struct smack_known *skp)
2170{
2171 skp->smk_netlabel.domain = skp->smk_known;
2172 skp->smk_netlabel.flags =
2173 NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
2174 return smk_netlbl_mls(smack_cipso_direct, skp->smk_known,
2175 &skp->smk_netlabel, strlen(skp->smk_known));
2176}
2177
2178/** 1504/**
2179 * init_smk_fs - get the smackfs superblock 1505 * init_smk_fs - get the smackfs superblock
2180 * 1506 *
@@ -2191,15 +1517,10 @@ static int __init smk_preset_netlabel(struct smack_known *skp)
2191static int __init init_smk_fs(void) 1517static int __init init_smk_fs(void)
2192{ 1518{
2193 int err; 1519 int err;
2194 int rc;
2195 1520
2196 if (!security_module_enable(&smack_ops)) 1521 if (!security_module_enable(&smack_ops))
2197 return 0; 1522 return 0;
2198 1523
2199 err = smk_init_sysfs();
2200 if (err)
2201 printk(KERN_ERR "smackfs: sysfs mountpoint problem.\n");
2202
2203 err = register_filesystem(&smk_fs_type); 1524 err = register_filesystem(&smk_fs_type);
2204 if (!err) { 1525 if (!err) {
2205 smackfs_mount = kern_mount(&smk_fs_type); 1526 smackfs_mount = kern_mount(&smk_fs_type);
@@ -2213,25 +1534,6 @@ static int __init init_smk_fs(void)
2213 smk_cipso_doi(); 1534 smk_cipso_doi();
2214 smk_unlbl_ambient(NULL); 1535 smk_unlbl_ambient(NULL);
2215 1536
2216 rc = smk_preset_netlabel(&smack_known_floor);
2217 if (err == 0 && rc < 0)
2218 err = rc;
2219 rc = smk_preset_netlabel(&smack_known_hat);
2220 if (err == 0 && rc < 0)
2221 err = rc;
2222 rc = smk_preset_netlabel(&smack_known_huh);
2223 if (err == 0 && rc < 0)
2224 err = rc;
2225 rc = smk_preset_netlabel(&smack_known_invalid);
2226 if (err == 0 && rc < 0)
2227 err = rc;
2228 rc = smk_preset_netlabel(&smack_known_star);
2229 if (err == 0 && rc < 0)
2230 err = rc;
2231 rc = smk_preset_netlabel(&smack_known_web);
2232 if (err == 0 && rc < 0)
2233 err = rc;
2234
2235 return err; 1537 return err;
2236} 1538}
2237 1539