diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 78 |
1 files changed, 42 insertions, 36 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 447a1e0f48cb..45c41490d521 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -122,11 +122,10 @@ static int task_alloc_security(struct task_struct *task) | |||
122 | { | 122 | { |
123 | struct task_security_struct *tsec; | 123 | struct task_security_struct *tsec; |
124 | 124 | ||
125 | tsec = kmalloc(sizeof(struct task_security_struct), GFP_KERNEL); | 125 | tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL); |
126 | if (!tsec) | 126 | if (!tsec) |
127 | return -ENOMEM; | 127 | return -ENOMEM; |
128 | 128 | ||
129 | memset(tsec, 0, sizeof(struct task_security_struct)); | ||
130 | tsec->magic = SELINUX_MAGIC; | 129 | tsec->magic = SELINUX_MAGIC; |
131 | tsec->task = task; | 130 | tsec->task = task; |
132 | tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED; | 131 | tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED; |
@@ -151,11 +150,10 @@ static int inode_alloc_security(struct inode *inode) | |||
151 | struct task_security_struct *tsec = current->security; | 150 | struct task_security_struct *tsec = current->security; |
152 | struct inode_security_struct *isec; | 151 | struct inode_security_struct *isec; |
153 | 152 | ||
154 | isec = kmalloc(sizeof(struct inode_security_struct), GFP_KERNEL); | 153 | isec = kzalloc(sizeof(struct inode_security_struct), GFP_KERNEL); |
155 | if (!isec) | 154 | if (!isec) |
156 | return -ENOMEM; | 155 | return -ENOMEM; |
157 | 156 | ||
158 | memset(isec, 0, sizeof(struct inode_security_struct)); | ||
159 | init_MUTEX(&isec->sem); | 157 | init_MUTEX(&isec->sem); |
160 | INIT_LIST_HEAD(&isec->list); | 158 | INIT_LIST_HEAD(&isec->list); |
161 | isec->magic = SELINUX_MAGIC; | 159 | isec->magic = SELINUX_MAGIC; |
@@ -193,11 +191,10 @@ static int file_alloc_security(struct file *file) | |||
193 | struct task_security_struct *tsec = current->security; | 191 | struct task_security_struct *tsec = current->security; |
194 | struct file_security_struct *fsec; | 192 | struct file_security_struct *fsec; |
195 | 193 | ||
196 | fsec = kmalloc(sizeof(struct file_security_struct), GFP_ATOMIC); | 194 | fsec = kzalloc(sizeof(struct file_security_struct), GFP_ATOMIC); |
197 | if (!fsec) | 195 | if (!fsec) |
198 | return -ENOMEM; | 196 | return -ENOMEM; |
199 | 197 | ||
200 | memset(fsec, 0, sizeof(struct file_security_struct)); | ||
201 | fsec->magic = SELINUX_MAGIC; | 198 | fsec->magic = SELINUX_MAGIC; |
202 | fsec->file = file; | 199 | fsec->file = file; |
203 | if (tsec && tsec->magic == SELINUX_MAGIC) { | 200 | if (tsec && tsec->magic == SELINUX_MAGIC) { |
@@ -227,11 +224,10 @@ static int superblock_alloc_security(struct super_block *sb) | |||
227 | { | 224 | { |
228 | struct superblock_security_struct *sbsec; | 225 | struct superblock_security_struct *sbsec; |
229 | 226 | ||
230 | sbsec = kmalloc(sizeof(struct superblock_security_struct), GFP_KERNEL); | 227 | sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL); |
231 | if (!sbsec) | 228 | if (!sbsec) |
232 | return -ENOMEM; | 229 | return -ENOMEM; |
233 | 230 | ||
234 | memset(sbsec, 0, sizeof(struct superblock_security_struct)); | ||
235 | init_MUTEX(&sbsec->sem); | 231 | init_MUTEX(&sbsec->sem); |
236 | INIT_LIST_HEAD(&sbsec->list); | 232 | INIT_LIST_HEAD(&sbsec->list); |
237 | INIT_LIST_HEAD(&sbsec->isec_head); | 233 | INIT_LIST_HEAD(&sbsec->isec_head); |
@@ -269,11 +265,10 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) | |||
269 | if (family != PF_UNIX) | 265 | if (family != PF_UNIX) |
270 | return 0; | 266 | return 0; |
271 | 267 | ||
272 | ssec = kmalloc(sizeof(*ssec), priority); | 268 | ssec = kzalloc(sizeof(*ssec), priority); |
273 | if (!ssec) | 269 | if (!ssec) |
274 | return -ENOMEM; | 270 | return -ENOMEM; |
275 | 271 | ||
276 | memset(ssec, 0, sizeof(*ssec)); | ||
277 | ssec->magic = SELINUX_MAGIC; | 272 | ssec->magic = SELINUX_MAGIC; |
278 | ssec->sk = sk; | 273 | ssec->sk = sk; |
279 | ssec->peer_sid = SECINITSID_UNLABELED; | 274 | ssec->peer_sid = SECINITSID_UNLABELED; |
@@ -1483,11 +1478,10 @@ static int selinux_bprm_alloc_security(struct linux_binprm *bprm) | |||
1483 | { | 1478 | { |
1484 | struct bprm_security_struct *bsec; | 1479 | struct bprm_security_struct *bsec; |
1485 | 1480 | ||
1486 | bsec = kmalloc(sizeof(struct bprm_security_struct), GFP_KERNEL); | 1481 | bsec = kzalloc(sizeof(struct bprm_security_struct), GFP_KERNEL); |
1487 | if (!bsec) | 1482 | if (!bsec) |
1488 | return -ENOMEM; | 1483 | return -ENOMEM; |
1489 | 1484 | ||
1490 | memset(bsec, 0, sizeof *bsec); | ||
1491 | bsec->magic = SELINUX_MAGIC; | 1485 | bsec->magic = SELINUX_MAGIC; |
1492 | bsec->bprm = bprm; | 1486 | bsec->bprm = bprm; |
1493 | bsec->sid = SECINITSID_UNLABELED; | 1487 | bsec->sid = SECINITSID_UNLABELED; |
@@ -1615,7 +1609,7 @@ static inline void flush_unauthorized_files(struct files_struct * files) | |||
1615 | 1609 | ||
1616 | if (tty) { | 1610 | if (tty) { |
1617 | file_list_lock(); | 1611 | file_list_lock(); |
1618 | file = list_entry(tty->tty_files.next, typeof(*file), f_list); | 1612 | file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list); |
1619 | if (file) { | 1613 | if (file) { |
1620 | /* Revalidate access to controlling tty. | 1614 | /* Revalidate access to controlling tty. |
1621 | Use inode_has_perm on the tty inode directly rather | 1615 | Use inode_has_perm on the tty inode directly rather |
@@ -2211,12 +2205,6 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, | |||
2211 | 2205 | ||
2212 | static int selinux_inode_getxattr (struct dentry *dentry, char *name) | 2206 | static int selinux_inode_getxattr (struct dentry *dentry, char *name) |
2213 | { | 2207 | { |
2214 | struct inode *inode = dentry->d_inode; | ||
2215 | struct superblock_security_struct *sbsec = inode->i_sb->s_security; | ||
2216 | |||
2217 | if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) | ||
2218 | return -EOPNOTSUPP; | ||
2219 | |||
2220 | return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); | 2208 | return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); |
2221 | } | 2209 | } |
2222 | 2210 | ||
@@ -2247,33 +2235,54 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name) | |||
2247 | return -EACCES; | 2235 | return -EACCES; |
2248 | } | 2236 | } |
2249 | 2237 | ||
2250 | static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size) | 2238 | /* |
2239 | * Copy the in-core inode security context value to the user. If the | ||
2240 | * getxattr() prior to this succeeded, check to see if we need to | ||
2241 | * canonicalize the value to be finally returned to the user. | ||
2242 | * | ||
2243 | * Permission check is handled by selinux_inode_getxattr hook. | ||
2244 | */ | ||
2245 | static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) | ||
2251 | { | 2246 | { |
2252 | struct inode_security_struct *isec = inode->i_security; | 2247 | struct inode_security_struct *isec = inode->i_security; |
2253 | char *context; | 2248 | char *context; |
2254 | unsigned len; | 2249 | unsigned len; |
2255 | int rc; | 2250 | int rc; |
2256 | 2251 | ||
2257 | /* Permission check handled by selinux_inode_getxattr hook.*/ | 2252 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) { |
2258 | 2253 | rc = -EOPNOTSUPP; | |
2259 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) | 2254 | goto out; |
2260 | return -EOPNOTSUPP; | 2255 | } |
2261 | 2256 | ||
2262 | rc = security_sid_to_context(isec->sid, &context, &len); | 2257 | rc = security_sid_to_context(isec->sid, &context, &len); |
2263 | if (rc) | 2258 | if (rc) |
2264 | return rc; | 2259 | goto out; |
2265 | 2260 | ||
2261 | /* Probe for required buffer size */ | ||
2266 | if (!buffer || !size) { | 2262 | if (!buffer || !size) { |
2267 | kfree(context); | 2263 | rc = len; |
2268 | return len; | 2264 | goto out_free; |
2269 | } | 2265 | } |
2266 | |||
2270 | if (size < len) { | 2267 | if (size < len) { |
2271 | kfree(context); | 2268 | rc = -ERANGE; |
2272 | return -ERANGE; | 2269 | goto out_free; |
2270 | } | ||
2271 | |||
2272 | if (err > 0) { | ||
2273 | if ((len == err) && !(memcmp(context, buffer, len))) { | ||
2274 | /* Don't need to canonicalize value */ | ||
2275 | rc = err; | ||
2276 | goto out_free; | ||
2277 | } | ||
2278 | memset(buffer, 0, size); | ||
2273 | } | 2279 | } |
2274 | memcpy(buffer, context, len); | 2280 | memcpy(buffer, context, len); |
2281 | rc = len; | ||
2282 | out_free: | ||
2275 | kfree(context); | 2283 | kfree(context); |
2276 | return len; | 2284 | out: |
2285 | return rc; | ||
2277 | } | 2286 | } |
2278 | 2287 | ||
2279 | static int selinux_inode_setsecurity(struct inode *inode, const char *name, | 2288 | static int selinux_inode_setsecurity(struct inode *inode, const char *name, |
@@ -2704,8 +2713,7 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int si | |||
2704 | if (rc) | 2713 | if (rc) |
2705 | return rc; | 2714 | return rc; |
2706 | 2715 | ||
2707 | if (info && ((unsigned long)info == 1 || | 2716 | if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info))) |
2708 | (unsigned long)info == 2 || SI_FROMKERNEL(info))) | ||
2709 | return 0; | 2717 | return 0; |
2710 | 2718 | ||
2711 | if (!sig) | 2719 | if (!sig) |
@@ -3599,11 +3607,10 @@ static int ipc_alloc_security(struct task_struct *task, | |||
3599 | struct task_security_struct *tsec = task->security; | 3607 | struct task_security_struct *tsec = task->security; |
3600 | struct ipc_security_struct *isec; | 3608 | struct ipc_security_struct *isec; |
3601 | 3609 | ||
3602 | isec = kmalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); | 3610 | isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); |
3603 | if (!isec) | 3611 | if (!isec) |
3604 | return -ENOMEM; | 3612 | return -ENOMEM; |
3605 | 3613 | ||
3606 | memset(isec, 0, sizeof(struct ipc_security_struct)); | ||
3607 | isec->magic = SELINUX_MAGIC; | 3614 | isec->magic = SELINUX_MAGIC; |
3608 | isec->sclass = sclass; | 3615 | isec->sclass = sclass; |
3609 | isec->ipc_perm = perm; | 3616 | isec->ipc_perm = perm; |
@@ -3631,11 +3638,10 @@ static int msg_msg_alloc_security(struct msg_msg *msg) | |||
3631 | { | 3638 | { |
3632 | struct msg_security_struct *msec; | 3639 | struct msg_security_struct *msec; |
3633 | 3640 | ||
3634 | msec = kmalloc(sizeof(struct msg_security_struct), GFP_KERNEL); | 3641 | msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL); |
3635 | if (!msec) | 3642 | if (!msec) |
3636 | return -ENOMEM; | 3643 | return -ENOMEM; |
3637 | 3644 | ||
3638 | memset(msec, 0, sizeof(struct msg_security_struct)); | ||
3639 | msec->magic = SELINUX_MAGIC; | 3645 | msec->magic = SELINUX_MAGIC; |
3640 | msec->msg = msg; | 3646 | msec->msg = msg; |
3641 | msec->sid = SECINITSID_UNLABELED; | 3647 | msec->sid = SECINITSID_UNLABELED; |