diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-23 21:49:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-23 21:49:06 -0400 |
commit | e05644e17e744315bce12b0948cdc36910b9a76e (patch) | |
tree | 92d62ff59c57f991ef6b5c3cc2c2dcd205946a11 /security | |
parent | 97e7292ab5ccd30a13c3612835535fc3f3e59715 (diff) | |
parent | 663728418e3494f8e4a82f5d1b2f23c22d11be35 (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris:
"Nothing groundbreaking for this kernel, just cleanups and fixes, and a
couple of Smack enhancements."
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (21 commits)
Smack: Maintainer Record
Smack: don't show empty rules when /smack/load or /smack/load2 is read
Smack: user access check bounds
Smack: onlycap limits on CAP_MAC_ADMIN
Smack: fix smack_new_inode bogosities
ima: audit is compiled only when enabled
ima: ima_initialized is set only if successful
ima: add policy for pseudo fs
ima: remove unused cleanup functions
ima: free securityfs violations file
ima: use full pathnames in measurement list
security: Fix nommu build.
samples: seccomp: add .gitignore for untracked executables
tpm: check the chip reference before using it
TPM: fix memleak when register hardware fails
TPM: chip disabled state erronously being reported as error
MAINTAINERS: TPM maintainers' contacts update
Merge branches 'next-queue' and 'next' into next
Remove unused code from MPI library
Revert "crypto: GnuPG based MPI lib - additional sources (part 4)"
...
Diffstat (limited to 'security')
-rw-r--r-- | security/integrity/ima/Kconfig | 3 | ||||
-rw-r--r-- | security/integrity/ima/Makefile | 3 | ||||
-rw-r--r-- | security/integrity/ima/ima.h | 9 | ||||
-rw-r--r-- | security/integrity/ima/ima_api.c | 4 | ||||
-rw-r--r-- | security/integrity/ima/ima_audit.c | 3 | ||||
-rw-r--r-- | security/integrity/ima/ima_fs.c | 11 | ||||
-rw-r--r-- | security/integrity/ima/ima_init.c | 5 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 50 | ||||
-rw-r--r-- | security/integrity/ima/ima_policy.c | 2 | ||||
-rw-r--r-- | security/keys/compat.c | 4 | ||||
-rw-r--r-- | security/keys/internal.h | 2 | ||||
-rw-r--r-- | security/keys/keyctl.c | 2 | ||||
-rw-r--r-- | security/keys/keyring.c | 2 | ||||
-rw-r--r-- | security/smack/smack.h | 14 | ||||
-rw-r--r-- | security/smack/smack_access.c | 9 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 25 | ||||
-rw-r--r-- | security/smack/smackfs.c | 53 |
17 files changed, 114 insertions, 87 deletions
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 35664fe6daa1..b9c1219924f1 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig | |||
@@ -38,8 +38,9 @@ config IMA_MEASURE_PCR_IDX | |||
38 | measurement list. If unsure, use the default 10. | 38 | measurement list. If unsure, use the default 10. |
39 | 39 | ||
40 | config IMA_AUDIT | 40 | config IMA_AUDIT |
41 | bool | 41 | bool "Enables auditing support" |
42 | depends on IMA | 42 | depends on IMA |
43 | depends on AUDIT | ||
43 | default y | 44 | default y |
44 | help | 45 | help |
45 | This option adds a kernel parameter 'ima_audit', which | 46 | This option adds a kernel parameter 'ima_audit', which |
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile index 5690c021de8f..5f740f6971e1 100644 --- a/security/integrity/ima/Makefile +++ b/security/integrity/ima/Makefile | |||
@@ -6,4 +6,5 @@ | |||
6 | obj-$(CONFIG_IMA) += ima.o | 6 | obj-$(CONFIG_IMA) += ima.o |
7 | 7 | ||
8 | ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ | 8 | ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ |
9 | ima_policy.o ima_audit.o | 9 | ima_policy.o |
10 | ima-$(CONFIG_IMA_AUDIT) += ima_audit.o | ||
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 3ccf7acac6df..e7c99fd0d223 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -61,10 +61,19 @@ struct ima_queue_entry { | |||
61 | }; | 61 | }; |
62 | extern struct list_head ima_measurements; /* list of all measurements */ | 62 | extern struct list_head ima_measurements; /* list of all measurements */ |
63 | 63 | ||
64 | #ifdef CONFIG_IMA_AUDIT | ||
64 | /* declarations */ | 65 | /* declarations */ |
65 | void integrity_audit_msg(int audit_msgno, struct inode *inode, | 66 | void integrity_audit_msg(int audit_msgno, struct inode *inode, |
66 | const unsigned char *fname, const char *op, | 67 | const unsigned char *fname, const char *op, |
67 | const char *cause, int result, int info); | 68 | const char *cause, int result, int info); |
69 | #else | ||
70 | static inline void integrity_audit_msg(int audit_msgno, struct inode *inode, | ||
71 | const unsigned char *fname, | ||
72 | const char *op, const char *cause, | ||
73 | int result, int info) | ||
74 | { | ||
75 | } | ||
76 | #endif | ||
68 | 77 | ||
69 | /* Internal IMA function definitions */ | 78 | /* Internal IMA function definitions */ |
70 | int ima_init(void); | 79 | int ima_init(void); |
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 88a2788b981d..032ff03ad907 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c | |||
@@ -175,7 +175,9 @@ void ima_store_measurement(struct integrity_iint_cache *iint, | |||
175 | } | 175 | } |
176 | memset(&entry->template, 0, sizeof(entry->template)); | 176 | memset(&entry->template, 0, sizeof(entry->template)); |
177 | memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE); | 177 | memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE); |
178 | strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX); | 178 | strcpy(entry->template.file_name, |
179 | (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ? | ||
180 | file->f_dentry->d_name.name : filename); | ||
179 | 181 | ||
180 | result = ima_store_template(entry, violation, inode); | 182 | result = ima_store_template(entry, violation, inode); |
181 | if (!result || result == -EEXIST) | 183 | if (!result || result == -EEXIST) |
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c index 21e96bf188df..7a57f6769e9c 100644 --- a/security/integrity/ima/ima_audit.c +++ b/security/integrity/ima/ima_audit.c | |||
@@ -17,8 +17,6 @@ | |||
17 | 17 | ||
18 | static int ima_audit; | 18 | static int ima_audit; |
19 | 19 | ||
20 | #ifdef CONFIG_IMA_AUDIT | ||
21 | |||
22 | /* ima_audit_setup - enable informational auditing messages */ | 20 | /* ima_audit_setup - enable informational auditing messages */ |
23 | static int __init ima_audit_setup(char *str) | 21 | static int __init ima_audit_setup(char *str) |
24 | { | 22 | { |
@@ -29,7 +27,6 @@ static int __init ima_audit_setup(char *str) | |||
29 | return 1; | 27 | return 1; |
30 | } | 28 | } |
31 | __setup("ima_audit=", ima_audit_setup); | 29 | __setup("ima_audit=", ima_audit_setup); |
32 | #endif | ||
33 | 30 | ||
34 | void integrity_audit_msg(int audit_msgno, struct inode *inode, | 31 | void integrity_audit_msg(int audit_msgno, struct inode *inode, |
35 | const unsigned char *fname, const char *op, | 32 | const unsigned char *fname, const char *op, |
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index e1aa2b482dd2..38477c9c3415 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c | |||
@@ -367,20 +367,11 @@ int __init ima_fs_init(void) | |||
367 | 367 | ||
368 | return 0; | 368 | return 0; |
369 | out: | 369 | out: |
370 | securityfs_remove(runtime_measurements_count); | ||
371 | securityfs_remove(ascii_runtime_measurements); | ||
372 | securityfs_remove(binary_runtime_measurements); | ||
373 | securityfs_remove(ima_dir); | ||
374 | securityfs_remove(ima_policy); | ||
375 | return -1; | ||
376 | } | ||
377 | |||
378 | void __exit ima_fs_cleanup(void) | ||
379 | { | ||
380 | securityfs_remove(violations); | 370 | securityfs_remove(violations); |
381 | securityfs_remove(runtime_measurements_count); | 371 | securityfs_remove(runtime_measurements_count); |
382 | securityfs_remove(ascii_runtime_measurements); | 372 | securityfs_remove(ascii_runtime_measurements); |
383 | securityfs_remove(binary_runtime_measurements); | 373 | securityfs_remove(binary_runtime_measurements); |
384 | securityfs_remove(ima_dir); | 374 | securityfs_remove(ima_dir); |
385 | securityfs_remove(ima_policy); | 375 | securityfs_remove(ima_policy); |
376 | return -1; | ||
386 | } | 377 | } |
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 17f1f060306f..b5dfd534f13d 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c | |||
@@ -90,8 +90,3 @@ int __init ima_init(void) | |||
90 | 90 | ||
91 | return ima_fs_init(); | 91 | return ima_fs_init(); |
92 | } | 92 | } |
93 | |||
94 | void __exit ima_cleanup(void) | ||
95 | { | ||
96 | ima_fs_cleanup(); | ||
97 | } | ||
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index b17be79b9cf2..be8294915cf7 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -54,6 +54,7 @@ static void ima_rdwr_violation_check(struct file *file) | |||
54 | fmode_t mode = file->f_mode; | 54 | fmode_t mode = file->f_mode; |
55 | int rc; | 55 | int rc; |
56 | bool send_tomtou = false, send_writers = false; | 56 | bool send_tomtou = false, send_writers = false; |
57 | unsigned char *pathname = NULL, *pathbuf = NULL; | ||
57 | 58 | ||
58 | if (!S_ISREG(inode->i_mode) || !ima_initialized) | 59 | if (!S_ISREG(inode->i_mode) || !ima_initialized) |
59 | return; | 60 | return; |
@@ -75,12 +76,27 @@ static void ima_rdwr_violation_check(struct file *file) | |||
75 | out: | 76 | out: |
76 | mutex_unlock(&inode->i_mutex); | 77 | mutex_unlock(&inode->i_mutex); |
77 | 78 | ||
79 | if (!send_tomtou && !send_writers) | ||
80 | return; | ||
81 | |||
82 | /* We will allow 11 spaces for ' (deleted)' to be appended */ | ||
83 | pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL); | ||
84 | if (pathbuf) { | ||
85 | pathname = d_path(&file->f_path, pathbuf, PATH_MAX + 11); | ||
86 | if (IS_ERR(pathname)) | ||
87 | pathname = NULL; | ||
88 | else if (strlen(pathname) > IMA_EVENT_NAME_LEN_MAX) | ||
89 | pathname = NULL; | ||
90 | } | ||
78 | if (send_tomtou) | 91 | if (send_tomtou) |
79 | ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", | 92 | ima_add_violation(inode, |
80 | "ToMToU"); | 93 | !pathname ? dentry->d_name.name : pathname, |
94 | "invalid_pcr", "ToMToU"); | ||
81 | if (send_writers) | 95 | if (send_writers) |
82 | ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", | 96 | ima_add_violation(inode, |
83 | "open_writers"); | 97 | !pathname ? dentry->d_name.name : pathname, |
98 | "invalid_pcr", "open_writers"); | ||
99 | kfree(pathbuf); | ||
84 | } | 100 | } |
85 | 101 | ||
86 | static void ima_check_last_writer(struct integrity_iint_cache *iint, | 102 | static void ima_check_last_writer(struct integrity_iint_cache *iint, |
@@ -123,6 +139,7 @@ static int process_measurement(struct file *file, const unsigned char *filename, | |||
123 | { | 139 | { |
124 | struct inode *inode = file->f_dentry->d_inode; | 140 | struct inode *inode = file->f_dentry->d_inode; |
125 | struct integrity_iint_cache *iint; | 141 | struct integrity_iint_cache *iint; |
142 | unsigned char *pathname = NULL, *pathbuf = NULL; | ||
126 | int rc = 0; | 143 | int rc = 0; |
127 | 144 | ||
128 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | 145 | if (!ima_initialized || !S_ISREG(inode->i_mode)) |
@@ -147,8 +164,21 @@ retry: | |||
147 | goto out; | 164 | goto out; |
148 | 165 | ||
149 | rc = ima_collect_measurement(iint, file); | 166 | rc = ima_collect_measurement(iint, file); |
150 | if (!rc) | 167 | if (rc != 0) |
151 | ima_store_measurement(iint, file, filename); | 168 | goto out; |
169 | |||
170 | if (function != BPRM_CHECK) { | ||
171 | /* We will allow 11 spaces for ' (deleted)' to be appended */ | ||
172 | pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL); | ||
173 | if (pathbuf) { | ||
174 | pathname = | ||
175 | d_path(&file->f_path, pathbuf, PATH_MAX + 11); | ||
176 | if (IS_ERR(pathname)) | ||
177 | pathname = NULL; | ||
178 | } | ||
179 | } | ||
180 | ima_store_measurement(iint, file, !pathname ? filename : pathname); | ||
181 | kfree(pathbuf); | ||
152 | out: | 182 | out: |
153 | mutex_unlock(&iint->mutex); | 183 | mutex_unlock(&iint->mutex); |
154 | return rc; | 184 | return rc; |
@@ -228,15 +258,11 @@ static int __init init_ima(void) | |||
228 | int error; | 258 | int error; |
229 | 259 | ||
230 | error = ima_init(); | 260 | error = ima_init(); |
231 | ima_initialized = 1; | 261 | if (!error) |
262 | ima_initialized = 1; | ||
232 | return error; | 263 | return error; |
233 | } | 264 | } |
234 | 265 | ||
235 | static void __exit cleanup_ima(void) | ||
236 | { | ||
237 | ima_cleanup(); | ||
238 | } | ||
239 | |||
240 | late_initcall(init_ima); /* Start IMA after the TPM is available */ | 266 | late_initcall(init_ima); /* Start IMA after the TPM is available */ |
241 | 267 | ||
242 | MODULE_DESCRIPTION("Integrity Measurement Architecture"); | 268 | MODULE_DESCRIPTION("Integrity Measurement Architecture"); |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index d8edff209bf3..1a9583008aae 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
@@ -63,6 +63,8 @@ static struct ima_measure_rule_entry default_rules[] = { | |||
63 | {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, | 63 | {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, |
64 | {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, | 64 | {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, |
65 | {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC}, | 65 | {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC}, |
66 | {.action = DONT_MEASURE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC}, | ||
67 | {.action = DONT_MEASURE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC}, | ||
66 | {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, | 68 | {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, |
67 | {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, | 69 | {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, |
68 | {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, | 70 | {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, |
diff --git a/security/keys/compat.c b/security/keys/compat.c index c92d42b021aa..1c261763f479 100644 --- a/security/keys/compat.c +++ b/security/keys/compat.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * | 24 | * |
25 | * If successful, 0 will be returned. | 25 | * If successful, 0 will be returned. |
26 | */ | 26 | */ |
27 | long compat_keyctl_instantiate_key_iov( | 27 | static long compat_keyctl_instantiate_key_iov( |
28 | key_serial_t id, | 28 | key_serial_t id, |
29 | const struct compat_iovec __user *_payload_iov, | 29 | const struct compat_iovec __user *_payload_iov, |
30 | unsigned ioc, | 30 | unsigned ioc, |
@@ -33,7 +33,7 @@ long compat_keyctl_instantiate_key_iov( | |||
33 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; | 33 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; |
34 | long ret; | 34 | long ret; |
35 | 35 | ||
36 | if (_payload_iov == 0 || ioc == 0) | 36 | if (!_payload_iov || !ioc) |
37 | goto no_payload; | 37 | goto no_payload; |
38 | 38 | ||
39 | ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc, | 39 | ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc, |
diff --git a/security/keys/internal.h b/security/keys/internal.h index c246ba5d43ab..22ff05269e3d 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
@@ -242,7 +242,7 @@ extern long keyctl_instantiate_key_iov(key_serial_t, | |||
242 | extern long keyctl_invalidate_key(key_serial_t); | 242 | extern long keyctl_invalidate_key(key_serial_t); |
243 | 243 | ||
244 | extern long keyctl_instantiate_key_common(key_serial_t, | 244 | extern long keyctl_instantiate_key_common(key_serial_t, |
245 | const struct iovec __user *, | 245 | const struct iovec *, |
246 | unsigned, size_t, key_serial_t); | 246 | unsigned, size_t, key_serial_t); |
247 | 247 | ||
248 | /* | 248 | /* |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index f1b59ae39d7e..3364fbf46807 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -1106,7 +1106,7 @@ long keyctl_instantiate_key_iov(key_serial_t id, | |||
1106 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; | 1106 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; |
1107 | long ret; | 1107 | long ret; |
1108 | 1108 | ||
1109 | if (_payload_iov == 0 || ioc == 0) | 1109 | if (!_payload_iov || !ioc) |
1110 | goto no_payload; | 1110 | goto no_payload; |
1111 | 1111 | ||
1112 | ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc, | 1112 | ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc, |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 7445875f6818..81e7852d281d 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -751,6 +751,7 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu) | |||
751 | int __key_link_begin(struct key *keyring, const struct key_type *type, | 751 | int __key_link_begin(struct key *keyring, const struct key_type *type, |
752 | const char *description, unsigned long *_prealloc) | 752 | const char *description, unsigned long *_prealloc) |
753 | __acquires(&keyring->sem) | 753 | __acquires(&keyring->sem) |
754 | __acquires(&keyring_serialise_link_sem) | ||
754 | { | 755 | { |
755 | struct keyring_list *klist, *nklist; | 756 | struct keyring_list *klist, *nklist; |
756 | unsigned long prealloc; | 757 | unsigned long prealloc; |
@@ -960,6 +961,7 @@ void __key_link(struct key *keyring, struct key *key, | |||
960 | void __key_link_end(struct key *keyring, struct key_type *type, | 961 | void __key_link_end(struct key *keyring, struct key_type *type, |
961 | unsigned long prealloc) | 962 | unsigned long prealloc) |
962 | __releases(&keyring->sem) | 963 | __releases(&keyring->sem) |
964 | __releases(&keyring_serialise_link_sem) | ||
963 | { | 965 | { |
964 | BUG_ON(type == NULL); | 966 | BUG_ON(type == NULL); |
965 | BUG_ON(type->name == NULL); | 967 | BUG_ON(type->name == NULL); |
diff --git a/security/smack/smack.h b/security/smack/smack.h index cc361b8f3d13..99b36124f712 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
@@ -43,7 +43,6 @@ struct superblock_smack { | |||
43 | char *smk_hat; | 43 | char *smk_hat; |
44 | char *smk_default; | 44 | char *smk_default; |
45 | int smk_initialized; | 45 | int smk_initialized; |
46 | spinlock_t smk_sblock; /* for initialization */ | ||
47 | }; | 46 | }; |
48 | 47 | ||
49 | struct socket_smack { | 48 | struct socket_smack { |
@@ -284,6 +283,19 @@ static inline char *smk_of_current(void) | |||
284 | } | 283 | } |
285 | 284 | ||
286 | /* | 285 | /* |
286 | * Is the task privileged and allowed to be privileged | ||
287 | * by the onlycap rule. | ||
288 | */ | ||
289 | static inline int smack_privileged(int cap) | ||
290 | { | ||
291 | if (!capable(cap)) | ||
292 | return 0; | ||
293 | if (smack_onlycap == NULL || smack_onlycap == smk_of_current()) | ||
294 | return 1; | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | /* | ||
287 | * logging functions | 299 | * logging functions |
288 | */ | 300 | */ |
289 | #define SMACK_AUDIT_DENIED 0x1 | 301 | #define SMACK_AUDIT_DENIED 0x1 |
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 9f3705e92712..db14689a21e0 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c | |||
@@ -220,14 +220,9 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) | |||
220 | } | 220 | } |
221 | 221 | ||
222 | /* | 222 | /* |
223 | * Return if a specific label has been designated as the | 223 | * Allow for priviliged to override policy. |
224 | * only one that gets privilege and current does not | ||
225 | * have that label. | ||
226 | */ | 224 | */ |
227 | if (smack_onlycap != NULL && smack_onlycap != sp) | 225 | if (rc != 0 && smack_privileged(CAP_MAC_OVERRIDE)) |
228 | goto out_audit; | ||
229 | |||
230 | if (capable(CAP_MAC_OVERRIDE)) | ||
231 | rc = 0; | 226 | rc = 0; |
232 | 227 | ||
233 | out_audit: | 228 | out_audit: |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index ee0bb5735f35..8221514cc997 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -217,7 +217,7 @@ static int smack_syslog(int typefrom_file) | |||
217 | int rc = 0; | 217 | int rc = 0; |
218 | char *sp = smk_of_current(); | 218 | char *sp = smk_of_current(); |
219 | 219 | ||
220 | if (capable(CAP_MAC_OVERRIDE)) | 220 | if (smack_privileged(CAP_MAC_OVERRIDE)) |
221 | return 0; | 221 | return 0; |
222 | 222 | ||
223 | if (sp != smack_known_floor.smk_known) | 223 | if (sp != smack_known_floor.smk_known) |
@@ -251,7 +251,6 @@ static int smack_sb_alloc_security(struct super_block *sb) | |||
251 | sbsp->smk_floor = smack_known_floor.smk_known; | 251 | sbsp->smk_floor = smack_known_floor.smk_known; |
252 | sbsp->smk_hat = smack_known_hat.smk_known; | 252 | sbsp->smk_hat = smack_known_hat.smk_known; |
253 | sbsp->smk_initialized = 0; | 253 | sbsp->smk_initialized = 0; |
254 | spin_lock_init(&sbsp->smk_sblock); | ||
255 | 254 | ||
256 | sb->s_security = sbsp; | 255 | sb->s_security = sbsp; |
257 | 256 | ||
@@ -332,13 +331,10 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
332 | char *commap; | 331 | char *commap; |
333 | char *nsp; | 332 | char *nsp; |
334 | 333 | ||
335 | spin_lock(&sp->smk_sblock); | 334 | if (sp->smk_initialized != 0) |
336 | if (sp->smk_initialized != 0) { | ||
337 | spin_unlock(&sp->smk_sblock); | ||
338 | return 0; | 335 | return 0; |
339 | } | 336 | |
340 | sp->smk_initialized = 1; | 337 | sp->smk_initialized = 1; |
341 | spin_unlock(&sp->smk_sblock); | ||
342 | 338 | ||
343 | for (op = data; op != NULL; op = commap) { | 339 | for (op = data; op != NULL; op = commap) { |
344 | commap = strchr(op, ','); | 340 | commap = strchr(op, ','); |
@@ -825,7 +821,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
825 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || | 821 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || |
826 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || | 822 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || |
827 | strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { | 823 | strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { |
828 | if (!capable(CAP_MAC_ADMIN)) | 824 | if (!smack_privileged(CAP_MAC_ADMIN)) |
829 | rc = -EPERM; | 825 | rc = -EPERM; |
830 | /* | 826 | /* |
831 | * check label validity here so import wont fail on | 827 | * check label validity here so import wont fail on |
@@ -835,7 +831,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
835 | smk_import(value, size) == NULL) | 831 | smk_import(value, size) == NULL) |
836 | rc = -EINVAL; | 832 | rc = -EINVAL; |
837 | } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { | 833 | } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { |
838 | if (!capable(CAP_MAC_ADMIN)) | 834 | if (!smack_privileged(CAP_MAC_ADMIN)) |
839 | rc = -EPERM; | 835 | rc = -EPERM; |
840 | if (size != TRANS_TRUE_SIZE || | 836 | if (size != TRANS_TRUE_SIZE || |
841 | strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) | 837 | strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) |
@@ -931,7 +927,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) | |||
931 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || | 927 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || |
932 | strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || | 928 | strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || |
933 | strcmp(name, XATTR_NAME_SMACKMMAP)) { | 929 | strcmp(name, XATTR_NAME_SMACKMMAP)) { |
934 | if (!capable(CAP_MAC_ADMIN)) | 930 | if (!smack_privileged(CAP_MAC_ADMIN)) |
935 | rc = -EPERM; | 931 | rc = -EPERM; |
936 | } else | 932 | } else |
937 | rc = cap_inode_removexattr(dentry, name); | 933 | rc = cap_inode_removexattr(dentry, name); |
@@ -1720,7 +1716,8 @@ static int smack_task_wait(struct task_struct *p) | |||
1720 | * state into account in the decision as well as | 1716 | * state into account in the decision as well as |
1721 | * the smack value. | 1717 | * the smack value. |
1722 | */ | 1718 | */ |
1723 | if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE)) | 1719 | if (smack_privileged(CAP_MAC_OVERRIDE) || |
1720 | has_capability(p, CAP_MAC_OVERRIDE)) | ||
1724 | rc = 0; | 1721 | rc = 0; |
1725 | /* we log only if we didn't get overriden */ | 1722 | /* we log only if we didn't get overriden */ |
1726 | out_log: | 1723 | out_log: |
@@ -2721,7 +2718,7 @@ static int smack_setprocattr(struct task_struct *p, char *name, | |||
2721 | if (p != current) | 2718 | if (p != current) |
2722 | return -EPERM; | 2719 | return -EPERM; |
2723 | 2720 | ||
2724 | if (!capable(CAP_MAC_ADMIN)) | 2721 | if (!smack_privileged(CAP_MAC_ADMIN)) |
2725 | return -EPERM; | 2722 | return -EPERM; |
2726 | 2723 | ||
2727 | if (value == NULL || size == 0 || size >= SMK_LONGLABEL) | 2724 | if (value == NULL || size == 0 || size >= SMK_LONGLABEL) |
@@ -2784,7 +2781,7 @@ static int smack_unix_stream_connect(struct sock *sock, | |||
2784 | smk_ad_setfield_u_net_sk(&ad, other); | 2781 | smk_ad_setfield_u_net_sk(&ad, other); |
2785 | #endif | 2782 | #endif |
2786 | 2783 | ||
2787 | if (!capable(CAP_MAC_OVERRIDE)) | 2784 | if (!smack_privileged(CAP_MAC_OVERRIDE)) |
2788 | rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); | 2785 | rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); |
2789 | 2786 | ||
2790 | /* | 2787 | /* |
@@ -2820,7 +2817,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) | |||
2820 | smk_ad_setfield_u_net_sk(&ad, other->sk); | 2817 | smk_ad_setfield_u_net_sk(&ad, other->sk); |
2821 | #endif | 2818 | #endif |
2822 | 2819 | ||
2823 | if (!capable(CAP_MAC_OVERRIDE)) | 2820 | if (!smack_privileged(CAP_MAC_OVERRIDE)) |
2824 | rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); | 2821 | rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); |
2825 | 2822 | ||
2826 | return rc; | 2823 | return rc; |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 1810c9a4ed48..d31e6d957c21 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -215,28 +215,27 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list, | |||
215 | * @access: access string | 215 | * @access: access string |
216 | * @rule: Smack rule | 216 | * @rule: Smack rule |
217 | * @import: if non-zero, import labels | 217 | * @import: if non-zero, import labels |
218 | * @len: label length limit | ||
218 | * | 219 | * |
219 | * Returns 0 on success, -1 on failure | 220 | * Returns 0 on success, -1 on failure |
220 | */ | 221 | */ |
221 | static int smk_fill_rule(const char *subject, const char *object, | 222 | static int smk_fill_rule(const char *subject, const char *object, |
222 | const char *access, struct smack_rule *rule, | 223 | const char *access, struct smack_rule *rule, |
223 | int import) | 224 | int import, int len) |
224 | { | 225 | { |
225 | int rc = -1; | ||
226 | int done; | ||
227 | const char *cp; | 226 | const char *cp; |
228 | struct smack_known *skp; | 227 | struct smack_known *skp; |
229 | 228 | ||
230 | if (import) { | 229 | if (import) { |
231 | rule->smk_subject = smk_import(subject, 0); | 230 | rule->smk_subject = smk_import(subject, len); |
232 | if (rule->smk_subject == NULL) | 231 | if (rule->smk_subject == NULL) |
233 | return -1; | 232 | return -1; |
234 | 233 | ||
235 | rule->smk_object = smk_import(object, 0); | 234 | rule->smk_object = smk_import(object, len); |
236 | if (rule->smk_object == NULL) | 235 | if (rule->smk_object == NULL) |
237 | return -1; | 236 | return -1; |
238 | } else { | 237 | } else { |
239 | cp = smk_parse_smack(subject, 0); | 238 | cp = smk_parse_smack(subject, len); |
240 | if (cp == NULL) | 239 | if (cp == NULL) |
241 | return -1; | 240 | return -1; |
242 | skp = smk_find_entry(cp); | 241 | skp = smk_find_entry(cp); |
@@ -245,7 +244,7 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
245 | return -1; | 244 | return -1; |
246 | rule->smk_subject = skp->smk_known; | 245 | rule->smk_subject = skp->smk_known; |
247 | 246 | ||
248 | cp = smk_parse_smack(object, 0); | 247 | cp = smk_parse_smack(object, len); |
249 | if (cp == NULL) | 248 | if (cp == NULL) |
250 | return -1; | 249 | return -1; |
251 | skp = smk_find_entry(cp); | 250 | skp = smk_find_entry(cp); |
@@ -257,7 +256,7 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
257 | 256 | ||
258 | rule->smk_access = 0; | 257 | rule->smk_access = 0; |
259 | 258 | ||
260 | for (cp = access, done = 0; *cp && !done; cp++) { | 259 | for (cp = access; *cp != '\0'; cp++) { |
261 | switch (*cp) { | 260 | switch (*cp) { |
262 | case '-': | 261 | case '-': |
263 | break; | 262 | break; |
@@ -282,13 +281,11 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
282 | rule->smk_access |= MAY_TRANSMUTE; | 281 | rule->smk_access |= MAY_TRANSMUTE; |
283 | break; | 282 | break; |
284 | default: | 283 | default: |
285 | done = 1; | 284 | return 0; |
286 | break; | ||
287 | } | 285 | } |
288 | } | 286 | } |
289 | rc = 0; | ||
290 | 287 | ||
291 | return rc; | 288 | return 0; |
292 | } | 289 | } |
293 | 290 | ||
294 | /** | 291 | /** |
@@ -304,7 +301,8 @@ static int smk_parse_rule(const char *data, struct smack_rule *rule, int import) | |||
304 | int rc; | 301 | int rc; |
305 | 302 | ||
306 | rc = smk_fill_rule(data, data + SMK_LABELLEN, | 303 | rc = smk_fill_rule(data, data + SMK_LABELLEN, |
307 | data + SMK_LABELLEN + SMK_LABELLEN, rule, import); | 304 | data + SMK_LABELLEN + SMK_LABELLEN, rule, import, |
305 | SMK_LABELLEN); | ||
308 | return rc; | 306 | return rc; |
309 | } | 307 | } |
310 | 308 | ||
@@ -340,7 +338,7 @@ static int smk_parse_long_rule(const char *data, struct smack_rule *rule, | |||
340 | goto free_out_o; | 338 | goto free_out_o; |
341 | 339 | ||
342 | if (sscanf(data, "%s %s %s", subject, object, access) == 3) | 340 | if (sscanf(data, "%s %s %s", subject, object, access) == 3) |
343 | rc = smk_fill_rule(subject, object, access, rule, import); | 341 | rc = smk_fill_rule(subject, object, access, rule, import, 0); |
344 | 342 | ||
345 | kfree(access); | 343 | kfree(access); |
346 | free_out_o: | 344 | free_out_o: |
@@ -520,6 +518,9 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) | |||
520 | if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) | 518 | if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) |
521 | return; | 519 | return; |
522 | 520 | ||
521 | if (srp->smk_access == 0) | ||
522 | return; | ||
523 | |||
523 | seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); | 524 | seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); |
524 | 525 | ||
525 | seq_putc(s, ' '); | 526 | seq_putc(s, ' '); |
@@ -534,8 +535,6 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) | |||
534 | seq_putc(s, 'a'); | 535 | seq_putc(s, 'a'); |
535 | if (srp->smk_access & MAY_TRANSMUTE) | 536 | if (srp->smk_access & MAY_TRANSMUTE) |
536 | seq_putc(s, 't'); | 537 | seq_putc(s, 't'); |
537 | if (srp->smk_access == 0) | ||
538 | seq_putc(s, '-'); | ||
539 | 538 | ||
540 | seq_putc(s, '\n'); | 539 | seq_putc(s, '\n'); |
541 | } | 540 | } |
@@ -595,13 +594,12 @@ static int smk_open_load(struct inode *inode, struct file *file) | |||
595 | static ssize_t smk_write_load(struct file *file, const char __user *buf, | 594 | static ssize_t smk_write_load(struct file *file, const char __user *buf, |
596 | size_t count, loff_t *ppos) | 595 | size_t count, loff_t *ppos) |
597 | { | 596 | { |
598 | |||
599 | /* | 597 | /* |
600 | * Must have privilege. | 598 | * Must have privilege. |
601 | * No partial writes. | 599 | * No partial writes. |
602 | * Enough data must be present. | 600 | * Enough data must be present. |
603 | */ | 601 | */ |
604 | if (!capable(CAP_MAC_ADMIN)) | 602 | if (!smack_privileged(CAP_MAC_ADMIN)) |
605 | return -EPERM; | 603 | return -EPERM; |
606 | 604 | ||
607 | return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, | 605 | return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, |
@@ -787,7 +785,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, | |||
787 | * No partial writes. | 785 | * No partial writes. |
788 | * Enough data must be present. | 786 | * Enough data must be present. |
789 | */ | 787 | */ |
790 | if (!capable(CAP_MAC_ADMIN)) | 788 | if (!smack_privileged(CAP_MAC_ADMIN)) |
791 | return -EPERM; | 789 | return -EPERM; |
792 | if (*ppos != 0) | 790 | if (*ppos != 0) |
793 | return -EINVAL; | 791 | return -EINVAL; |
@@ -1090,7 +1088,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
1090 | * "<addr/mask, as a.b.c.d/e><space><label>" | 1088 | * "<addr/mask, as a.b.c.d/e><space><label>" |
1091 | * "<addr, as a.b.c.d><space><label>" | 1089 | * "<addr, as a.b.c.d><space><label>" |
1092 | */ | 1090 | */ |
1093 | if (!capable(CAP_MAC_ADMIN)) | 1091 | if (!smack_privileged(CAP_MAC_ADMIN)) |
1094 | return -EPERM; | 1092 | return -EPERM; |
1095 | if (*ppos != 0) | 1093 | if (*ppos != 0) |
1096 | return -EINVAL; | 1094 | return -EINVAL; |
@@ -1267,7 +1265,7 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf, | |||
1267 | char temp[80]; | 1265 | char temp[80]; |
1268 | int i; | 1266 | int i; |
1269 | 1267 | ||
1270 | if (!capable(CAP_MAC_ADMIN)) | 1268 | if (!smack_privileged(CAP_MAC_ADMIN)) |
1271 | return -EPERM; | 1269 | return -EPERM; |
1272 | 1270 | ||
1273 | if (count >= sizeof(temp) || count == 0) | 1271 | if (count >= sizeof(temp) || count == 0) |
@@ -1334,7 +1332,7 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf, | |||
1334 | char temp[80]; | 1332 | char temp[80]; |
1335 | int i; | 1333 | int i; |
1336 | 1334 | ||
1337 | if (!capable(CAP_MAC_ADMIN)) | 1335 | if (!smack_privileged(CAP_MAC_ADMIN)) |
1338 | return -EPERM; | 1336 | return -EPERM; |
1339 | 1337 | ||
1340 | if (count >= sizeof(temp) || count == 0) | 1338 | if (count >= sizeof(temp) || count == 0) |
@@ -1412,7 +1410,7 @@ static ssize_t smk_write_mapped(struct file *file, const char __user *buf, | |||
1412 | char temp[80]; | 1410 | char temp[80]; |
1413 | int i; | 1411 | int i; |
1414 | 1412 | ||
1415 | if (!capable(CAP_MAC_ADMIN)) | 1413 | if (!smack_privileged(CAP_MAC_ADMIN)) |
1416 | return -EPERM; | 1414 | return -EPERM; |
1417 | 1415 | ||
1418 | if (count >= sizeof(temp) || count == 0) | 1416 | if (count >= sizeof(temp) || count == 0) |
@@ -1503,7 +1501,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, | |||
1503 | char *data; | 1501 | char *data; |
1504 | int rc = count; | 1502 | int rc = count; |
1505 | 1503 | ||
1506 | if (!capable(CAP_MAC_ADMIN)) | 1504 | if (!smack_privileged(CAP_MAC_ADMIN)) |
1507 | return -EPERM; | 1505 | return -EPERM; |
1508 | 1506 | ||
1509 | data = kzalloc(count + 1, GFP_KERNEL); | 1507 | data = kzalloc(count + 1, GFP_KERNEL); |
@@ -1586,7 +1584,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, | |||
1586 | char *sp = smk_of_task(current->cred->security); | 1584 | char *sp = smk_of_task(current->cred->security); |
1587 | int rc = count; | 1585 | int rc = count; |
1588 | 1586 | ||
1589 | if (!capable(CAP_MAC_ADMIN)) | 1587 | if (!smack_privileged(CAP_MAC_ADMIN)) |
1590 | return -EPERM; | 1588 | return -EPERM; |
1591 | 1589 | ||
1592 | /* | 1590 | /* |
@@ -1664,7 +1662,7 @@ static ssize_t smk_write_logging(struct file *file, const char __user *buf, | |||
1664 | char temp[32]; | 1662 | char temp[32]; |
1665 | int i; | 1663 | int i; |
1666 | 1664 | ||
1667 | if (!capable(CAP_MAC_ADMIN)) | 1665 | if (!smack_privileged(CAP_MAC_ADMIN)) |
1668 | return -EPERM; | 1666 | return -EPERM; |
1669 | 1667 | ||
1670 | if (count >= sizeof(temp) || count == 0) | 1668 | if (count >= sizeof(temp) || count == 0) |
@@ -1885,7 +1883,7 @@ static ssize_t smk_write_load2(struct file *file, const char __user *buf, | |||
1885 | /* | 1883 | /* |
1886 | * Must have privilege. | 1884 | * Must have privilege. |
1887 | */ | 1885 | */ |
1888 | if (!capable(CAP_MAC_ADMIN)) | 1886 | if (!smack_privileged(CAP_MAC_ADMIN)) |
1889 | return -EPERM; | 1887 | return -EPERM; |
1890 | 1888 | ||
1891 | return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, | 1889 | return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, |
@@ -2051,7 +2049,6 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) | |||
2051 | } | 2049 | } |
2052 | 2050 | ||
2053 | root_inode = sb->s_root->d_inode; | 2051 | root_inode = sb->s_root->d_inode; |
2054 | root_inode->i_security = new_inode_smack(smack_known_floor.smk_known); | ||
2055 | 2052 | ||
2056 | return 0; | 2053 | return 0; |
2057 | } | 2054 | } |