aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-10 13:05:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-10 13:05:36 -0400
commitfad0701eaa091beb8ce5ef2eef04b5e833617368 (patch)
tree788297c7b05b167599265013ef8ec473a0d367fe /security
parentd53b47c08d8fda1892f47393de8eeab4e34b3188 (diff)
parentf9b2a735bdddf836214b5dca74f6ca7712e5a08c (diff)
Merge branch 'serge-next-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux-security
Pull security layer updates from Serge Hallyn: "This is a merge of James Morris' security-next tree from 3.14 to yesterday's master, plus four patches from Paul Moore which are in linux-next, plus one patch from Mimi" * 'serge-next-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux-security: ima: audit log files opened with O_DIRECT flag selinux: conditionally reschedule in hashtab_insert while loading selinux policy selinux: conditionally reschedule in mls_convert_context while loading selinux policy selinux: reject setexeccon() on MNT_NOSUID applications with -EACCES selinux: Report permissive mode in avc: denied messages. Warning in scanf string typing Smack: Label cgroup files for systemd Smack: Verify read access on file open - v3 security: Convert use of typedef ctl_table to struct ctl_table Smack: bidirectional UDS connect check Smack: Correctly remove SMACK64TRANSMUTE attribute SMACK: Fix handling value==NULL in post setxattr bugfix patch for SMACK Smack: adds smackfs/ptrace interface Smack: unify all ptrace accesses in the smack Smack: fix the subject/object order in smack_ptrace_traceme() Minor improvement of 'smack_sb_kern_mount' smack: fix key permission verification KEYS: Move the flags representing required permission to linux/key.h
Diffstat (limited to 'security')
-rw-r--r--security/capability.c2
-rw-r--r--security/integrity/ima/ima_api.c10
-rw-r--r--security/integrity/ima/ima_main.c5
-rw-r--r--security/integrity/ima/ima_policy.c6
-rw-r--r--security/integrity/integrity.h1
-rw-r--r--security/keys/internal.h11
-rw-r--r--security/keys/key.c6
-rw-r--r--security/keys/keyctl.c44
-rw-r--r--security/keys/keyring.c8
-rw-r--r--security/keys/permission.c4
-rw-r--r--security/keys/persistent.c4
-rw-r--r--security/keys/proc.c2
-rw-r--r--security/keys/sysctl.c2
-rw-r--r--security/security.c2
-rw-r--r--security/selinux/avc.c7
-rw-r--r--security/selinux/hooks.c13
-rw-r--r--security/selinux/include/avc.h4
-rw-r--r--security/selinux/ss/hashtab.c3
-rw-r--r--security/selinux/ss/mls.c2
-rw-r--r--security/smack/smack.h16
-rw-r--r--security/smack/smack_access.c38
-rw-r--r--security/smack/smack_lsm.c249
-rw-r--r--security/smack/smackfs.c76
23 files changed, 382 insertions, 133 deletions
diff --git a/security/capability.c b/security/capability.c
index ad0d4de69944..e76373de3129 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -879,7 +879,7 @@ static void cap_key_free(struct key *key)
879} 879}
880 880
881static int cap_key_permission(key_ref_t key_ref, const struct cred *cred, 881static int cap_key_permission(key_ref_t key_ref, const struct cred *cred,
882 key_perm_t perm) 882 unsigned perm)
883{ 883{
884 return 0; 884 return 0;
885} 885}
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index ba9e4d792dd5..d9cd5ce14d2b 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -199,6 +199,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
199 struct evm_ima_xattr_data **xattr_value, 199 struct evm_ima_xattr_data **xattr_value,
200 int *xattr_len) 200 int *xattr_len)
201{ 201{
202 const char *audit_cause = "failed";
202 struct inode *inode = file_inode(file); 203 struct inode *inode = file_inode(file);
203 const char *filename = file->f_dentry->d_name.name; 204 const char *filename = file->f_dentry->d_name.name;
204 int result = 0; 205 int result = 0;
@@ -213,6 +214,12 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
213 if (!(iint->flags & IMA_COLLECTED)) { 214 if (!(iint->flags & IMA_COLLECTED)) {
214 u64 i_version = file_inode(file)->i_version; 215 u64 i_version = file_inode(file)->i_version;
215 216
217 if (file->f_flags & O_DIRECT) {
218 audit_cause = "failed(directio)";
219 result = -EACCES;
220 goto out;
221 }
222
216 /* use default hash algorithm */ 223 /* use default hash algorithm */
217 hash.hdr.algo = ima_hash_algo; 224 hash.hdr.algo = ima_hash_algo;
218 225
@@ -233,9 +240,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
233 result = -ENOMEM; 240 result = -ENOMEM;
234 } 241 }
235 } 242 }
243out:
236 if (result) 244 if (result)
237 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, 245 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
238 filename, "collect_data", "failed", 246 filename, "collect_data", audit_cause,
239 result, 0); 247 result, 0);
240 return result; 248 return result;
241} 249}
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 52ac6cf41f88..dcc98cf542d8 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -214,8 +214,11 @@ static int process_measurement(struct file *file, const char *filename,
214 xattr_ptr = &xattr_value; 214 xattr_ptr = &xattr_value;
215 215
216 rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len); 216 rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len);
217 if (rc != 0) 217 if (rc != 0) {
218 if (file->f_flags & O_DIRECT)
219 rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES;
218 goto out_digsig; 220 goto out_digsig;
221 }
219 222
220 pathname = filename ?: ima_d_path(&file->f_path, &pathbuf); 223 pathname = filename ?: ima_d_path(&file->f_path, &pathbuf);
221 224
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 93873a450ff7..40a7488f6721 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -353,7 +353,7 @@ enum {
353 Opt_obj_user, Opt_obj_role, Opt_obj_type, 353 Opt_obj_user, Opt_obj_role, Opt_obj_type,
354 Opt_subj_user, Opt_subj_role, Opt_subj_type, 354 Opt_subj_user, Opt_subj_role, Opt_subj_type,
355 Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner, 355 Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner,
356 Opt_appraise_type, Opt_fsuuid 356 Opt_appraise_type, Opt_fsuuid, Opt_permit_directio
357}; 357};
358 358
359static match_table_t policy_tokens = { 359static match_table_t policy_tokens = {
@@ -375,6 +375,7 @@ static match_table_t policy_tokens = {
375 {Opt_uid, "uid=%s"}, 375 {Opt_uid, "uid=%s"},
376 {Opt_fowner, "fowner=%s"}, 376 {Opt_fowner, "fowner=%s"},
377 {Opt_appraise_type, "appraise_type=%s"}, 377 {Opt_appraise_type, "appraise_type=%s"},
378 {Opt_permit_directio, "permit_directio"},
378 {Opt_err, NULL} 379 {Opt_err, NULL}
379}; 380};
380 381
@@ -622,6 +623,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
622 else 623 else
623 result = -EINVAL; 624 result = -EINVAL;
624 break; 625 break;
626 case Opt_permit_directio:
627 entry->flags |= IMA_PERMIT_DIRECTIO;
628 break;
625 case Opt_err: 629 case Opt_err:
626 ima_log_string(ab, "UNKNOWN", p); 630 ima_log_string(ab, "UNKNOWN", p);
627 result = -EINVAL; 631 result = -EINVAL;
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 2fb5e53e927f..33c0a70f6b15 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -30,6 +30,7 @@
30#define IMA_ACTION_FLAGS 0xff000000 30#define IMA_ACTION_FLAGS 0xff000000
31#define IMA_DIGSIG 0x01000000 31#define IMA_DIGSIG 0x01000000
32#define IMA_DIGSIG_REQUIRED 0x02000000 32#define IMA_DIGSIG_REQUIRED 0x02000000
33#define IMA_PERMIT_DIRECTIO 0x04000000
33 34
34#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \ 35#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
35 IMA_APPRAISE_SUBMASK) 36 IMA_APPRAISE_SUBMASK)
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 80b2aac4f50c..5f20da01fd8d 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -176,20 +176,11 @@ extern int key_task_permission(const key_ref_t key_ref,
176/* 176/*
177 * Check to see whether permission is granted to use a key in the desired way. 177 * Check to see whether permission is granted to use a key in the desired way.
178 */ 178 */
179static inline int key_permission(const key_ref_t key_ref, key_perm_t perm) 179static inline int key_permission(const key_ref_t key_ref, unsigned perm)
180{ 180{
181 return key_task_permission(key_ref, current_cred(), perm); 181 return key_task_permission(key_ref, current_cred(), perm);
182} 182}
183 183
184/* required permissions */
185#define KEY_VIEW 0x01 /* require permission to view attributes */
186#define KEY_READ 0x02 /* require permission to read content */
187#define KEY_WRITE 0x04 /* require permission to update / modify */
188#define KEY_SEARCH 0x08 /* require permission to search (keyring) or find (key) */
189#define KEY_LINK 0x10 /* require permission to link */
190#define KEY_SETATTR 0x20 /* require permission to change attributes */
191#define KEY_ALL 0x3f /* all the above permissions */
192
193/* 184/*
194 * Authorisation record for request_key(). 185 * Authorisation record for request_key().
195 */ 186 */
diff --git a/security/keys/key.c b/security/keys/key.c
index 6e21c11e48bc..2048a110e7f1 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -714,7 +714,7 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
714 int ret; 714 int ret;
715 715
716 /* need write permission on the key to update it */ 716 /* need write permission on the key to update it */
717 ret = key_permission(key_ref, KEY_WRITE); 717 ret = key_permission(key_ref, KEY_NEED_WRITE);
718 if (ret < 0) 718 if (ret < 0)
719 goto error; 719 goto error;
720 720
@@ -838,7 +838,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
838 838
839 /* if we're going to allocate a new key, we're going to have 839 /* if we're going to allocate a new key, we're going to have
840 * to modify the keyring */ 840 * to modify the keyring */
841 ret = key_permission(keyring_ref, KEY_WRITE); 841 ret = key_permission(keyring_ref, KEY_NEED_WRITE);
842 if (ret < 0) { 842 if (ret < 0) {
843 key_ref = ERR_PTR(ret); 843 key_ref = ERR_PTR(ret);
844 goto error_link_end; 844 goto error_link_end;
@@ -928,7 +928,7 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
928 key_check(key); 928 key_check(key);
929 929
930 /* the key must be writable */ 930 /* the key must be writable */
931 ret = key_permission(key_ref, KEY_WRITE); 931 ret = key_permission(key_ref, KEY_NEED_WRITE);
932 if (ret < 0) 932 if (ret < 0)
933 goto error; 933 goto error;
934 934
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index cee72ce64222..cd5bd0cef25d 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -111,7 +111,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
111 } 111 }
112 112
113 /* find the target keyring (which must be writable) */ 113 /* find the target keyring (which must be writable) */
114 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); 114 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
115 if (IS_ERR(keyring_ref)) { 115 if (IS_ERR(keyring_ref)) {
116 ret = PTR_ERR(keyring_ref); 116 ret = PTR_ERR(keyring_ref);
117 goto error3; 117 goto error3;
@@ -195,7 +195,7 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
195 dest_ref = NULL; 195 dest_ref = NULL;
196 if (destringid) { 196 if (destringid) {
197 dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE, 197 dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE,
198 KEY_WRITE); 198 KEY_NEED_WRITE);
199 if (IS_ERR(dest_ref)) { 199 if (IS_ERR(dest_ref)) {
200 ret = PTR_ERR(dest_ref); 200 ret = PTR_ERR(dest_ref);
201 goto error3; 201 goto error3;
@@ -253,7 +253,7 @@ long keyctl_get_keyring_ID(key_serial_t id, int create)
253 long ret; 253 long ret;
254 254
255 lflags = create ? KEY_LOOKUP_CREATE : 0; 255 lflags = create ? KEY_LOOKUP_CREATE : 0;
256 key_ref = lookup_user_key(id, lflags, KEY_SEARCH); 256 key_ref = lookup_user_key(id, lflags, KEY_NEED_SEARCH);
257 if (IS_ERR(key_ref)) { 257 if (IS_ERR(key_ref)) {
258 ret = PTR_ERR(key_ref); 258 ret = PTR_ERR(key_ref);
259 goto error; 259 goto error;
@@ -334,7 +334,7 @@ long keyctl_update_key(key_serial_t id,
334 } 334 }
335 335
336 /* find the target key (which must be writable) */ 336 /* find the target key (which must be writable) */
337 key_ref = lookup_user_key(id, 0, KEY_WRITE); 337 key_ref = lookup_user_key(id, 0, KEY_NEED_WRITE);
338 if (IS_ERR(key_ref)) { 338 if (IS_ERR(key_ref)) {
339 ret = PTR_ERR(key_ref); 339 ret = PTR_ERR(key_ref);
340 goto error2; 340 goto error2;
@@ -365,12 +365,12 @@ long keyctl_revoke_key(key_serial_t id)
365 key_ref_t key_ref; 365 key_ref_t key_ref;
366 long ret; 366 long ret;
367 367
368 key_ref = lookup_user_key(id, 0, KEY_WRITE); 368 key_ref = lookup_user_key(id, 0, KEY_NEED_WRITE);
369 if (IS_ERR(key_ref)) { 369 if (IS_ERR(key_ref)) {
370 ret = PTR_ERR(key_ref); 370 ret = PTR_ERR(key_ref);
371 if (ret != -EACCES) 371 if (ret != -EACCES)
372 goto error; 372 goto error;
373 key_ref = lookup_user_key(id, 0, KEY_SETATTR); 373 key_ref = lookup_user_key(id, 0, KEY_NEED_SETATTR);
374 if (IS_ERR(key_ref)) { 374 if (IS_ERR(key_ref)) {
375 ret = PTR_ERR(key_ref); 375 ret = PTR_ERR(key_ref);
376 goto error; 376 goto error;
@@ -401,7 +401,7 @@ long keyctl_invalidate_key(key_serial_t id)
401 401
402 kenter("%d", id); 402 kenter("%d", id);
403 403
404 key_ref = lookup_user_key(id, 0, KEY_SEARCH); 404 key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH);
405 if (IS_ERR(key_ref)) { 405 if (IS_ERR(key_ref)) {
406 ret = PTR_ERR(key_ref); 406 ret = PTR_ERR(key_ref);
407 goto error; 407 goto error;
@@ -428,7 +428,7 @@ long keyctl_keyring_clear(key_serial_t ringid)
428 key_ref_t keyring_ref; 428 key_ref_t keyring_ref;
429 long ret; 429 long ret;
430 430
431 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); 431 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
432 if (IS_ERR(keyring_ref)) { 432 if (IS_ERR(keyring_ref)) {
433 ret = PTR_ERR(keyring_ref); 433 ret = PTR_ERR(keyring_ref);
434 434
@@ -470,13 +470,13 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
470 key_ref_t keyring_ref, key_ref; 470 key_ref_t keyring_ref, key_ref;
471 long ret; 471 long ret;
472 472
473 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); 473 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
474 if (IS_ERR(keyring_ref)) { 474 if (IS_ERR(keyring_ref)) {
475 ret = PTR_ERR(keyring_ref); 475 ret = PTR_ERR(keyring_ref);
476 goto error; 476 goto error;
477 } 477 }
478 478
479 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE, KEY_LINK); 479 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE, KEY_NEED_LINK);
480 if (IS_ERR(key_ref)) { 480 if (IS_ERR(key_ref)) {
481 ret = PTR_ERR(key_ref); 481 ret = PTR_ERR(key_ref);
482 goto error2; 482 goto error2;
@@ -505,7 +505,7 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
505 key_ref_t keyring_ref, key_ref; 505 key_ref_t keyring_ref, key_ref;
506 long ret; 506 long ret;
507 507
508 keyring_ref = lookup_user_key(ringid, 0, KEY_WRITE); 508 keyring_ref = lookup_user_key(ringid, 0, KEY_NEED_WRITE);
509 if (IS_ERR(keyring_ref)) { 509 if (IS_ERR(keyring_ref)) {
510 ret = PTR_ERR(keyring_ref); 510 ret = PTR_ERR(keyring_ref);
511 goto error; 511 goto error;
@@ -548,7 +548,7 @@ long keyctl_describe_key(key_serial_t keyid,
548 char *tmpbuf; 548 char *tmpbuf;
549 long ret; 549 long ret;
550 550
551 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_VIEW); 551 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_VIEW);
552 if (IS_ERR(key_ref)) { 552 if (IS_ERR(key_ref)) {
553 /* viewing a key under construction is permitted if we have the 553 /* viewing a key under construction is permitted if we have the
554 * authorisation token handy */ 554 * authorisation token handy */
@@ -639,7 +639,7 @@ long keyctl_keyring_search(key_serial_t ringid,
639 } 639 }
640 640
641 /* get the keyring at which to begin the search */ 641 /* get the keyring at which to begin the search */
642 keyring_ref = lookup_user_key(ringid, 0, KEY_SEARCH); 642 keyring_ref = lookup_user_key(ringid, 0, KEY_NEED_SEARCH);
643 if (IS_ERR(keyring_ref)) { 643 if (IS_ERR(keyring_ref)) {
644 ret = PTR_ERR(keyring_ref); 644 ret = PTR_ERR(keyring_ref);
645 goto error2; 645 goto error2;
@@ -649,7 +649,7 @@ long keyctl_keyring_search(key_serial_t ringid,
649 dest_ref = NULL; 649 dest_ref = NULL;
650 if (destringid) { 650 if (destringid) {
651 dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE, 651 dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE,
652 KEY_WRITE); 652 KEY_NEED_WRITE);
653 if (IS_ERR(dest_ref)) { 653 if (IS_ERR(dest_ref)) {
654 ret = PTR_ERR(dest_ref); 654 ret = PTR_ERR(dest_ref);
655 goto error3; 655 goto error3;
@@ -676,7 +676,7 @@ long keyctl_keyring_search(key_serial_t ringid,
676 676
677 /* link the resulting key to the destination keyring if we can */ 677 /* link the resulting key to the destination keyring if we can */
678 if (dest_ref) { 678 if (dest_ref) {
679 ret = key_permission(key_ref, KEY_LINK); 679 ret = key_permission(key_ref, KEY_NEED_LINK);
680 if (ret < 0) 680 if (ret < 0)
681 goto error6; 681 goto error6;
682 682
@@ -727,7 +727,7 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
727 key = key_ref_to_ptr(key_ref); 727 key = key_ref_to_ptr(key_ref);
728 728
729 /* see if we can read it directly */ 729 /* see if we can read it directly */
730 ret = key_permission(key_ref, KEY_READ); 730 ret = key_permission(key_ref, KEY_NEED_READ);
731 if (ret == 0) 731 if (ret == 0)
732 goto can_read_key; 732 goto can_read_key;
733 if (ret != -EACCES) 733 if (ret != -EACCES)
@@ -799,7 +799,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
799 goto error; 799 goto error;
800 800
801 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, 801 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
802 KEY_SETATTR); 802 KEY_NEED_SETATTR);
803 if (IS_ERR(key_ref)) { 803 if (IS_ERR(key_ref)) {
804 ret = PTR_ERR(key_ref); 804 ret = PTR_ERR(key_ref);
805 goto error; 805 goto error;
@@ -905,7 +905,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
905 goto error; 905 goto error;
906 906
907 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, 907 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
908 KEY_SETATTR); 908 KEY_NEED_SETATTR);
909 if (IS_ERR(key_ref)) { 909 if (IS_ERR(key_ref)) {
910 ret = PTR_ERR(key_ref); 910 ret = PTR_ERR(key_ref);
911 goto error; 911 goto error;
@@ -947,7 +947,7 @@ static long get_instantiation_keyring(key_serial_t ringid,
947 947
948 /* if a specific keyring is nominated by ID, then use that */ 948 /* if a specific keyring is nominated by ID, then use that */
949 if (ringid > 0) { 949 if (ringid > 0) {
950 dkref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); 950 dkref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
951 if (IS_ERR(dkref)) 951 if (IS_ERR(dkref))
952 return PTR_ERR(dkref); 952 return PTR_ERR(dkref);
953 *_dest_keyring = key_ref_to_ptr(dkref); 953 *_dest_keyring = key_ref_to_ptr(dkref);
@@ -1315,7 +1315,7 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout)
1315 long ret; 1315 long ret;
1316 1316
1317 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, 1317 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
1318 KEY_SETATTR); 1318 KEY_NEED_SETATTR);
1319 if (IS_ERR(key_ref)) { 1319 if (IS_ERR(key_ref)) {
1320 /* setting the timeout on a key under construction is permitted 1320 /* setting the timeout on a key under construction is permitted
1321 * if we have the authorisation token handy */ 1321 * if we have the authorisation token handy */
@@ -1418,7 +1418,7 @@ long keyctl_get_security(key_serial_t keyid,
1418 char *context; 1418 char *context;
1419 long ret; 1419 long ret;
1420 1420
1421 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_VIEW); 1421 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_VIEW);
1422 if (IS_ERR(key_ref)) { 1422 if (IS_ERR(key_ref)) {
1423 if (PTR_ERR(key_ref) != -EACCES) 1423 if (PTR_ERR(key_ref) != -EACCES)
1424 return PTR_ERR(key_ref); 1424 return PTR_ERR(key_ref);
@@ -1482,7 +1482,7 @@ long keyctl_session_to_parent(void)
1482 struct cred *cred; 1482 struct cred *cred;
1483 int ret; 1483 int ret;
1484 1484
1485 keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_LINK); 1485 keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_NEED_LINK);
1486 if (IS_ERR(keyring_r)) 1486 if (IS_ERR(keyring_r))
1487 return PTR_ERR(keyring_r); 1487 return PTR_ERR(keyring_r);
1488 1488
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 2fb2576dc644..9cf2575f0d97 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -541,7 +541,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
541 /* key must have search permissions */ 541 /* key must have search permissions */
542 if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM) && 542 if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM) &&
543 key_task_permission(make_key_ref(key, ctx->possessed), 543 key_task_permission(make_key_ref(key, ctx->possessed),
544 ctx->cred, KEY_SEARCH) < 0) { 544 ctx->cred, KEY_NEED_SEARCH) < 0) {
545 ctx->result = ERR_PTR(-EACCES); 545 ctx->result = ERR_PTR(-EACCES);
546 kleave(" = %d [!perm]", ctx->skipped_ret); 546 kleave(" = %d [!perm]", ctx->skipped_ret);
547 goto skipped; 547 goto skipped;
@@ -721,7 +721,7 @@ ascend_to_node:
721 /* Search a nested keyring */ 721 /* Search a nested keyring */
722 if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM) && 722 if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM) &&
723 key_task_permission(make_key_ref(key, ctx->possessed), 723 key_task_permission(make_key_ref(key, ctx->possessed),
724 ctx->cred, KEY_SEARCH) < 0) 724 ctx->cred, KEY_NEED_SEARCH) < 0)
725 continue; 725 continue;
726 726
727 /* stack the current position */ 727 /* stack the current position */
@@ -843,7 +843,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
843 return ERR_PTR(-ENOTDIR); 843 return ERR_PTR(-ENOTDIR);
844 844
845 if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM)) { 845 if (!(ctx->flags & KEYRING_SEARCH_NO_CHECK_PERM)) {
846 err = key_task_permission(keyring_ref, ctx->cred, KEY_SEARCH); 846 err = key_task_permission(keyring_ref, ctx->cred, KEY_NEED_SEARCH);
847 if (err < 0) 847 if (err < 0)
848 return ERR_PTR(err); 848 return ERR_PTR(err);
849 } 849 }
@@ -973,7 +973,7 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
973 973
974 if (!skip_perm_check && 974 if (!skip_perm_check &&
975 key_permission(make_key_ref(keyring, 0), 975 key_permission(make_key_ref(keyring, 0),
976 KEY_SEARCH) < 0) 976 KEY_NEED_SEARCH) < 0)
977 continue; 977 continue;
978 978
979 /* we've got a match but we might end up racing with 979 /* we've got a match but we might end up racing with
diff --git a/security/keys/permission.c b/security/keys/permission.c
index efcc0c855a0d..732cc0beffdf 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -28,7 +28,7 @@
28 * permissions bits or the LSM check. 28 * permissions bits or the LSM check.
29 */ 29 */
30int key_task_permission(const key_ref_t key_ref, const struct cred *cred, 30int key_task_permission(const key_ref_t key_ref, const struct cred *cred,
31 key_perm_t perm) 31 unsigned perm)
32{ 32{
33 struct key *key; 33 struct key *key;
34 key_perm_t kperm; 34 key_perm_t kperm;
@@ -68,7 +68,7 @@ use_these_perms:
68 if (is_key_possessed(key_ref)) 68 if (is_key_possessed(key_ref))
69 kperm |= key->perm >> 24; 69 kperm |= key->perm >> 24;
70 70
71 kperm = kperm & perm & KEY_ALL; 71 kperm = kperm & perm & KEY_NEED_ALL;
72 72
73 if (kperm != perm) 73 if (kperm != perm)
74 return -EACCES; 74 return -EACCES;
diff --git a/security/keys/persistent.c b/security/keys/persistent.c
index 0ad3ee283781..c9fae5ea89fe 100644
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -108,7 +108,7 @@ static long key_get_persistent(struct user_namespace *ns, kuid_t uid,
108 return PTR_ERR(persistent_ref); 108 return PTR_ERR(persistent_ref);
109 109
110found: 110found:
111 ret = key_task_permission(persistent_ref, current_cred(), KEY_LINK); 111 ret = key_task_permission(persistent_ref, current_cred(), KEY_NEED_LINK);
112 if (ret == 0) { 112 if (ret == 0) {
113 persistent = key_ref_to_ptr(persistent_ref); 113 persistent = key_ref_to_ptr(persistent_ref);
114 ret = key_link(key_ref_to_ptr(dest_ref), persistent); 114 ret = key_link(key_ref_to_ptr(dest_ref), persistent);
@@ -151,7 +151,7 @@ long keyctl_get_persistent(uid_t _uid, key_serial_t destid)
151 } 151 }
152 152
153 /* There must be a destination keyring */ 153 /* There must be a destination keyring */
154 dest_ref = lookup_user_key(destid, KEY_LOOKUP_CREATE, KEY_WRITE); 154 dest_ref = lookup_user_key(destid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
155 if (IS_ERR(dest_ref)) 155 if (IS_ERR(dest_ref))
156 return PTR_ERR(dest_ref); 156 return PTR_ERR(dest_ref);
157 if (key_ref_to_ptr(dest_ref)->type != &key_type_keyring) { 157 if (key_ref_to_ptr(dest_ref)->type != &key_type_keyring) {
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 88e9a466940f..d3f6f2fd21db 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -218,7 +218,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
218 * - the caller holds a spinlock, and thus the RCU read lock, making our 218 * - the caller holds a spinlock, and thus the RCU read lock, making our
219 * access to __current_cred() safe 219 * access to __current_cred() safe
220 */ 220 */
221 rc = key_task_permission(key_ref, ctx.cred, KEY_VIEW); 221 rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW);
222 if (rc < 0) 222 if (rc < 0)
223 return 0; 223 return 0;
224 224
diff --git a/security/keys/sysctl.c b/security/keys/sysctl.c
index 8c0af08760c8..b68faa1a5cfd 100644
--- a/security/keys/sysctl.c
+++ b/security/keys/sysctl.c
@@ -15,7 +15,7 @@
15 15
16static const int zero, one = 1, max = INT_MAX; 16static const int zero, one = 1, max = INT_MAX;
17 17
18ctl_table key_sysctls[] = { 18struct ctl_table key_sysctls[] = {
19 { 19 {
20 .procname = "maxkeys", 20 .procname = "maxkeys",
21 .data = &key_quota_maxkeys, 21 .data = &key_quota_maxkeys,
diff --git a/security/security.c b/security/security.c
index 8b774f362a3d..31614e9e96e5 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1425,7 +1425,7 @@ void security_key_free(struct key *key)
1425} 1425}
1426 1426
1427int security_key_permission(key_ref_t key_ref, 1427int security_key_permission(key_ref_t key_ref,
1428 const struct cred *cred, key_perm_t perm) 1428 const struct cred *cred, unsigned perm)
1429{ 1429{
1430 return security_ops->key_permission(key_ref, cred, perm); 1430 return security_ops->key_permission(key_ref, cred, perm);
1431} 1431}
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index fc3e6628a864..a18f1fa6440b 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -444,11 +444,15 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
444 avc_dump_query(ab, ad->selinux_audit_data->ssid, 444 avc_dump_query(ab, ad->selinux_audit_data->ssid,
445 ad->selinux_audit_data->tsid, 445 ad->selinux_audit_data->tsid,
446 ad->selinux_audit_data->tclass); 446 ad->selinux_audit_data->tclass);
447 if (ad->selinux_audit_data->denied) {
448 audit_log_format(ab, " permissive=%u",
449 ad->selinux_audit_data->result ? 0 : 1);
450 }
447} 451}
448 452
449/* This is the slow part of avc audit with big stack footprint */ 453/* This is the slow part of avc audit with big stack footprint */
450noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, 454noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
451 u32 requested, u32 audited, u32 denied, 455 u32 requested, u32 audited, u32 denied, int result,
452 struct common_audit_data *a, 456 struct common_audit_data *a,
453 unsigned flags) 457 unsigned flags)
454{ 458{
@@ -477,6 +481,7 @@ noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
477 sad.tsid = tsid; 481 sad.tsid = tsid;
478 sad.audited = audited; 482 sad.audited = audited;
479 sad.denied = denied; 483 sad.denied = denied;
484 sad.result = result;
480 485
481 a->selinux_audit_data = &sad; 486 a->selinux_audit_data = &sad;
482 487
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2c7341dbc5d6..83d06db34d03 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2123,11 +2123,13 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2123 new_tsec->exec_sid = 0; 2123 new_tsec->exec_sid = 0;
2124 2124
2125 /* 2125 /*
2126 * Minimize confusion: if no_new_privs and a transition is 2126 * Minimize confusion: if no_new_privs or nosuid and a
2127 * explicitly requested, then fail the exec. 2127 * transition is explicitly requested, then fail the exec.
2128 */ 2128 */
2129 if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) 2129 if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
2130 return -EPERM; 2130 return -EPERM;
2131 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
2132 return -EACCES;
2131 } else { 2133 } else {
2132 /* Check for a default transition on this program. */ 2134 /* Check for a default transition on this program. */
2133 rc = security_transition_sid(old_tsec->sid, isec->sid, 2135 rc = security_transition_sid(old_tsec->sid, isec->sid,
@@ -2770,6 +2772,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
2770 2772
2771static noinline int audit_inode_permission(struct inode *inode, 2773static noinline int audit_inode_permission(struct inode *inode,
2772 u32 perms, u32 audited, u32 denied, 2774 u32 perms, u32 audited, u32 denied,
2775 int result,
2773 unsigned flags) 2776 unsigned flags)
2774{ 2777{
2775 struct common_audit_data ad; 2778 struct common_audit_data ad;
@@ -2780,7 +2783,7 @@ static noinline int audit_inode_permission(struct inode *inode,
2780 ad.u.inode = inode; 2783 ad.u.inode = inode;
2781 2784
2782 rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms, 2785 rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms,
2783 audited, denied, &ad, flags); 2786 audited, denied, result, &ad, flags);
2784 if (rc) 2787 if (rc)
2785 return rc; 2788 return rc;
2786 return 0; 2789 return 0;
@@ -2822,7 +2825,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
2822 if (likely(!audited)) 2825 if (likely(!audited))
2823 return rc; 2826 return rc;
2824 2827
2825 rc2 = audit_inode_permission(inode, perms, audited, denied, flags); 2828 rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags);
2826 if (rc2) 2829 if (rc2)
2827 return rc2; 2830 return rc2;
2828 return rc; 2831 return rc;
@@ -5722,7 +5725,7 @@ static void selinux_key_free(struct key *k)
5722 5725
5723static int selinux_key_permission(key_ref_t key_ref, 5726static int selinux_key_permission(key_ref_t key_ref,
5724 const struct cred *cred, 5727 const struct cred *cred,
5725 key_perm_t perm) 5728 unsigned perm)
5726{ 5729{
5727 struct key *key; 5730 struct key *key;
5728 struct key_security_struct *ksec; 5731 struct key_security_struct *ksec;
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index f53ee3c58d0f..ddf8eec03f21 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -102,7 +102,7 @@ static inline u32 avc_audit_required(u32 requested,
102} 102}
103 103
104int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, 104int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
105 u32 requested, u32 audited, u32 denied, 105 u32 requested, u32 audited, u32 denied, int result,
106 struct common_audit_data *a, 106 struct common_audit_data *a,
107 unsigned flags); 107 unsigned flags);
108 108
@@ -137,7 +137,7 @@ static inline int avc_audit(u32 ssid, u32 tsid,
137 if (likely(!audited)) 137 if (likely(!audited))
138 return 0; 138 return 0;
139 return slow_avc_audit(ssid, tsid, tclass, 139 return slow_avc_audit(ssid, tsid, tclass,
140 requested, audited, denied, 140 requested, audited, denied, result,
141 a, 0); 141 a, 0);
142} 142}
143 143
diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c
index 933e735bb185..2cc496149842 100644
--- a/security/selinux/ss/hashtab.c
+++ b/security/selinux/ss/hashtab.c
@@ -6,6 +6,7 @@
6#include <linux/kernel.h> 6#include <linux/kernel.h>
7#include <linux/slab.h> 7#include <linux/slab.h>
8#include <linux/errno.h> 8#include <linux/errno.h>
9#include <linux/sched.h>
9#include "hashtab.h" 10#include "hashtab.h"
10 11
11struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), 12struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key),
@@ -40,6 +41,8 @@ int hashtab_insert(struct hashtab *h, void *key, void *datum)
40 u32 hvalue; 41 u32 hvalue;
41 struct hashtab_node *prev, *cur, *newnode; 42 struct hashtab_node *prev, *cur, *newnode;
42 43
44 cond_resched();
45
43 if (!h || h->nel == HASHTAB_MAX_NODES) 46 if (!h || h->nel == HASHTAB_MAX_NODES)
44 return -EINVAL; 47 return -EINVAL;
45 48
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index c85bc1ec040c..d307b37ddc2b 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -492,6 +492,8 @@ int mls_convert_context(struct policydb *oldp,
492 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); 492 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
493 if (rc) 493 if (rc)
494 return rc; 494 return rc;
495
496 cond_resched();
495 } 497 }
496 ebitmap_destroy(&c->range.level[l].cat); 498 ebitmap_destroy(&c->range.level[l].cat);
497 c->range.level[l].cat = bitmap; 499 c->range.level[l].cat = bitmap;
diff --git a/security/smack/smack.h b/security/smack/smack.h
index d072fd32212d..020307ef0972 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -80,8 +80,8 @@ struct superblock_smack {
80 80
81struct socket_smack { 81struct socket_smack {
82 struct smack_known *smk_out; /* outbound label */ 82 struct smack_known *smk_out; /* outbound label */
83 char *smk_in; /* inbound label */ 83 struct smack_known *smk_in; /* inbound label */
84 char *smk_packet; /* TCP peer label */ 84 struct smack_known *smk_packet; /* TCP peer label */
85}; 85};
86 86
87/* 87/*
@@ -133,7 +133,7 @@ struct smk_port_label {
133 struct list_head list; 133 struct list_head list;
134 struct sock *smk_sock; /* socket initialized on */ 134 struct sock *smk_sock; /* socket initialized on */
135 unsigned short smk_port; /* the port number */ 135 unsigned short smk_port; /* the port number */
136 char *smk_in; /* incoming label */ 136 struct smack_known *smk_in; /* inbound label */
137 struct smack_known *smk_out; /* outgoing label */ 137 struct smack_known *smk_out; /* outgoing label */
138}; 138};
139 139
@@ -177,6 +177,14 @@ struct smk_port_label {
177#define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */ 177#define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */
178 178
179/* 179/*
180 * Ptrace rules
181 */
182#define SMACK_PTRACE_DEFAULT 0
183#define SMACK_PTRACE_EXACT 1
184#define SMACK_PTRACE_DRACONIAN 2
185#define SMACK_PTRACE_MAX SMACK_PTRACE_DRACONIAN
186
187/*
180 * Flags for untraditional access modes. 188 * Flags for untraditional access modes.
181 * It shouldn't be necessary to avoid conflicts with definitions 189 * It shouldn't be necessary to avoid conflicts with definitions
182 * in fs.h, but do so anyway. 190 * in fs.h, but do so anyway.
@@ -225,6 +233,7 @@ struct inode_smack *new_inode_smack(char *);
225 */ 233 */
226int smk_access_entry(char *, char *, struct list_head *); 234int smk_access_entry(char *, char *, struct list_head *);
227int smk_access(struct smack_known *, char *, int, struct smk_audit_info *); 235int smk_access(struct smack_known *, char *, int, struct smk_audit_info *);
236int smk_tskacc(struct task_smack *, char *, u32, struct smk_audit_info *);
228int smk_curacc(char *, u32, struct smk_audit_info *); 237int smk_curacc(char *, u32, struct smk_audit_info *);
229struct smack_known *smack_from_secid(const u32); 238struct smack_known *smack_from_secid(const u32);
230char *smk_parse_smack(const char *string, int len); 239char *smk_parse_smack(const char *string, int len);
@@ -244,6 +253,7 @@ extern struct smack_known *smack_net_ambient;
244extern struct smack_known *smack_onlycap; 253extern struct smack_known *smack_onlycap;
245extern struct smack_known *smack_syslog_label; 254extern struct smack_known *smack_syslog_label;
246extern const char *smack_cipso_option; 255extern const char *smack_cipso_option;
256extern int smack_ptrace_rule;
247 257
248extern struct smack_known smack_known_floor; 258extern struct smack_known smack_known_floor;
249extern struct smack_known smack_known_hat; 259extern struct smack_known smack_known_hat;
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 14293cd9b1e5..c062e9467b62 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -192,20 +192,21 @@ out_audit:
192} 192}
193 193
194/** 194/**
195 * smk_curacc - determine if current has a specific access to an object 195 * smk_tskacc - determine if a task has a specific access to an object
196 * @tsp: a pointer to the subject task
196 * @obj_label: a pointer to the object's Smack label 197 * @obj_label: a pointer to the object's Smack label
197 * @mode: the access requested, in "MAY" format 198 * @mode: the access requested, in "MAY" format
198 * @a : common audit data 199 * @a : common audit data
199 * 200 *
200 * This function checks the current subject label/object label pair 201 * This function checks the subject task's label/object label pair
201 * in the access rule list and returns 0 if the access is permitted, 202 * in the access rule list and returns 0 if the access is permitted,
202 * non zero otherwise. It allows that current may have the capability 203 * non zero otherwise. It allows that the task may have the capability
203 * to override the rules. 204 * to override the rules.
204 */ 205 */
205int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) 206int smk_tskacc(struct task_smack *subject, char *obj_label,
207 u32 mode, struct smk_audit_info *a)
206{ 208{
207 struct task_smack *tsp = current_security(); 209 struct smack_known *skp = smk_of_task(subject);
208 struct smack_known *skp = smk_of_task(tsp);
209 int may; 210 int may;
210 int rc; 211 int rc;
211 212
@@ -219,7 +220,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
219 * it can further restrict access. 220 * it can further restrict access.
220 */ 221 */
221 may = smk_access_entry(skp->smk_known, obj_label, 222 may = smk_access_entry(skp->smk_known, obj_label,
222 &tsp->smk_rules); 223 &subject->smk_rules);
223 if (may < 0) 224 if (may < 0)
224 goto out_audit; 225 goto out_audit;
225 if ((mode & may) == mode) 226 if ((mode & may) == mode)
@@ -241,6 +242,24 @@ out_audit:
241 return rc; 242 return rc;
242} 243}
243 244
245/**
246 * smk_curacc - determine if current has a specific access to an object
247 * @obj_label: a pointer to the object's Smack label
248 * @mode: the access requested, in "MAY" format
249 * @a : common audit data
250 *
251 * This function checks the current subject label/object label pair
252 * in the access rule list and returns 0 if the access is permitted,
253 * non zero otherwise. It allows that current may have the capability
254 * to override the rules.
255 */
256int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
257{
258 struct task_smack *tsp = current_security();
259
260 return smk_tskacc(tsp, obj_label, mode, a);
261}
262
244#ifdef CONFIG_AUDIT 263#ifdef CONFIG_AUDIT
245/** 264/**
246 * smack_str_from_perm : helper to transalate an int to a 265 * smack_str_from_perm : helper to transalate an int to a
@@ -285,7 +304,10 @@ static void smack_log_callback(struct audit_buffer *ab, void *a)
285 audit_log_untrustedstring(ab, sad->subject); 304 audit_log_untrustedstring(ab, sad->subject);
286 audit_log_format(ab, " object="); 305 audit_log_format(ab, " object=");
287 audit_log_untrustedstring(ab, sad->object); 306 audit_log_untrustedstring(ab, sad->object);
288 audit_log_format(ab, " requested=%s", sad->request); 307 if (sad->request[0] == '\0')
308 audit_log_format(ab, " labels_differ");
309 else
310 audit_log_format(ab, " requested=%s", sad->request);
289} 311}
290 312
291/** 313/**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 14f52be78c75..f2c30801ce41 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -157,6 +157,74 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
157 return rc; 157 return rc;
158} 158}
159 159
160/**
161 * smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_*
162 * @mode - input mode in form of PTRACE_MODE_*
163 *
164 * Returns a converted MAY_* mode usable by smack rules
165 */
166static inline unsigned int smk_ptrace_mode(unsigned int mode)
167{
168 switch (mode) {
169 case PTRACE_MODE_READ:
170 return MAY_READ;
171 case PTRACE_MODE_ATTACH:
172 return MAY_READWRITE;
173 }
174
175 return 0;
176}
177
178/**
179 * smk_ptrace_rule_check - helper for ptrace access
180 * @tracer: tracer process
181 * @tracee_label: label of the process that's about to be traced,
182 * the pointer must originate from smack structures
183 * @mode: ptrace attachment mode (PTRACE_MODE_*)
184 * @func: name of the function that called us, used for audit
185 *
186 * Returns 0 on access granted, -error on error
187 */
188static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label,
189 unsigned int mode, const char *func)
190{
191 int rc;
192 struct smk_audit_info ad, *saip = NULL;
193 struct task_smack *tsp;
194 struct smack_known *skp;
195
196 if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
197 smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK);
198 smk_ad_setfield_u_tsk(&ad, tracer);
199 saip = &ad;
200 }
201
202 tsp = task_security(tracer);
203 skp = smk_of_task(tsp);
204
205 if ((mode & PTRACE_MODE_ATTACH) &&
206 (smack_ptrace_rule == SMACK_PTRACE_EXACT ||
207 smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)) {
208 if (skp->smk_known == tracee_label)
209 rc = 0;
210 else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)
211 rc = -EACCES;
212 else if (capable(CAP_SYS_PTRACE))
213 rc = 0;
214 else
215 rc = -EACCES;
216
217 if (saip)
218 smack_log(skp->smk_known, tracee_label, 0, rc, saip);
219
220 return rc;
221 }
222
223 /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */
224 rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip);
225 return rc;
226}
227
160/* 228/*
161 * LSM hooks. 229 * LSM hooks.
162 * We he, that is fun! 230 * We he, that is fun!
@@ -165,16 +233,15 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
165/** 233/**
166 * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH 234 * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH
167 * @ctp: child task pointer 235 * @ctp: child task pointer
168 * @mode: ptrace attachment mode 236 * @mode: ptrace attachment mode (PTRACE_MODE_*)
169 * 237 *
170 * Returns 0 if access is OK, an error code otherwise 238 * Returns 0 if access is OK, an error code otherwise
171 * 239 *
172 * Do the capability checks, and require read and write. 240 * Do the capability checks.
173 */ 241 */
174static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) 242static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
175{ 243{
176 int rc; 244 int rc;
177 struct smk_audit_info ad;
178 struct smack_known *skp; 245 struct smack_known *skp;
179 246
180 rc = cap_ptrace_access_check(ctp, mode); 247 rc = cap_ptrace_access_check(ctp, mode);
@@ -182,10 +249,8 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
182 return rc; 249 return rc;
183 250
184 skp = smk_of_task(task_security(ctp)); 251 skp = smk_of_task(task_security(ctp));
185 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
186 smk_ad_setfield_u_tsk(&ad, ctp);
187 252
188 rc = smk_curacc(skp->smk_known, mode, &ad); 253 rc = smk_ptrace_rule_check(current, skp->smk_known, mode, __func__);
189 return rc; 254 return rc;
190} 255}
191 256
@@ -195,23 +260,21 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
195 * 260 *
196 * Returns 0 if access is OK, an error code otherwise 261 * Returns 0 if access is OK, an error code otherwise
197 * 262 *
198 * Do the capability checks, and require read and write. 263 * Do the capability checks, and require PTRACE_MODE_ATTACH.
199 */ 264 */
200static int smack_ptrace_traceme(struct task_struct *ptp) 265static int smack_ptrace_traceme(struct task_struct *ptp)
201{ 266{
202 int rc; 267 int rc;
203 struct smk_audit_info ad;
204 struct smack_known *skp; 268 struct smack_known *skp;
205 269
206 rc = cap_ptrace_traceme(ptp); 270 rc = cap_ptrace_traceme(ptp);
207 if (rc != 0) 271 if (rc != 0)
208 return rc; 272 return rc;
209 273
210 skp = smk_of_task(task_security(ptp)); 274 skp = smk_of_task(current_security());
211 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
212 smk_ad_setfield_u_tsk(&ad, ptp);
213 275
214 rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad); 276 rc = smk_ptrace_rule_check(ptp, skp->smk_known,
277 PTRACE_MODE_ATTACH, __func__);
215 return rc; 278 return rc;
216} 279}
217 280
@@ -413,9 +476,11 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
413 * Initialize the root inode. 476 * Initialize the root inode.
414 */ 477 */
415 isp = inode->i_security; 478 isp = inode->i_security;
416 if (inode->i_security == NULL) { 479 if (isp == NULL) {
417 inode->i_security = new_inode_smack(sp->smk_root); 480 isp = new_inode_smack(sp->smk_root);
418 isp = inode->i_security; 481 if (isp == NULL)
482 return -ENOMEM;
483 inode->i_security = isp;
419 } else 484 } else
420 isp->smk_inode = sp->smk_root; 485 isp->smk_inode = sp->smk_root;
421 486
@@ -453,7 +518,7 @@ static int smack_sb_statfs(struct dentry *dentry)
453 * smack_bprm_set_creds - set creds for exec 518 * smack_bprm_set_creds - set creds for exec
454 * @bprm: the exec information 519 * @bprm: the exec information
455 * 520 *
456 * Returns 0 if it gets a blob, -ENOMEM otherwise 521 * Returns 0 if it gets a blob, -EPERM if exec forbidden and -ENOMEM otherwise
457 */ 522 */
458static int smack_bprm_set_creds(struct linux_binprm *bprm) 523static int smack_bprm_set_creds(struct linux_binprm *bprm)
459{ 524{
@@ -473,7 +538,22 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm)
473 if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task) 538 if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
474 return 0; 539 return 0;
475 540
476 if (bprm->unsafe) 541 if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
542 struct task_struct *tracer;
543 rc = 0;
544
545 rcu_read_lock();
546 tracer = ptrace_parent(current);
547 if (likely(tracer != NULL))
548 rc = smk_ptrace_rule_check(tracer,
549 isp->smk_task->smk_known,
550 PTRACE_MODE_ATTACH,
551 __func__);
552 rcu_read_unlock();
553
554 if (rc != 0)
555 return rc;
556 } else if (bprm->unsafe)
477 return -EPERM; 557 return -EPERM;
478 558
479 bsp->smk_task = isp->smk_task; 559 bsp->smk_task = isp->smk_task;
@@ -880,18 +960,20 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
880 return; 960 return;
881 } 961 }
882 962
883 skp = smk_import_entry(value, size);
884 if (strcmp(name, XATTR_NAME_SMACK) == 0) { 963 if (strcmp(name, XATTR_NAME_SMACK) == 0) {
964 skp = smk_import_entry(value, size);
885 if (skp != NULL) 965 if (skp != NULL)
886 isp->smk_inode = skp->smk_known; 966 isp->smk_inode = skp->smk_known;
887 else 967 else
888 isp->smk_inode = smack_known_invalid.smk_known; 968 isp->smk_inode = smack_known_invalid.smk_known;
889 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { 969 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
970 skp = smk_import_entry(value, size);
890 if (skp != NULL) 971 if (skp != NULL)
891 isp->smk_task = skp; 972 isp->smk_task = skp;
892 else 973 else
893 isp->smk_task = &smack_known_invalid; 974 isp->smk_task = &smack_known_invalid;
894 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { 975 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
976 skp = smk_import_entry(value, size);
895 if (skp != NULL) 977 if (skp != NULL)
896 isp->smk_mmap = skp; 978 isp->smk_mmap = skp;
897 else 979 else
@@ -938,24 +1020,37 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
938 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || 1020 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
939 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || 1021 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
940 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || 1022 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
941 strcmp(name, XATTR_NAME_SMACKMMAP)) { 1023 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
942 if (!smack_privileged(CAP_MAC_ADMIN)) 1024 if (!smack_privileged(CAP_MAC_ADMIN))
943 rc = -EPERM; 1025 rc = -EPERM;
944 } else 1026 } else
945 rc = cap_inode_removexattr(dentry, name); 1027 rc = cap_inode_removexattr(dentry, name);
946 1028
1029 if (rc != 0)
1030 return rc;
1031
947 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); 1032 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
948 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 1033 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
949 if (rc == 0)
950 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
951 1034
952 if (rc == 0) { 1035 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
953 isp = dentry->d_inode->i_security; 1036 if (rc != 0)
1037 return rc;
1038
1039 isp = dentry->d_inode->i_security;
1040 /*
1041 * Don't do anything special for these.
1042 * XATTR_NAME_SMACKIPIN
1043 * XATTR_NAME_SMACKIPOUT
1044 * XATTR_NAME_SMACKEXEC
1045 */
1046 if (strcmp(name, XATTR_NAME_SMACK) == 0)
954 isp->smk_task = NULL; 1047 isp->smk_task = NULL;
1048 else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0)
955 isp->smk_mmap = NULL; 1049 isp->smk_mmap = NULL;
956 } 1050 else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
1051 isp->smk_flags &= ~SMK_INODE_TRANSMUTE;
957 1052
958 return rc; 1053 return 0;
959} 1054}
960 1055
961/** 1056/**
@@ -1000,7 +1095,7 @@ static int smack_inode_getsecurity(const struct inode *inode,
1000 ssp = sock->sk->sk_security; 1095 ssp = sock->sk->sk_security;
1001 1096
1002 if (strcmp(name, XATTR_SMACK_IPIN) == 0) 1097 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
1003 isp = ssp->smk_in; 1098 isp = ssp->smk_in->smk_known;
1004 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) 1099 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
1005 isp = ssp->smk_out->smk_known; 1100 isp = ssp->smk_out->smk_known;
1006 else 1101 else
@@ -1367,19 +1462,32 @@ static int smack_file_receive(struct file *file)
1367/** 1462/**
1368 * smack_file_open - Smack dentry open processing 1463 * smack_file_open - Smack dentry open processing
1369 * @file: the object 1464 * @file: the object
1370 * @cred: unused 1465 * @cred: task credential
1371 * 1466 *
1372 * Set the security blob in the file structure. 1467 * Set the security blob in the file structure.
1468 * Allow the open only if the task has read access. There are
1469 * many read operations (e.g. fstat) that you can do with an
1470 * fd even if you have the file open write-only.
1373 * 1471 *
1374 * Returns 0 1472 * Returns 0
1375 */ 1473 */
1376static int smack_file_open(struct file *file, const struct cred *cred) 1474static int smack_file_open(struct file *file, const struct cred *cred)
1377{ 1475{
1476 struct task_smack *tsp = cred->security;
1378 struct inode_smack *isp = file_inode(file)->i_security; 1477 struct inode_smack *isp = file_inode(file)->i_security;
1478 struct smk_audit_info ad;
1479 int rc;
1379 1480
1380 file->f_security = isp->smk_inode; 1481 if (smack_privileged(CAP_MAC_OVERRIDE))
1482 return 0;
1381 1483
1382 return 0; 1484 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1485 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1486 rc = smk_access(tsp->smk_task, isp->smk_inode, MAY_READ, &ad);
1487 if (rc == 0)
1488 file->f_security = isp->smk_inode;
1489
1490 return rc;
1383} 1491}
1384 1492
1385/* 1493/*
@@ -1764,7 +1872,7 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1764 if (ssp == NULL) 1872 if (ssp == NULL)
1765 return -ENOMEM; 1873 return -ENOMEM;
1766 1874
1767 ssp->smk_in = skp->smk_known; 1875 ssp->smk_in = skp;
1768 ssp->smk_out = skp; 1876 ssp->smk_out = skp;
1769 ssp->smk_packet = NULL; 1877 ssp->smk_packet = NULL;
1770 1878
@@ -2004,7 +2112,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
2004 2112
2005 if (act == SMK_RECEIVING) { 2113 if (act == SMK_RECEIVING) {
2006 skp = smack_net_ambient; 2114 skp = smack_net_ambient;
2007 object = ssp->smk_in; 2115 object = ssp->smk_in->smk_known;
2008 } else { 2116 } else {
2009 skp = ssp->smk_out; 2117 skp = ssp->smk_out;
2010 object = smack_net_ambient->smk_known; 2118 object = smack_net_ambient->smk_known;
@@ -2034,9 +2142,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
2034 list_for_each_entry(spp, &smk_ipv6_port_list, list) { 2142 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
2035 if (spp->smk_port != port) 2143 if (spp->smk_port != port)
2036 continue; 2144 continue;
2037 object = spp->smk_in; 2145 object = spp->smk_in->smk_known;
2038 if (act == SMK_CONNECTING) 2146 if (act == SMK_CONNECTING)
2039 ssp->smk_packet = spp->smk_out->smk_known; 2147 ssp->smk_packet = spp->smk_out;
2040 break; 2148 break;
2041 } 2149 }
2042 2150
@@ -2076,7 +2184,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
2076 int rc = 0; 2184 int rc = 0;
2077 2185
2078 if (value == NULL || size > SMK_LONGLABEL || size == 0) 2186 if (value == NULL || size > SMK_LONGLABEL || size == 0)
2079 return -EACCES; 2187 return -EINVAL;
2080 2188
2081 skp = smk_import_entry(value, size); 2189 skp = smk_import_entry(value, size);
2082 if (skp == NULL) 2190 if (skp == NULL)
@@ -2100,7 +2208,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
2100 ssp = sock->sk->sk_security; 2208 ssp = sock->sk->sk_security;
2101 2209
2102 if (strcmp(name, XATTR_SMACK_IPIN) == 0) 2210 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
2103 ssp->smk_in = skp->smk_known; 2211 ssp->smk_in = skp;
2104 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 2212 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
2105 ssp->smk_out = skp; 2213 ssp->smk_out = skp;
2106 if (sock->sk->sk_family == PF_INET) { 2214 if (sock->sk->sk_family == PF_INET) {
@@ -2713,6 +2821,15 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2713 * of the superblock. 2821 * of the superblock.
2714 */ 2822 */
2715 if (opt_dentry->d_parent == opt_dentry) { 2823 if (opt_dentry->d_parent == opt_dentry) {
2824 if (sbp->s_magic == CGROUP_SUPER_MAGIC) {
2825 /*
2826 * The cgroup filesystem is never mounted,
2827 * so there's no opportunity to set the mount
2828 * options.
2829 */
2830 sbsp->smk_root = smack_known_star.smk_known;
2831 sbsp->smk_default = smack_known_star.smk_known;
2832 }
2716 isp->smk_inode = sbsp->smk_root; 2833 isp->smk_inode = sbsp->smk_root;
2717 isp->smk_flags |= SMK_INODE_INSTANT; 2834 isp->smk_flags |= SMK_INODE_INSTANT;
2718 goto unlockandout; 2835 goto unlockandout;
@@ -2726,16 +2843,20 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2726 */ 2843 */
2727 switch (sbp->s_magic) { 2844 switch (sbp->s_magic) {
2728 case SMACK_MAGIC: 2845 case SMACK_MAGIC:
2846 case PIPEFS_MAGIC:
2847 case SOCKFS_MAGIC:
2848 case CGROUP_SUPER_MAGIC:
2729 /* 2849 /*
2730 * Casey says that it's a little embarrassing 2850 * Casey says that it's a little embarrassing
2731 * that the smack file system doesn't do 2851 * that the smack file system doesn't do
2732 * extended attributes. 2852 * extended attributes.
2733 */ 2853 *
2734 final = smack_known_star.smk_known;
2735 break;
2736 case PIPEFS_MAGIC:
2737 /*
2738 * Casey says pipes are easy (?) 2854 * Casey says pipes are easy (?)
2855 *
2856 * Socket access is controlled by the socket
2857 * structures associated with the task involved.
2858 *
2859 * Cgroupfs is special
2739 */ 2860 */
2740 final = smack_known_star.smk_known; 2861 final = smack_known_star.smk_known;
2741 break; 2862 break;
@@ -2747,13 +2868,6 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2747 */ 2868 */
2748 final = ckp->smk_known; 2869 final = ckp->smk_known;
2749 break; 2870 break;
2750 case SOCKFS_MAGIC:
2751 /*
2752 * Socket access is controlled by the socket
2753 * structures associated with the task involved.
2754 */
2755 final = smack_known_star.smk_known;
2756 break;
2757 case PROC_SUPER_MAGIC: 2871 case PROC_SUPER_MAGIC:
2758 /* 2872 /*
2759 * Casey says procfs appears not to care. 2873 * Casey says procfs appears not to care.
@@ -2959,30 +3073,34 @@ static int smack_unix_stream_connect(struct sock *sock,
2959 struct sock *other, struct sock *newsk) 3073 struct sock *other, struct sock *newsk)
2960{ 3074{
2961 struct smack_known *skp; 3075 struct smack_known *skp;
3076 struct smack_known *okp;
2962 struct socket_smack *ssp = sock->sk_security; 3077 struct socket_smack *ssp = sock->sk_security;
2963 struct socket_smack *osp = other->sk_security; 3078 struct socket_smack *osp = other->sk_security;
2964 struct socket_smack *nsp = newsk->sk_security; 3079 struct socket_smack *nsp = newsk->sk_security;
2965 struct smk_audit_info ad; 3080 struct smk_audit_info ad;
2966 int rc = 0; 3081 int rc = 0;
2967
2968#ifdef CONFIG_AUDIT 3082#ifdef CONFIG_AUDIT
2969 struct lsm_network_audit net; 3083 struct lsm_network_audit net;
2970
2971 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2972 smk_ad_setfield_u_net_sk(&ad, other);
2973#endif 3084#endif
2974 3085
2975 if (!smack_privileged(CAP_MAC_OVERRIDE)) { 3086 if (!smack_privileged(CAP_MAC_OVERRIDE)) {
2976 skp = ssp->smk_out; 3087 skp = ssp->smk_out;
2977 rc = smk_access(skp, osp->smk_in, MAY_WRITE, &ad); 3088 okp = osp->smk_out;
3089#ifdef CONFIG_AUDIT
3090 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
3091 smk_ad_setfield_u_net_sk(&ad, other);
3092#endif
3093 rc = smk_access(skp, okp->smk_known, MAY_WRITE, &ad);
3094 if (rc == 0)
3095 rc = smk_access(okp, okp->smk_known, MAY_WRITE, NULL);
2978 } 3096 }
2979 3097
2980 /* 3098 /*
2981 * Cross reference the peer labels for SO_PEERSEC. 3099 * Cross reference the peer labels for SO_PEERSEC.
2982 */ 3100 */
2983 if (rc == 0) { 3101 if (rc == 0) {
2984 nsp->smk_packet = ssp->smk_out->smk_known; 3102 nsp->smk_packet = ssp->smk_out;
2985 ssp->smk_packet = osp->smk_out->smk_known; 3103 ssp->smk_packet = osp->smk_out;
2986 } 3104 }
2987 3105
2988 return rc; 3106 return rc;
@@ -3014,7 +3132,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
3014 return 0; 3132 return 0;
3015 3133
3016 skp = ssp->smk_out; 3134 skp = ssp->smk_out;
3017 return smk_access(skp, osp->smk_in, MAY_WRITE, &ad); 3135 return smk_access(skp, osp->smk_in->smk_known, MAY_WRITE, &ad);
3018} 3136}
3019 3137
3020/** 3138/**
@@ -3109,7 +3227,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3109 if (found) 3227 if (found)
3110 return skp; 3228 return skp;
3111 3229
3112 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known) 3230 if (ssp != NULL && ssp->smk_in == &smack_known_star)
3113 return &smack_known_web; 3231 return &smack_known_web;
3114 return &smack_known_star; 3232 return &smack_known_star;
3115 } 3233 }
@@ -3228,7 +3346,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3228 * This is the simplist possible security model 3346 * This is the simplist possible security model
3229 * for networking. 3347 * for networking.
3230 */ 3348 */
3231 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); 3349 rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad);
3232 if (rc != 0) 3350 if (rc != 0)
3233 netlbl_skbuff_err(skb, rc, 0); 3351 netlbl_skbuff_err(skb, rc, 0);
3234 break; 3352 break;
@@ -3263,7 +3381,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
3263 3381
3264 ssp = sock->sk->sk_security; 3382 ssp = sock->sk->sk_security;
3265 if (ssp->smk_packet != NULL) { 3383 if (ssp->smk_packet != NULL) {
3266 rcp = ssp->smk_packet; 3384 rcp = ssp->smk_packet->smk_known;
3267 slen = strlen(rcp) + 1; 3385 slen = strlen(rcp) + 1;
3268 } 3386 }
3269 3387
@@ -3348,7 +3466,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
3348 return; 3466 return;
3349 3467
3350 ssp = sk->sk_security; 3468 ssp = sk->sk_security;
3351 ssp->smk_in = skp->smk_known; 3469 ssp->smk_in = skp;
3352 ssp->smk_out = skp; 3470 ssp->smk_out = skp;
3353 /* cssp->smk_packet is already set in smack_inet_csk_clone() */ 3471 /* cssp->smk_packet is already set in smack_inet_csk_clone() */
3354} 3472}
@@ -3408,7 +3526,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3408 * Receiving a packet requires that the other end be able to write 3526 * Receiving a packet requires that the other end be able to write
3409 * here. Read access is not required. 3527 * here. Read access is not required.
3410 */ 3528 */
3411 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); 3529 rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad);
3412 if (rc != 0) 3530 if (rc != 0)
3413 return rc; 3531 return rc;
3414 3532
@@ -3452,7 +3570,7 @@ static void smack_inet_csk_clone(struct sock *sk,
3452 3570
3453 if (req->peer_secid != 0) { 3571 if (req->peer_secid != 0) {
3454 skp = smack_from_secid(req->peer_secid); 3572 skp = smack_from_secid(req->peer_secid);
3455 ssp->smk_packet = skp->smk_known; 3573 ssp->smk_packet = skp;
3456 } else 3574 } else
3457 ssp->smk_packet = NULL; 3575 ssp->smk_packet = NULL;
3458} 3576}
@@ -3506,11 +3624,12 @@ static void smack_key_free(struct key *key)
3506 * an error code otherwise 3624 * an error code otherwise
3507 */ 3625 */
3508static int smack_key_permission(key_ref_t key_ref, 3626static int smack_key_permission(key_ref_t key_ref,
3509 const struct cred *cred, key_perm_t perm) 3627 const struct cred *cred, unsigned perm)
3510{ 3628{
3511 struct key *keyp; 3629 struct key *keyp;
3512 struct smk_audit_info ad; 3630 struct smk_audit_info ad;
3513 struct smack_known *tkp = smk_of_task(cred->security); 3631 struct smack_known *tkp = smk_of_task(cred->security);
3632 int request = 0;
3514 3633
3515 keyp = key_ref_to_ptr(key_ref); 3634 keyp = key_ref_to_ptr(key_ref);
3516 if (keyp == NULL) 3635 if (keyp == NULL)
@@ -3531,7 +3650,11 @@ static int smack_key_permission(key_ref_t key_ref,
3531 ad.a.u.key_struct.key = keyp->serial; 3650 ad.a.u.key_struct.key = keyp->serial;
3532 ad.a.u.key_struct.key_desc = keyp->description; 3651 ad.a.u.key_struct.key_desc = keyp->description;
3533#endif 3652#endif
3534 return smk_access(tkp, keyp->security, MAY_READWRITE, &ad); 3653 if (perm & KEY_NEED_READ)
3654 request = MAY_READ;
3655 if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR))
3656 request = MAY_WRITE;
3657 return smk_access(tkp, keyp->security, request, &ad);
3535} 3658}
3536#endif /* CONFIG_KEYS */ 3659#endif /* CONFIG_KEYS */
3537 3660
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 3198cfe1dcc6..32b248820840 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -53,6 +53,7 @@ enum smk_inos {
53 SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */ 53 SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */
54 SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ 54 SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */
55 SMK_SYSLOG = 20, /* change syslog label) */ 55 SMK_SYSLOG = 20, /* change syslog label) */
56 SMK_PTRACE = 21, /* set ptrace rule */
56}; 57};
57 58
58/* 59/*
@@ -101,6 +102,15 @@ struct smack_known *smack_onlycap;
101struct smack_known *smack_syslog_label; 102struct smack_known *smack_syslog_label;
102 103
103/* 104/*
105 * Ptrace current rule
106 * SMACK_PTRACE_DEFAULT regular smack ptrace rules (/proc based)
107 * SMACK_PTRACE_EXACT labels must match, but can be overriden with
108 * CAP_SYS_PTRACE
109 * SMACK_PTRACE_DRACONIAN lables must match, CAP_SYS_PTRACE has no effect
110 */
111int smack_ptrace_rule = SMACK_PTRACE_DEFAULT;
112
113/*
104 * Certain IP addresses may be designated as single label hosts. 114 * Certain IP addresses may be designated as single label hosts.
105 * Packets are sent there unlabeled, but only from tasks that 115 * Packets are sent there unlabeled, but only from tasks that
106 * can write to the specified label. 116 * can write to the specified label.
@@ -1183,7 +1193,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1183 1193
1184 data[count] = '\0'; 1194 data[count] = '\0';
1185 1195
1186 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%d %s", 1196 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s",
1187 &host[0], &host[1], &host[2], &host[3], &m, smack); 1197 &host[0], &host[1], &host[2], &host[3], &m, smack);
1188 if (rc != 6) { 1198 if (rc != 6) {
1189 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", 1199 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s",
@@ -2244,6 +2254,68 @@ static const struct file_operations smk_syslog_ops = {
2244 2254
2245 2255
2246/** 2256/**
2257 * smk_read_ptrace - read() for /smack/ptrace
2258 * @filp: file pointer, not actually used
2259 * @buf: where to put the result
2260 * @count: maximum to send along
2261 * @ppos: where to start
2262 *
2263 * Returns number of bytes read or error code, as appropriate
2264 */
2265static ssize_t smk_read_ptrace(struct file *filp, char __user *buf,
2266 size_t count, loff_t *ppos)
2267{
2268 char temp[32];
2269 ssize_t rc;
2270
2271 if (*ppos != 0)
2272 return 0;
2273
2274 sprintf(temp, "%d\n", smack_ptrace_rule);
2275 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
2276 return rc;
2277}
2278
2279/**
2280 * smk_write_ptrace - write() for /smack/ptrace
2281 * @file: file pointer
2282 * @buf: data from user space
2283 * @count: bytes sent
2284 * @ppos: where to start - must be 0
2285 */
2286static ssize_t smk_write_ptrace(struct file *file, const char __user *buf,
2287 size_t count, loff_t *ppos)
2288{
2289 char temp[32];
2290 int i;
2291
2292 if (!smack_privileged(CAP_MAC_ADMIN))
2293 return -EPERM;
2294
2295 if (*ppos != 0 || count >= sizeof(temp) || count == 0)
2296 return -EINVAL;
2297
2298 if (copy_from_user(temp, buf, count) != 0)
2299 return -EFAULT;
2300
2301 temp[count] = '\0';
2302
2303 if (sscanf(temp, "%d", &i) != 1)
2304 return -EINVAL;
2305 if (i < SMACK_PTRACE_DEFAULT || i > SMACK_PTRACE_MAX)
2306 return -EINVAL;
2307 smack_ptrace_rule = i;
2308
2309 return count;
2310}
2311
2312static const struct file_operations smk_ptrace_ops = {
2313 .write = smk_write_ptrace,
2314 .read = smk_read_ptrace,
2315 .llseek = default_llseek,
2316};
2317
2318/**
2247 * smk_fill_super - fill the smackfs superblock 2319 * smk_fill_super - fill the smackfs superblock
2248 * @sb: the empty superblock 2320 * @sb: the empty superblock
2249 * @data: unused 2321 * @data: unused
@@ -2296,6 +2368,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
2296 "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR}, 2368 "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR},
2297 [SMK_SYSLOG] = { 2369 [SMK_SYSLOG] = {
2298 "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, 2370 "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
2371 [SMK_PTRACE] = {
2372 "ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR},
2299 /* last one */ 2373 /* last one */
2300 {""} 2374 {""}
2301 }; 2375 };