diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /security/smack/smackfs.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r-- | security/smack/smackfs.c | 424 |
1 files changed, 297 insertions, 127 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index a2b72d77f926..f93460156dce 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -43,6 +43,7 @@ enum smk_inos { | |||
43 | SMK_NETLBLADDR = 8, /* single label hosts */ | 43 | SMK_NETLBLADDR = 8, /* single label hosts */ |
44 | SMK_ONLYCAP = 9, /* the only "capable" label */ | 44 | SMK_ONLYCAP = 9, /* the only "capable" label */ |
45 | SMK_LOGGING = 10, /* logging */ | 45 | SMK_LOGGING = 10, /* logging */ |
46 | SMK_LOAD_SELF = 11, /* task specific rules */ | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | /* | 49 | /* |
@@ -109,9 +110,12 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION; | |||
109 | * SMK_ACCESSLEN: Maximum length for a rule access field | 110 | * SMK_ACCESSLEN: Maximum length for a rule access field |
110 | * SMK_LOADLEN: Smack rule length | 111 | * SMK_LOADLEN: Smack rule length |
111 | */ | 112 | */ |
112 | #define SMK_ACCESS "rwxa" | 113 | #define SMK_OACCESS "rwxa" |
113 | #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) | 114 | #define SMK_ACCESS "rwxat" |
114 | #define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) | 115 | #define SMK_OACCESSLEN (sizeof(SMK_OACCESS) - 1) |
116 | #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) | ||
117 | #define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN) | ||
118 | #define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) | ||
115 | 119 | ||
116 | /** | 120 | /** |
117 | * smk_netlabel_audit_set - fill a netlbl_audit struct | 121 | * smk_netlabel_audit_set - fill a netlbl_audit struct |
@@ -121,7 +125,7 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap) | |||
121 | { | 125 | { |
122 | nap->loginuid = audit_get_loginuid(current); | 126 | nap->loginuid = audit_get_loginuid(current); |
123 | nap->sessionid = audit_get_sessionid(current); | 127 | nap->sessionid = audit_get_sessionid(current); |
124 | nap->secid = smack_to_secid(current_security()); | 128 | nap->secid = smack_to_secid(smk_of_current()); |
125 | } | 129 | } |
126 | 130 | ||
127 | /* | 131 | /* |
@@ -132,102 +136,30 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap) | |||
132 | #define SMK_NETLBLADDRMIN 9 | 136 | #define SMK_NETLBLADDRMIN 9 |
133 | #define SMK_NETLBLADDRMAX 42 | 137 | #define SMK_NETLBLADDRMAX 42 |
134 | 138 | ||
135 | /* | ||
136 | * Seq_file read operations for /smack/load | ||
137 | */ | ||
138 | |||
139 | static void *load_seq_start(struct seq_file *s, loff_t *pos) | ||
140 | { | ||
141 | if (*pos == SEQ_READ_FINISHED) | ||
142 | return NULL; | ||
143 | if (list_empty(&smack_rule_list)) | ||
144 | return NULL; | ||
145 | return smack_rule_list.next; | ||
146 | } | ||
147 | |||
148 | static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
149 | { | ||
150 | struct list_head *list = v; | ||
151 | |||
152 | if (list_is_last(list, &smack_rule_list)) { | ||
153 | *pos = SEQ_READ_FINISHED; | ||
154 | return NULL; | ||
155 | } | ||
156 | return list->next; | ||
157 | } | ||
158 | |||
159 | static int load_seq_show(struct seq_file *s, void *v) | ||
160 | { | ||
161 | struct list_head *list = v; | ||
162 | struct smack_rule *srp = | ||
163 | list_entry(list, struct smack_rule, list); | ||
164 | |||
165 | seq_printf(s, "%s %s", (char *)srp->smk_subject, | ||
166 | (char *)srp->smk_object); | ||
167 | |||
168 | seq_putc(s, ' '); | ||
169 | |||
170 | if (srp->smk_access & MAY_READ) | ||
171 | seq_putc(s, 'r'); | ||
172 | if (srp->smk_access & MAY_WRITE) | ||
173 | seq_putc(s, 'w'); | ||
174 | if (srp->smk_access & MAY_EXEC) | ||
175 | seq_putc(s, 'x'); | ||
176 | if (srp->smk_access & MAY_APPEND) | ||
177 | seq_putc(s, 'a'); | ||
178 | if (srp->smk_access == 0) | ||
179 | seq_putc(s, '-'); | ||
180 | |||
181 | seq_putc(s, '\n'); | ||
182 | |||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static void load_seq_stop(struct seq_file *s, void *v) | ||
187 | { | ||
188 | /* No-op */ | ||
189 | } | ||
190 | |||
191 | static const struct seq_operations load_seq_ops = { | ||
192 | .start = load_seq_start, | ||
193 | .next = load_seq_next, | ||
194 | .show = load_seq_show, | ||
195 | .stop = load_seq_stop, | ||
196 | }; | ||
197 | |||
198 | /** | ||
199 | * smk_open_load - open() for /smack/load | ||
200 | * @inode: inode structure representing file | ||
201 | * @file: "load" file pointer | ||
202 | * | ||
203 | * For reading, use load_seq_* seq_file reading operations. | ||
204 | */ | ||
205 | static int smk_open_load(struct inode *inode, struct file *file) | ||
206 | { | ||
207 | return seq_open(file, &load_seq_ops); | ||
208 | } | ||
209 | |||
210 | /** | 139 | /** |
211 | * smk_set_access - add a rule to the rule list | 140 | * smk_set_access - add a rule to the rule list |
212 | * @srp: the new rule to add | 141 | * @srp: the new rule to add |
142 | * @rule_list: the list of rules | ||
143 | * @rule_lock: the rule list lock | ||
213 | * | 144 | * |
214 | * Looks through the current subject/object/access list for | 145 | * Looks through the current subject/object/access list for |
215 | * the subject/object pair and replaces the access that was | 146 | * the subject/object pair and replaces the access that was |
216 | * there. If the pair isn't found add it with the specified | 147 | * there. If the pair isn't found add it with the specified |
217 | * access. | 148 | * access. |
218 | * | 149 | * |
150 | * Returns 1 if a rule was found to exist already, 0 if it is new | ||
219 | * Returns 0 if nothing goes wrong or -ENOMEM if it fails | 151 | * Returns 0 if nothing goes wrong or -ENOMEM if it fails |
220 | * during the allocation of the new pair to add. | 152 | * during the allocation of the new pair to add. |
221 | */ | 153 | */ |
222 | static int smk_set_access(struct smack_rule *srp) | 154 | static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list, |
155 | struct mutex *rule_lock) | ||
223 | { | 156 | { |
224 | struct smack_rule *sp; | 157 | struct smack_rule *sp; |
225 | int ret = 0; | 158 | int found = 0; |
226 | int found; | ||
227 | mutex_lock(&smack_list_lock); | ||
228 | 159 | ||
229 | found = 0; | 160 | mutex_lock(rule_lock); |
230 | list_for_each_entry_rcu(sp, &smack_rule_list, list) { | 161 | |
162 | list_for_each_entry_rcu(sp, rule_list, list) { | ||
231 | if (sp->smk_subject == srp->smk_subject && | 163 | if (sp->smk_subject == srp->smk_subject && |
232 | sp->smk_object == srp->smk_object) { | 164 | sp->smk_object == srp->smk_object) { |
233 | found = 1; | 165 | found = 1; |
@@ -236,19 +168,21 @@ static int smk_set_access(struct smack_rule *srp) | |||
236 | } | 168 | } |
237 | } | 169 | } |
238 | if (found == 0) | 170 | if (found == 0) |
239 | list_add_rcu(&srp->list, &smack_rule_list); | 171 | list_add_rcu(&srp->list, rule_list); |
240 | 172 | ||
241 | mutex_unlock(&smack_list_lock); | 173 | mutex_unlock(rule_lock); |
242 | 174 | ||
243 | return ret; | 175 | return found; |
244 | } | 176 | } |
245 | 177 | ||
246 | /** | 178 | /** |
247 | * smk_write_load - write() for /smack/load | 179 | * smk_write_load_list - write() for any /smack/load |
248 | * @file: file pointer, not actually used | 180 | * @file: file pointer, not actually used |
249 | * @buf: where to get the data from | 181 | * @buf: where to get the data from |
250 | * @count: bytes sent | 182 | * @count: bytes sent |
251 | * @ppos: where to start - must be 0 | 183 | * @ppos: where to start - must be 0 |
184 | * @rule_list: the list of rules to write to | ||
185 | * @rule_lock: lock for the rule list | ||
252 | * | 186 | * |
253 | * Get one smack access rule from above. | 187 | * Get one smack access rule from above. |
254 | * The format is exactly: | 188 | * The format is exactly: |
@@ -258,25 +192,28 @@ static int smk_set_access(struct smack_rule *srp) | |||
258 | * | 192 | * |
259 | * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes. | 193 | * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes. |
260 | */ | 194 | */ |
261 | static ssize_t smk_write_load(struct file *file, const char __user *buf, | 195 | static ssize_t smk_write_load_list(struct file *file, const char __user *buf, |
262 | size_t count, loff_t *ppos) | 196 | size_t count, loff_t *ppos, |
197 | struct list_head *rule_list, | ||
198 | struct mutex *rule_lock) | ||
263 | { | 199 | { |
264 | struct smack_rule *rule; | 200 | struct smack_rule *rule; |
265 | char *data; | 201 | char *data; |
266 | int rc = -EINVAL; | 202 | int rc = -EINVAL; |
267 | 203 | ||
268 | /* | 204 | /* |
269 | * Must have privilege. | ||
270 | * No partial writes. | 205 | * No partial writes. |
271 | * Enough data must be present. | 206 | * Enough data must be present. |
272 | */ | 207 | */ |
273 | if (!capable(CAP_MAC_ADMIN)) | 208 | if (*ppos != 0) |
274 | return -EPERM; | 209 | return -EINVAL; |
275 | 210 | /* | |
276 | if (*ppos != 0 || count != SMK_LOADLEN) | 211 | * Minor hack for backward compatibility |
212 | */ | ||
213 | if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN) | ||
277 | return -EINVAL; | 214 | return -EINVAL; |
278 | 215 | ||
279 | data = kzalloc(count, GFP_KERNEL); | 216 | data = kzalloc(SMK_LOADLEN, GFP_KERNEL); |
280 | if (data == NULL) | 217 | if (data == NULL) |
281 | return -ENOMEM; | 218 | return -ENOMEM; |
282 | 219 | ||
@@ -285,6 +222,12 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf, | |||
285 | goto out; | 222 | goto out; |
286 | } | 223 | } |
287 | 224 | ||
225 | /* | ||
226 | * More on the minor hack for backward compatibility | ||
227 | */ | ||
228 | if (count == (SMK_OLOADLEN)) | ||
229 | data[SMK_OLOADLEN] = '-'; | ||
230 | |||
288 | rule = kzalloc(sizeof(*rule), GFP_KERNEL); | 231 | rule = kzalloc(sizeof(*rule), GFP_KERNEL); |
289 | if (rule == NULL) { | 232 | if (rule == NULL) { |
290 | rc = -ENOMEM; | 233 | rc = -ENOMEM; |
@@ -345,11 +288,24 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf, | |||
345 | goto out_free_rule; | 288 | goto out_free_rule; |
346 | } | 289 | } |
347 | 290 | ||
348 | rc = smk_set_access(rule); | 291 | switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) { |
292 | case '-': | ||
293 | break; | ||
294 | case 't': | ||
295 | case 'T': | ||
296 | rule->smk_access |= MAY_TRANSMUTE; | ||
297 | break; | ||
298 | default: | ||
299 | goto out_free_rule; | ||
300 | } | ||
349 | 301 | ||
350 | if (!rc) | 302 | rc = count; |
351 | rc = count; | 303 | /* |
352 | goto out; | 304 | * smk_set_access returns true if there was already a rule |
305 | * for the subject/object pair, and false if it was new. | ||
306 | */ | ||
307 | if (!smk_set_access(rule, rule_list, rule_lock)) | ||
308 | goto out; | ||
353 | 309 | ||
354 | out_free_rule: | 310 | out_free_rule: |
355 | kfree(rule); | 311 | kfree(rule); |
@@ -358,6 +314,108 @@ out: | |||
358 | return rc; | 314 | return rc; |
359 | } | 315 | } |
360 | 316 | ||
317 | |||
318 | /* | ||
319 | * Seq_file read operations for /smack/load | ||
320 | */ | ||
321 | |||
322 | static void *load_seq_start(struct seq_file *s, loff_t *pos) | ||
323 | { | ||
324 | if (*pos == SEQ_READ_FINISHED) | ||
325 | return NULL; | ||
326 | if (list_empty(&smack_rule_list)) | ||
327 | return NULL; | ||
328 | return smack_rule_list.next; | ||
329 | } | ||
330 | |||
331 | static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
332 | { | ||
333 | struct list_head *list = v; | ||
334 | |||
335 | if (list_is_last(list, &smack_rule_list)) { | ||
336 | *pos = SEQ_READ_FINISHED; | ||
337 | return NULL; | ||
338 | } | ||
339 | return list->next; | ||
340 | } | ||
341 | |||
342 | static int load_seq_show(struct seq_file *s, void *v) | ||
343 | { | ||
344 | struct list_head *list = v; | ||
345 | struct smack_rule *srp = | ||
346 | list_entry(list, struct smack_rule, list); | ||
347 | |||
348 | seq_printf(s, "%s %s", (char *)srp->smk_subject, | ||
349 | (char *)srp->smk_object); | ||
350 | |||
351 | seq_putc(s, ' '); | ||
352 | |||
353 | if (srp->smk_access & MAY_READ) | ||
354 | seq_putc(s, 'r'); | ||
355 | if (srp->smk_access & MAY_WRITE) | ||
356 | seq_putc(s, 'w'); | ||
357 | if (srp->smk_access & MAY_EXEC) | ||
358 | seq_putc(s, 'x'); | ||
359 | if (srp->smk_access & MAY_APPEND) | ||
360 | seq_putc(s, 'a'); | ||
361 | if (srp->smk_access & MAY_TRANSMUTE) | ||
362 | seq_putc(s, 't'); | ||
363 | if (srp->smk_access == 0) | ||
364 | seq_putc(s, '-'); | ||
365 | |||
366 | seq_putc(s, '\n'); | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static void load_seq_stop(struct seq_file *s, void *v) | ||
372 | { | ||
373 | /* No-op */ | ||
374 | } | ||
375 | |||
376 | static const struct seq_operations load_seq_ops = { | ||
377 | .start = load_seq_start, | ||
378 | .next = load_seq_next, | ||
379 | .show = load_seq_show, | ||
380 | .stop = load_seq_stop, | ||
381 | }; | ||
382 | |||
383 | /** | ||
384 | * smk_open_load - open() for /smack/load | ||
385 | * @inode: inode structure representing file | ||
386 | * @file: "load" file pointer | ||
387 | * | ||
388 | * For reading, use load_seq_* seq_file reading operations. | ||
389 | */ | ||
390 | static int smk_open_load(struct inode *inode, struct file *file) | ||
391 | { | ||
392 | return seq_open(file, &load_seq_ops); | ||
393 | } | ||
394 | |||
395 | /** | ||
396 | * smk_write_load - write() for /smack/load | ||
397 | * @file: file pointer, not actually used | ||
398 | * @buf: where to get the data from | ||
399 | * @count: bytes sent | ||
400 | * @ppos: where to start - must be 0 | ||
401 | * | ||
402 | */ | ||
403 | static ssize_t smk_write_load(struct file *file, const char __user *buf, | ||
404 | size_t count, loff_t *ppos) | ||
405 | { | ||
406 | |||
407 | /* | ||
408 | * Must have privilege. | ||
409 | * No partial writes. | ||
410 | * Enough data must be present. | ||
411 | */ | ||
412 | if (!capable(CAP_MAC_ADMIN)) | ||
413 | return -EPERM; | ||
414 | |||
415 | return smk_write_load_list(file, buf, count, ppos, &smack_rule_list, | ||
416 | &smack_list_lock); | ||
417 | } | ||
418 | |||
361 | static const struct file_operations smk_load_ops = { | 419 | static const struct file_operations smk_load_ops = { |
362 | .open = smk_open_load, | 420 | .open = smk_open_load, |
363 | .read = seq_read, | 421 | .read = seq_read, |
@@ -869,7 +927,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
869 | } | 927 | } |
870 | } else { | 928 | } else { |
871 | /* we delete the unlabeled entry, only if the previous label | 929 | /* we delete the unlabeled entry, only if the previous label |
872 | * wasnt the special CIPSO option */ | 930 | * wasn't the special CIPSO option */ |
873 | if (skp->smk_label != smack_cipso_option) | 931 | if (skp->smk_label != smack_cipso_option) |
874 | rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, | 932 | rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, |
875 | &skp->smk_host.sin_addr, &skp->smk_mask, | 933 | &skp->smk_host.sin_addr, &skp->smk_mask, |
@@ -968,6 +1026,7 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf, | |||
968 | static const struct file_operations smk_doi_ops = { | 1026 | static const struct file_operations smk_doi_ops = { |
969 | .read = smk_read_doi, | 1027 | .read = smk_read_doi, |
970 | .write = smk_write_doi, | 1028 | .write = smk_write_doi, |
1029 | .llseek = default_llseek, | ||
971 | }; | 1030 | }; |
972 | 1031 | ||
973 | /** | 1032 | /** |
@@ -1031,6 +1090,7 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf, | |||
1031 | static const struct file_operations smk_direct_ops = { | 1090 | static const struct file_operations smk_direct_ops = { |
1032 | .read = smk_read_direct, | 1091 | .read = smk_read_direct, |
1033 | .write = smk_write_direct, | 1092 | .write = smk_write_direct, |
1093 | .llseek = default_llseek, | ||
1034 | }; | 1094 | }; |
1035 | 1095 | ||
1036 | /** | 1096 | /** |
@@ -1112,6 +1172,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, | |||
1112 | static const struct file_operations smk_ambient_ops = { | 1172 | static const struct file_operations smk_ambient_ops = { |
1113 | .read = smk_read_ambient, | 1173 | .read = smk_read_ambient, |
1114 | .write = smk_write_ambient, | 1174 | .write = smk_write_ambient, |
1175 | .llseek = default_llseek, | ||
1115 | }; | 1176 | }; |
1116 | 1177 | ||
1117 | /** | 1178 | /** |
@@ -1157,7 +1218,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, | |||
1157 | size_t count, loff_t *ppos) | 1218 | size_t count, loff_t *ppos) |
1158 | { | 1219 | { |
1159 | char in[SMK_LABELLEN]; | 1220 | char in[SMK_LABELLEN]; |
1160 | char *sp = current->cred->security; | 1221 | char *sp = smk_of_task(current->cred->security); |
1161 | 1222 | ||
1162 | if (!capable(CAP_MAC_ADMIN)) | 1223 | if (!capable(CAP_MAC_ADMIN)) |
1163 | return -EPERM; | 1224 | return -EPERM; |
@@ -1191,6 +1252,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, | |||
1191 | static const struct file_operations smk_onlycap_ops = { | 1252 | static const struct file_operations smk_onlycap_ops = { |
1192 | .read = smk_read_onlycap, | 1253 | .read = smk_read_onlycap, |
1193 | .write = smk_write_onlycap, | 1254 | .write = smk_write_onlycap, |
1255 | .llseek = default_llseek, | ||
1194 | }; | 1256 | }; |
1195 | 1257 | ||
1196 | /** | 1258 | /** |
@@ -1255,6 +1317,113 @@ static ssize_t smk_write_logging(struct file *file, const char __user *buf, | |||
1255 | static const struct file_operations smk_logging_ops = { | 1317 | static const struct file_operations smk_logging_ops = { |
1256 | .read = smk_read_logging, | 1318 | .read = smk_read_logging, |
1257 | .write = smk_write_logging, | 1319 | .write = smk_write_logging, |
1320 | .llseek = default_llseek, | ||
1321 | }; | ||
1322 | |||
1323 | /* | ||
1324 | * Seq_file read operations for /smack/load-self | ||
1325 | */ | ||
1326 | |||
1327 | static void *load_self_seq_start(struct seq_file *s, loff_t *pos) | ||
1328 | { | ||
1329 | struct task_smack *tsp = current_security(); | ||
1330 | |||
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; | ||
1336 | } | ||
1337 | |||
1338 | static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
1339 | { | ||
1340 | struct task_smack *tsp = current_security(); | ||
1341 | struct list_head *list = v; | ||
1342 | |||
1343 | if (list_is_last(list, &tsp->smk_rules)) { | ||
1344 | *pos = SEQ_READ_FINISHED; | ||
1345 | return NULL; | ||
1346 | } | ||
1347 | return list->next; | ||
1348 | } | ||
1349 | |||
1350 | static int load_self_seq_show(struct seq_file *s, void *v) | ||
1351 | { | ||
1352 | struct list_head *list = v; | ||
1353 | struct smack_rule *srp = | ||
1354 | list_entry(list, struct smack_rule, list); | ||
1355 | |||
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'); | ||
1375 | |||
1376 | return 0; | ||
1377 | } | ||
1378 | |||
1379 | static void load_self_seq_stop(struct seq_file *s, void *v) | ||
1380 | { | ||
1381 | /* No-op */ | ||
1382 | } | ||
1383 | |||
1384 | static const struct seq_operations load_self_seq_ops = { | ||
1385 | .start = load_self_seq_start, | ||
1386 | .next = load_self_seq_next, | ||
1387 | .show = load_self_seq_show, | ||
1388 | .stop = load_self_seq_stop, | ||
1389 | }; | ||
1390 | |||
1391 | |||
1392 | /** | ||
1393 | * smk_open_load_self - open() for /smack/load-self | ||
1394 | * @inode: inode structure representing file | ||
1395 | * @file: "load" file pointer | ||
1396 | * | ||
1397 | * For reading, use load_seq_* seq_file reading operations. | ||
1398 | */ | ||
1399 | static int smk_open_load_self(struct inode *inode, struct file *file) | ||
1400 | { | ||
1401 | return seq_open(file, &load_self_seq_ops); | ||
1402 | } | ||
1403 | |||
1404 | /** | ||
1405 | * smk_write_load_self - write() for /smack/load-self | ||
1406 | * @file: file pointer, not actually used | ||
1407 | * @buf: where to get the data from | ||
1408 | * @count: bytes sent | ||
1409 | * @ppos: where to start - must be 0 | ||
1410 | * | ||
1411 | */ | ||
1412 | static ssize_t smk_write_load_self(struct file *file, const char __user *buf, | ||
1413 | size_t count, loff_t *ppos) | ||
1414 | { | ||
1415 | struct task_smack *tsp = current_security(); | ||
1416 | |||
1417 | return smk_write_load_list(file, buf, count, ppos, &tsp->smk_rules, | ||
1418 | &tsp->smk_rules_lock); | ||
1419 | } | ||
1420 | |||
1421 | static const struct file_operations smk_load_self_ops = { | ||
1422 | .open = smk_open_load_self, | ||
1423 | .read = seq_read, | ||
1424 | .llseek = seq_lseek, | ||
1425 | .write = smk_write_load_self, | ||
1426 | .release = seq_release, | ||
1258 | }; | 1427 | }; |
1259 | /** | 1428 | /** |
1260 | * smk_fill_super - fill the /smackfs superblock | 1429 | * smk_fill_super - fill the /smackfs superblock |
@@ -1272,23 +1441,26 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) | |||
1272 | struct inode *root_inode; | 1441 | struct inode *root_inode; |
1273 | 1442 | ||
1274 | static struct tree_descr smack_files[] = { | 1443 | static struct tree_descr smack_files[] = { |
1275 | [SMK_LOAD] = | 1444 | [SMK_LOAD] = { |
1276 | {"load", &smk_load_ops, S_IRUGO|S_IWUSR}, | 1445 | "load", &smk_load_ops, S_IRUGO|S_IWUSR}, |
1277 | [SMK_CIPSO] = | 1446 | [SMK_CIPSO] = { |
1278 | {"cipso", &smk_cipso_ops, S_IRUGO|S_IWUSR}, | 1447 | "cipso", &smk_cipso_ops, S_IRUGO|S_IWUSR}, |
1279 | [SMK_DOI] = | 1448 | [SMK_DOI] = { |
1280 | {"doi", &smk_doi_ops, S_IRUGO|S_IWUSR}, | 1449 | "doi", &smk_doi_ops, S_IRUGO|S_IWUSR}, |
1281 | [SMK_DIRECT] = | 1450 | [SMK_DIRECT] = { |
1282 | {"direct", &smk_direct_ops, S_IRUGO|S_IWUSR}, | 1451 | "direct", &smk_direct_ops, S_IRUGO|S_IWUSR}, |
1283 | [SMK_AMBIENT] = | 1452 | [SMK_AMBIENT] = { |
1284 | {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR}, | 1453 | "ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR}, |
1285 | [SMK_NETLBLADDR] = | 1454 | [SMK_NETLBLADDR] = { |
1286 | {"netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR}, | 1455 | "netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR}, |
1287 | [SMK_ONLYCAP] = | 1456 | [SMK_ONLYCAP] = { |
1288 | {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR}, | 1457 | "onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR}, |
1289 | [SMK_LOGGING] = | 1458 | [SMK_LOGGING] = { |
1290 | {"logging", &smk_logging_ops, S_IRUGO|S_IWUSR}, | 1459 | "logging", &smk_logging_ops, S_IRUGO|S_IWUSR}, |
1291 | /* last one */ {""} | 1460 | [SMK_LOAD_SELF] = { |
1461 | "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO}, | ||
1462 | /* last one */ | ||
1463 | {""} | ||
1292 | }; | 1464 | }; |
1293 | 1465 | ||
1294 | rc = simple_fill_super(sb, SMACK_MAGIC, smack_files); | 1466 | rc = simple_fill_super(sb, SMACK_MAGIC, smack_files); |
@@ -1305,27 +1477,25 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) | |||
1305 | } | 1477 | } |
1306 | 1478 | ||
1307 | /** | 1479 | /** |
1308 | * smk_get_sb - get the smackfs superblock | 1480 | * smk_mount - get the smackfs superblock |
1309 | * @fs_type: passed along without comment | 1481 | * @fs_type: passed along without comment |
1310 | * @flags: passed along without comment | 1482 | * @flags: passed along without comment |
1311 | * @dev_name: passed along without comment | 1483 | * @dev_name: passed along without comment |
1312 | * @data: passed along without comment | 1484 | * @data: passed along without comment |
1313 | * @mnt: passed along without comment | ||
1314 | * | 1485 | * |
1315 | * Just passes everything along. | 1486 | * Just passes everything along. |
1316 | * | 1487 | * |
1317 | * Returns what the lower level code does. | 1488 | * Returns what the lower level code does. |
1318 | */ | 1489 | */ |
1319 | static int smk_get_sb(struct file_system_type *fs_type, | 1490 | static struct dentry *smk_mount(struct file_system_type *fs_type, |
1320 | int flags, const char *dev_name, void *data, | 1491 | int flags, const char *dev_name, void *data) |
1321 | struct vfsmount *mnt) | ||
1322 | { | 1492 | { |
1323 | return get_sb_single(fs_type, flags, data, smk_fill_super, mnt); | 1493 | return mount_single(fs_type, flags, data, smk_fill_super); |
1324 | } | 1494 | } |
1325 | 1495 | ||
1326 | static struct file_system_type smk_fs_type = { | 1496 | static struct file_system_type smk_fs_type = { |
1327 | .name = "smackfs", | 1497 | .name = "smackfs", |
1328 | .get_sb = smk_get_sb, | 1498 | .mount = smk_mount, |
1329 | .kill_sb = kill_litter_super, | 1499 | .kill_sb = kill_litter_super, |
1330 | }; | 1500 | }; |
1331 | 1501 | ||