diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/apparmor/include/resource.h | 4 | ||||
-rw-r--r-- | security/apparmor/lib.c | 2 | ||||
-rw-r--r-- | security/apparmor/lsm.c | 2 | ||||
-rw-r--r-- | security/apparmor/path.c | 38 | ||||
-rw-r--r-- | security/apparmor/policy.c | 6 | ||||
-rw-r--r-- | security/apparmor/resource.c | 20 | ||||
-rw-r--r-- | security/integrity/ima/ima.h | 1 | ||||
-rw-r--r-- | security/integrity/ima/ima_iint.c | 4 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 8 | ||||
-rw-r--r-- | security/keys/keyctl.c | 6 | ||||
-rw-r--r-- | security/tomoyo/common.c | 6 | ||||
-rw-r--r-- | security/tomoyo/common.h | 3 |
12 files changed, 50 insertions, 50 deletions
diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h index 3c88be946494..02baec732bb5 100644 --- a/security/apparmor/include/resource.h +++ b/security/apparmor/include/resource.h | |||
@@ -33,8 +33,8 @@ struct aa_rlimit { | |||
33 | }; | 33 | }; |
34 | 34 | ||
35 | int aa_map_resource(int resource); | 35 | int aa_map_resource(int resource); |
36 | int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource, | 36 | int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *, |
37 | struct rlimit *new_rlim); | 37 | unsigned int resource, struct rlimit *new_rlim); |
38 | 38 | ||
39 | void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new); | 39 | void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new); |
40 | 40 | ||
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index 6e85cdb4303f..506d2baf6147 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c | |||
@@ -40,6 +40,7 @@ char *aa_split_fqname(char *fqname, char **ns_name) | |||
40 | *ns_name = NULL; | 40 | *ns_name = NULL; |
41 | if (name[0] == ':') { | 41 | if (name[0] == ':') { |
42 | char *split = strchr(&name[1], ':'); | 42 | char *split = strchr(&name[1], ':'); |
43 | *ns_name = skip_spaces(&name[1]); | ||
43 | if (split) { | 44 | if (split) { |
44 | /* overwrite ':' with \0 */ | 45 | /* overwrite ':' with \0 */ |
45 | *split = 0; | 46 | *split = 0; |
@@ -47,7 +48,6 @@ char *aa_split_fqname(char *fqname, char **ns_name) | |||
47 | } else | 48 | } else |
48 | /* a ns name without a following profile is allowed */ | 49 | /* a ns name without a following profile is allowed */ |
49 | name = NULL; | 50 | name = NULL; |
50 | *ns_name = &name[1]; | ||
51 | } | 51 | } |
52 | if (name && *name == 0) | 52 | if (name && *name == 0) |
53 | name = NULL; | 53 | name = NULL; |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index f73e2c204218..cf1de4462ccd 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -614,7 +614,7 @@ static int apparmor_task_setrlimit(struct task_struct *task, | |||
614 | int error = 0; | 614 | int error = 0; |
615 | 615 | ||
616 | if (!unconfined(profile)) | 616 | if (!unconfined(profile)) |
617 | error = aa_task_setrlimit(profile, resource, new_rlim); | 617 | error = aa_task_setrlimit(profile, task, resource, new_rlim); |
618 | 618 | ||
619 | return error; | 619 | return error; |
620 | } | 620 | } |
diff --git a/security/apparmor/path.c b/security/apparmor/path.c index 19358dc14605..82396050f186 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c | |||
@@ -59,8 +59,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
59 | { | 59 | { |
60 | struct path root, tmp; | 60 | struct path root, tmp; |
61 | char *res; | 61 | char *res; |
62 | int deleted, connected; | 62 | int connected, error = 0; |
63 | int error = 0; | ||
64 | 63 | ||
65 | /* Get the root we want to resolve too, released below */ | 64 | /* Get the root we want to resolve too, released below */ |
66 | if (flags & PATH_CHROOT_REL) { | 65 | if (flags & PATH_CHROOT_REL) { |
@@ -74,19 +73,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
74 | } | 73 | } |
75 | 74 | ||
76 | spin_lock(&dcache_lock); | 75 | spin_lock(&dcache_lock); |
77 | /* There is a race window between path lookup here and the | 76 | tmp = root; |
78 | * need to strip the " (deleted) string that __d_path applies | 77 | res = __d_path(path, &tmp, buf, buflen); |
79 | * Detect the race and relookup the path | ||
80 | * | ||
81 | * The stripping of (deleted) is a hack that could be removed | ||
82 | * with an updated __d_path | ||
83 | */ | ||
84 | do { | ||
85 | tmp = root; | ||
86 | deleted = d_unlinked(path->dentry); | ||
87 | res = __d_path(path, &tmp, buf, buflen); | ||
88 | |||
89 | } while (deleted != d_unlinked(path->dentry)); | ||
90 | spin_unlock(&dcache_lock); | 78 | spin_unlock(&dcache_lock); |
91 | 79 | ||
92 | *name = res; | 80 | *name = res; |
@@ -98,21 +86,17 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
98 | *name = buf; | 86 | *name = buf; |
99 | goto out; | 87 | goto out; |
100 | } | 88 | } |
101 | if (deleted) { | ||
102 | /* On some filesystems, newly allocated dentries appear to the | ||
103 | * security_path hooks as a deleted dentry except without an | ||
104 | * inode allocated. | ||
105 | * | ||
106 | * Remove the appended deleted text and return as string for | ||
107 | * normal mediation, or auditing. The (deleted) string is | ||
108 | * guaranteed to be added in this case, so just strip it. | ||
109 | */ | ||
110 | buf[buflen - 11] = 0; /* - (len(" (deleted)") +\0) */ | ||
111 | 89 | ||
112 | if (path->dentry->d_inode && !(flags & PATH_MEDIATE_DELETED)) { | 90 | /* Handle two cases: |
91 | * 1. A deleted dentry && profile is not allowing mediation of deleted | ||
92 | * 2. On some filesystems, newly allocated dentries appear to the | ||
93 | * security_path hooks as a deleted dentry except without an inode | ||
94 | * allocated. | ||
95 | */ | ||
96 | if (d_unlinked(path->dentry) && path->dentry->d_inode && | ||
97 | !(flags & PATH_MEDIATE_DELETED)) { | ||
113 | error = -ENOENT; | 98 | error = -ENOENT; |
114 | goto out; | 99 | goto out; |
115 | } | ||
116 | } | 100 | } |
117 | 101 | ||
118 | /* Determine if the path is connected to the expected root */ | 102 | /* Determine if the path is connected to the expected root */ |
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 3cdc1ad0787e..52cc865f1464 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c | |||
@@ -1151,12 +1151,14 @@ ssize_t aa_remove_profiles(char *fqname, size_t size) | |||
1151 | /* released below */ | 1151 | /* released below */ |
1152 | ns = aa_get_namespace(root); | 1152 | ns = aa_get_namespace(root); |
1153 | 1153 | ||
1154 | write_lock(&ns->lock); | ||
1155 | if (!name) { | 1154 | if (!name) { |
1156 | /* remove namespace - can only happen if fqname[0] == ':' */ | 1155 | /* remove namespace - can only happen if fqname[0] == ':' */ |
1156 | write_lock(&ns->parent->lock); | ||
1157 | __remove_namespace(ns); | 1157 | __remove_namespace(ns); |
1158 | write_unlock(&ns->parent->lock); | ||
1158 | } else { | 1159 | } else { |
1159 | /* remove profile */ | 1160 | /* remove profile */ |
1161 | write_lock(&ns->lock); | ||
1160 | profile = aa_get_profile(__lookup_profile(&ns->base, name)); | 1162 | profile = aa_get_profile(__lookup_profile(&ns->base, name)); |
1161 | if (!profile) { | 1163 | if (!profile) { |
1162 | error = -ENOENT; | 1164 | error = -ENOENT; |
@@ -1165,8 +1167,8 @@ ssize_t aa_remove_profiles(char *fqname, size_t size) | |||
1165 | } | 1167 | } |
1166 | name = profile->base.hname; | 1168 | name = profile->base.hname; |
1167 | __remove_profile(profile); | 1169 | __remove_profile(profile); |
1170 | write_unlock(&ns->lock); | ||
1168 | } | 1171 | } |
1169 | write_unlock(&ns->lock); | ||
1170 | 1172 | ||
1171 | /* don't fail removal if audit fails */ | 1173 | /* don't fail removal if audit fails */ |
1172 | (void) audit_policy(OP_PROF_RM, GFP_KERNEL, name, info, error); | 1174 | (void) audit_policy(OP_PROF_RM, GFP_KERNEL, name, info, error); |
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c index 4a368f1fd36d..a4136c10b1c6 100644 --- a/security/apparmor/resource.c +++ b/security/apparmor/resource.c | |||
@@ -72,6 +72,7 @@ int aa_map_resource(int resource) | |||
72 | /** | 72 | /** |
73 | * aa_task_setrlimit - test permission to set an rlimit | 73 | * aa_task_setrlimit - test permission to set an rlimit |
74 | * @profile - profile confining the task (NOT NULL) | 74 | * @profile - profile confining the task (NOT NULL) |
75 | * @task - task the resource is being set on | ||
75 | * @resource - the resource being set | 76 | * @resource - the resource being set |
76 | * @new_rlim - the new resource limit (NOT NULL) | 77 | * @new_rlim - the new resource limit (NOT NULL) |
77 | * | 78 | * |
@@ -79,18 +80,21 @@ int aa_map_resource(int resource) | |||
79 | * | 80 | * |
80 | * Returns: 0 or error code if setting resource failed | 81 | * Returns: 0 or error code if setting resource failed |
81 | */ | 82 | */ |
82 | int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource, | 83 | int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task, |
83 | struct rlimit *new_rlim) | 84 | unsigned int resource, struct rlimit *new_rlim) |
84 | { | 85 | { |
85 | int error = 0; | 86 | int error = 0; |
86 | 87 | ||
87 | if (profile->rlimits.mask & (1 << resource) && | 88 | /* TODO: extend resource control to handle other (non current) |
88 | new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max) | 89 | * processes. AppArmor rules currently have the implicit assumption |
89 | 90 | * that the task is setting the resource of the current process | |
90 | error = audit_resource(profile, resource, new_rlim->rlim_max, | 91 | */ |
91 | -EACCES); | 92 | if ((task != current->group_leader) || |
93 | (profile->rlimits.mask & (1 << resource) && | ||
94 | new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max)) | ||
95 | error = -EACCES; | ||
92 | 96 | ||
93 | return error; | 97 | return audit_resource(profile, resource, new_rlim->rlim_max, error); |
94 | } | 98 | } |
95 | 99 | ||
96 | /** | 100 | /** |
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 16d100d3fc38..3fbcd1dda0ef 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -35,6 +35,7 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; | |||
35 | #define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) | 35 | #define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) |
36 | 36 | ||
37 | /* set during initialization */ | 37 | /* set during initialization */ |
38 | extern int iint_initialized; | ||
38 | extern int ima_initialized; | 39 | extern int ima_initialized; |
39 | extern int ima_used_chip; | 40 | extern int ima_used_chip; |
40 | extern char *ima_hash; | 41 | extern char *ima_hash; |
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c index 7625b85c2274..afba4aef812f 100644 --- a/security/integrity/ima/ima_iint.c +++ b/security/integrity/ima/ima_iint.c | |||
@@ -22,9 +22,10 @@ | |||
22 | 22 | ||
23 | RADIX_TREE(ima_iint_store, GFP_ATOMIC); | 23 | RADIX_TREE(ima_iint_store, GFP_ATOMIC); |
24 | DEFINE_SPINLOCK(ima_iint_lock); | 24 | DEFINE_SPINLOCK(ima_iint_lock); |
25 | |||
26 | static struct kmem_cache *iint_cache __read_mostly; | 25 | static struct kmem_cache *iint_cache __read_mostly; |
27 | 26 | ||
27 | int iint_initialized = 0; | ||
28 | |||
28 | /* ima_iint_find_get - return the iint associated with an inode | 29 | /* ima_iint_find_get - return the iint associated with an inode |
29 | * | 30 | * |
30 | * ima_iint_find_get gets a reference to the iint. Caller must | 31 | * ima_iint_find_get gets a reference to the iint. Caller must |
@@ -141,6 +142,7 @@ static int __init ima_iintcache_init(void) | |||
141 | iint_cache = | 142 | iint_cache = |
142 | kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0, | 143 | kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0, |
143 | SLAB_PANIC, init_once); | 144 | SLAB_PANIC, init_once); |
145 | iint_initialized = 1; | ||
144 | return 0; | 146 | return 0; |
145 | } | 147 | } |
146 | security_initcall(ima_iintcache_init); | 148 | security_initcall(ima_iintcache_init); |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index f93641382e9f..e662b89d4079 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -148,12 +148,14 @@ void ima_counts_get(struct file *file) | |||
148 | struct ima_iint_cache *iint; | 148 | struct ima_iint_cache *iint; |
149 | int rc; | 149 | int rc; |
150 | 150 | ||
151 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | 151 | if (!iint_initialized || !S_ISREG(inode->i_mode)) |
152 | return; | 152 | return; |
153 | iint = ima_iint_find_get(inode); | 153 | iint = ima_iint_find_get(inode); |
154 | if (!iint) | 154 | if (!iint) |
155 | return; | 155 | return; |
156 | mutex_lock(&iint->mutex); | 156 | mutex_lock(&iint->mutex); |
157 | if (!ima_initialized) | ||
158 | goto out; | ||
157 | rc = ima_must_measure(iint, inode, MAY_READ, FILE_CHECK); | 159 | rc = ima_must_measure(iint, inode, MAY_READ, FILE_CHECK); |
158 | if (rc < 0) | 160 | if (rc < 0) |
159 | goto out; | 161 | goto out; |
@@ -213,7 +215,7 @@ void ima_file_free(struct file *file) | |||
213 | struct inode *inode = file->f_dentry->d_inode; | 215 | struct inode *inode = file->f_dentry->d_inode; |
214 | struct ima_iint_cache *iint; | 216 | struct ima_iint_cache *iint; |
215 | 217 | ||
216 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | 218 | if (!iint_initialized || !S_ISREG(inode->i_mode)) |
217 | return; | 219 | return; |
218 | iint = ima_iint_find_get(inode); | 220 | iint = ima_iint_find_get(inode); |
219 | if (!iint) | 221 | if (!iint) |
@@ -230,7 +232,7 @@ static int process_measurement(struct file *file, const unsigned char *filename, | |||
230 | { | 232 | { |
231 | struct inode *inode = file->f_dentry->d_inode; | 233 | struct inode *inode = file->f_dentry->d_inode; |
232 | struct ima_iint_cache *iint; | 234 | struct ima_iint_cache *iint; |
233 | int rc; | 235 | int rc = 0; |
234 | 236 | ||
235 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | 237 | if (!ima_initialized || !S_ISREG(inode->i_mode)) |
236 | return 0; | 238 | return 0; |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index b2b0998d6abd..60924f6a52db 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -1272,6 +1272,7 @@ long keyctl_session_to_parent(void) | |||
1272 | keyring_r = NULL; | 1272 | keyring_r = NULL; |
1273 | 1273 | ||
1274 | me = current; | 1274 | me = current; |
1275 | rcu_read_lock(); | ||
1275 | write_lock_irq(&tasklist_lock); | 1276 | write_lock_irq(&tasklist_lock); |
1276 | 1277 | ||
1277 | parent = me->real_parent; | 1278 | parent = me->real_parent; |
@@ -1304,7 +1305,8 @@ long keyctl_session_to_parent(void) | |||
1304 | goto not_permitted; | 1305 | goto not_permitted; |
1305 | 1306 | ||
1306 | /* the keyrings must have the same UID */ | 1307 | /* the keyrings must have the same UID */ |
1307 | if (pcred->tgcred->session_keyring->uid != mycred->euid || | 1308 | if ((pcred->tgcred->session_keyring && |
1309 | pcred->tgcred->session_keyring->uid != mycred->euid) || | ||
1308 | mycred->tgcred->session_keyring->uid != mycred->euid) | 1310 | mycred->tgcred->session_keyring->uid != mycred->euid) |
1309 | goto not_permitted; | 1311 | goto not_permitted; |
1310 | 1312 | ||
@@ -1319,6 +1321,7 @@ long keyctl_session_to_parent(void) | |||
1319 | set_ti_thread_flag(task_thread_info(parent), TIF_NOTIFY_RESUME); | 1321 | set_ti_thread_flag(task_thread_info(parent), TIF_NOTIFY_RESUME); |
1320 | 1322 | ||
1321 | write_unlock_irq(&tasklist_lock); | 1323 | write_unlock_irq(&tasklist_lock); |
1324 | rcu_read_unlock(); | ||
1322 | if (oldcred) | 1325 | if (oldcred) |
1323 | put_cred(oldcred); | 1326 | put_cred(oldcred); |
1324 | return 0; | 1327 | return 0; |
@@ -1327,6 +1330,7 @@ already_same: | |||
1327 | ret = 0; | 1330 | ret = 0; |
1328 | not_permitted: | 1331 | not_permitted: |
1329 | write_unlock_irq(&tasklist_lock); | 1332 | write_unlock_irq(&tasklist_lock); |
1333 | rcu_read_unlock(); | ||
1330 | put_cred(cred); | 1334 | put_cred(cred); |
1331 | return ret; | 1335 | return ret; |
1332 | 1336 | ||
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index ef43995119a4..c668b447c725 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -1416,15 +1416,19 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r) | |||
1416 | const pid_t gpid = task_pid_nr(current); | 1416 | const pid_t gpid = task_pid_nr(current); |
1417 | static const int tomoyo_buffer_len = 4096; | 1417 | static const int tomoyo_buffer_len = 4096; |
1418 | char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS); | 1418 | char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS); |
1419 | pid_t ppid; | ||
1419 | if (!buffer) | 1420 | if (!buffer) |
1420 | return NULL; | 1421 | return NULL; |
1421 | do_gettimeofday(&tv); | 1422 | do_gettimeofday(&tv); |
1423 | rcu_read_lock(); | ||
1424 | ppid = task_tgid_vnr(current->real_parent); | ||
1425 | rcu_read_unlock(); | ||
1422 | snprintf(buffer, tomoyo_buffer_len - 1, | 1426 | snprintf(buffer, tomoyo_buffer_len - 1, |
1423 | "#timestamp=%lu profile=%u mode=%s (global-pid=%u)" | 1427 | "#timestamp=%lu profile=%u mode=%s (global-pid=%u)" |
1424 | " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u" | 1428 | " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u" |
1425 | " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }", | 1429 | " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }", |
1426 | tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid, | 1430 | tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid, |
1427 | (pid_t) sys_getpid(), (pid_t) sys_getppid(), | 1431 | task_tgid_vnr(current), ppid, |
1428 | current_uid(), current_gid(), current_euid(), | 1432 | current_uid(), current_gid(), current_euid(), |
1429 | current_egid(), current_suid(), current_sgid(), | 1433 | current_egid(), current_suid(), current_sgid(), |
1430 | current_fsuid(), current_fsgid()); | 1434 | current_fsuid(), current_fsgid()); |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 04454cb7b24a..7c66bd898782 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -689,9 +689,6 @@ struct tomoyo_profile { | |||
689 | 689 | ||
690 | /********** Function prototypes. **********/ | 690 | /********** Function prototypes. **********/ |
691 | 691 | ||
692 | extern asmlinkage long sys_getpid(void); | ||
693 | extern asmlinkage long sys_getppid(void); | ||
694 | |||
695 | /* Check whether the given string starts with the given keyword. */ | 692 | /* Check whether the given string starts with the given keyword. */ |
696 | bool tomoyo_str_starts(char **src, const char *find); | 693 | bool tomoyo_str_starts(char **src, const char *find); |
697 | /* Get tomoyo_realpath() of current process. */ | 694 | /* Get tomoyo_realpath() of current process. */ |