diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 518 |
1 files changed, 232 insertions, 286 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f0e36c3492ba..1d0b37af2444 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -48,6 +48,8 @@ | |||
48 | #include <linux/fdtable.h> | 48 | #include <linux/fdtable.h> |
49 | #include <linux/namei.h> | 49 | #include <linux/namei.h> |
50 | #include <linux/mount.h> | 50 | #include <linux/mount.h> |
51 | #include <linux/fs_context.h> | ||
52 | #include <linux/fs_parser.h> | ||
51 | #include <linux/netfilter_ipv4.h> | 53 | #include <linux/netfilter_ipv4.h> |
52 | #include <linux/netfilter_ipv6.h> | 54 | #include <linux/netfilter_ipv6.h> |
53 | #include <linux/tty.h> | 55 | #include <linux/tty.h> |
@@ -79,7 +81,6 @@ | |||
79 | #include <linux/personality.h> | 81 | #include <linux/personality.h> |
80 | #include <linux/audit.h> | 82 | #include <linux/audit.h> |
81 | #include <linux/string.h> | 83 | #include <linux/string.h> |
82 | #include <linux/selinux.h> | ||
83 | #include <linux/mutex.h> | 84 | #include <linux/mutex.h> |
84 | #include <linux/posix-timers.h> | 85 | #include <linux/posix-timers.h> |
85 | #include <linux/syslog.h> | 86 | #include <linux/syslog.h> |
@@ -121,9 +122,8 @@ __setup("enforcing=", enforcing_setup); | |||
121 | #define selinux_enforcing_boot 1 | 122 | #define selinux_enforcing_boot 1 |
122 | #endif | 123 | #endif |
123 | 124 | ||
125 | int selinux_enabled __lsm_ro_after_init = 1; | ||
124 | #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM | 126 | #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM |
125 | int selinux_enabled = CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE; | ||
126 | |||
127 | static int __init selinux_enabled_setup(char *str) | 127 | static int __init selinux_enabled_setup(char *str) |
128 | { | 128 | { |
129 | unsigned long enabled; | 129 | unsigned long enabled; |
@@ -132,8 +132,6 @@ static int __init selinux_enabled_setup(char *str) | |||
132 | return 1; | 132 | return 1; |
133 | } | 133 | } |
134 | __setup("selinux=", selinux_enabled_setup); | 134 | __setup("selinux=", selinux_enabled_setup); |
135 | #else | ||
136 | int selinux_enabled = 1; | ||
137 | #endif | 135 | #endif |
138 | 136 | ||
139 | static unsigned int selinux_checkreqprot_boot = | 137 | static unsigned int selinux_checkreqprot_boot = |
@@ -149,9 +147,6 @@ static int __init checkreqprot_setup(char *str) | |||
149 | } | 147 | } |
150 | __setup("checkreqprot=", checkreqprot_setup); | 148 | __setup("checkreqprot=", checkreqprot_setup); |
151 | 149 | ||
152 | static struct kmem_cache *sel_inode_cache; | ||
153 | static struct kmem_cache *file_security_cache; | ||
154 | |||
155 | /** | 150 | /** |
156 | * selinux_secmark_enabled - Check to see if SECMARK is currently enabled | 151 | * selinux_secmark_enabled - Check to see if SECMARK is currently enabled |
157 | * | 152 | * |
@@ -214,12 +209,8 @@ static void cred_init_security(void) | |||
214 | struct cred *cred = (struct cred *) current->real_cred; | 209 | struct cred *cred = (struct cred *) current->real_cred; |
215 | struct task_security_struct *tsec; | 210 | struct task_security_struct *tsec; |
216 | 211 | ||
217 | tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL); | 212 | tsec = selinux_cred(cred); |
218 | if (!tsec) | ||
219 | panic("SELinux: Failed to initialize initial task.\n"); | ||
220 | |||
221 | tsec->osid = tsec->sid = SECINITSID_KERNEL; | 213 | tsec->osid = tsec->sid = SECINITSID_KERNEL; |
222 | cred->security = tsec; | ||
223 | } | 214 | } |
224 | 215 | ||
225 | /* | 216 | /* |
@@ -229,7 +220,7 @@ static inline u32 cred_sid(const struct cred *cred) | |||
229 | { | 220 | { |
230 | const struct task_security_struct *tsec; | 221 | const struct task_security_struct *tsec; |
231 | 222 | ||
232 | tsec = cred->security; | 223 | tsec = selinux_cred(cred); |
233 | return tsec->sid; | 224 | return tsec->sid; |
234 | } | 225 | } |
235 | 226 | ||
@@ -250,13 +241,9 @@ static inline u32 task_sid(const struct task_struct *task) | |||
250 | 241 | ||
251 | static int inode_alloc_security(struct inode *inode) | 242 | static int inode_alloc_security(struct inode *inode) |
252 | { | 243 | { |
253 | struct inode_security_struct *isec; | 244 | struct inode_security_struct *isec = selinux_inode(inode); |
254 | u32 sid = current_sid(); | 245 | u32 sid = current_sid(); |
255 | 246 | ||
256 | isec = kmem_cache_zalloc(sel_inode_cache, GFP_NOFS); | ||
257 | if (!isec) | ||
258 | return -ENOMEM; | ||
259 | |||
260 | spin_lock_init(&isec->lock); | 247 | spin_lock_init(&isec->lock); |
261 | INIT_LIST_HEAD(&isec->list); | 248 | INIT_LIST_HEAD(&isec->list); |
262 | isec->inode = inode; | 249 | isec->inode = inode; |
@@ -264,7 +251,6 @@ static int inode_alloc_security(struct inode *inode) | |||
264 | isec->sclass = SECCLASS_FILE; | 251 | isec->sclass = SECCLASS_FILE; |
265 | isec->task_sid = sid; | 252 | isec->task_sid = sid; |
266 | isec->initialized = LABEL_INVALID; | 253 | isec->initialized = LABEL_INVALID; |
267 | inode->i_security = isec; | ||
268 | 254 | ||
269 | return 0; | 255 | return 0; |
270 | } | 256 | } |
@@ -281,7 +267,7 @@ static int __inode_security_revalidate(struct inode *inode, | |||
281 | struct dentry *dentry, | 267 | struct dentry *dentry, |
282 | bool may_sleep) | 268 | bool may_sleep) |
283 | { | 269 | { |
284 | struct inode_security_struct *isec = inode->i_security; | 270 | struct inode_security_struct *isec = selinux_inode(inode); |
285 | 271 | ||
286 | might_sleep_if(may_sleep); | 272 | might_sleep_if(may_sleep); |
287 | 273 | ||
@@ -302,7 +288,7 @@ static int __inode_security_revalidate(struct inode *inode, | |||
302 | 288 | ||
303 | static struct inode_security_struct *inode_security_novalidate(struct inode *inode) | 289 | static struct inode_security_struct *inode_security_novalidate(struct inode *inode) |
304 | { | 290 | { |
305 | return inode->i_security; | 291 | return selinux_inode(inode); |
306 | } | 292 | } |
307 | 293 | ||
308 | static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu) | 294 | static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu) |
@@ -312,7 +298,7 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo | |||
312 | error = __inode_security_revalidate(inode, NULL, !rcu); | 298 | error = __inode_security_revalidate(inode, NULL, !rcu); |
313 | if (error) | 299 | if (error) |
314 | return ERR_PTR(error); | 300 | return ERR_PTR(error); |
315 | return inode->i_security; | 301 | return selinux_inode(inode); |
316 | } | 302 | } |
317 | 303 | ||
318 | /* | 304 | /* |
@@ -321,14 +307,14 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo | |||
321 | static struct inode_security_struct *inode_security(struct inode *inode) | 307 | static struct inode_security_struct *inode_security(struct inode *inode) |
322 | { | 308 | { |
323 | __inode_security_revalidate(inode, NULL, true); | 309 | __inode_security_revalidate(inode, NULL, true); |
324 | return inode->i_security; | 310 | return selinux_inode(inode); |
325 | } | 311 | } |
326 | 312 | ||
327 | static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry) | 313 | static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry) |
328 | { | 314 | { |
329 | struct inode *inode = d_backing_inode(dentry); | 315 | struct inode *inode = d_backing_inode(dentry); |
330 | 316 | ||
331 | return inode->i_security; | 317 | return selinux_inode(inode); |
332 | } | 318 | } |
333 | 319 | ||
334 | /* | 320 | /* |
@@ -339,22 +325,17 @@ static struct inode_security_struct *backing_inode_security(struct dentry *dentr | |||
339 | struct inode *inode = d_backing_inode(dentry); | 325 | struct inode *inode = d_backing_inode(dentry); |
340 | 326 | ||
341 | __inode_security_revalidate(inode, dentry, true); | 327 | __inode_security_revalidate(inode, dentry, true); |
342 | return inode->i_security; | 328 | return selinux_inode(inode); |
343 | } | ||
344 | |||
345 | static void inode_free_rcu(struct rcu_head *head) | ||
346 | { | ||
347 | struct inode_security_struct *isec; | ||
348 | |||
349 | isec = container_of(head, struct inode_security_struct, rcu); | ||
350 | kmem_cache_free(sel_inode_cache, isec); | ||
351 | } | 329 | } |
352 | 330 | ||
353 | static void inode_free_security(struct inode *inode) | 331 | static void inode_free_security(struct inode *inode) |
354 | { | 332 | { |
355 | struct inode_security_struct *isec = inode->i_security; | 333 | struct inode_security_struct *isec = selinux_inode(inode); |
356 | struct superblock_security_struct *sbsec = inode->i_sb->s_security; | 334 | struct superblock_security_struct *sbsec; |
357 | 335 | ||
336 | if (!isec) | ||
337 | return; | ||
338 | sbsec = inode->i_sb->s_security; | ||
358 | /* | 339 | /* |
359 | * As not all inode security structures are in a list, we check for | 340 | * As not all inode security structures are in a list, we check for |
360 | * empty list outside of the lock to make sure that we won't waste | 341 | * empty list outside of the lock to make sure that we won't waste |
@@ -370,42 +351,19 @@ static void inode_free_security(struct inode *inode) | |||
370 | list_del_init(&isec->list); | 351 | list_del_init(&isec->list); |
371 | spin_unlock(&sbsec->isec_lock); | 352 | spin_unlock(&sbsec->isec_lock); |
372 | } | 353 | } |
373 | |||
374 | /* | ||
375 | * The inode may still be referenced in a path walk and | ||
376 | * a call to selinux_inode_permission() can be made | ||
377 | * after inode_free_security() is called. Ideally, the VFS | ||
378 | * wouldn't do this, but fixing that is a much harder | ||
379 | * job. For now, simply free the i_security via RCU, and | ||
380 | * leave the current inode->i_security pointer intact. | ||
381 | * The inode will be freed after the RCU grace period too. | ||
382 | */ | ||
383 | call_rcu(&isec->rcu, inode_free_rcu); | ||
384 | } | 354 | } |
385 | 355 | ||
386 | static int file_alloc_security(struct file *file) | 356 | static int file_alloc_security(struct file *file) |
387 | { | 357 | { |
388 | struct file_security_struct *fsec; | 358 | struct file_security_struct *fsec = selinux_file(file); |
389 | u32 sid = current_sid(); | 359 | u32 sid = current_sid(); |
390 | 360 | ||
391 | fsec = kmem_cache_zalloc(file_security_cache, GFP_KERNEL); | ||
392 | if (!fsec) | ||
393 | return -ENOMEM; | ||
394 | |||
395 | fsec->sid = sid; | 361 | fsec->sid = sid; |
396 | fsec->fown_sid = sid; | 362 | fsec->fown_sid = sid; |
397 | file->f_security = fsec; | ||
398 | 363 | ||
399 | return 0; | 364 | return 0; |
400 | } | 365 | } |
401 | 366 | ||
402 | static void file_free_security(struct file *file) | ||
403 | { | ||
404 | struct file_security_struct *fsec = file->f_security; | ||
405 | file->f_security = NULL; | ||
406 | kmem_cache_free(file_security_cache, fsec); | ||
407 | } | ||
408 | |||
409 | static int superblock_alloc_security(struct super_block *sb) | 367 | static int superblock_alloc_security(struct super_block *sb) |
410 | { | 368 | { |
411 | struct superblock_security_struct *sbsec; | 369 | struct superblock_security_struct *sbsec; |
@@ -454,11 +412,11 @@ static inline int inode_doinit(struct inode *inode) | |||
454 | 412 | ||
455 | enum { | 413 | enum { |
456 | Opt_error = -1, | 414 | Opt_error = -1, |
457 | Opt_context = 1, | 415 | Opt_context = 0, |
416 | Opt_defcontext = 1, | ||
458 | Opt_fscontext = 2, | 417 | Opt_fscontext = 2, |
459 | Opt_defcontext = 3, | 418 | Opt_rootcontext = 3, |
460 | Opt_rootcontext = 4, | 419 | Opt_seclabel = 4, |
461 | Opt_seclabel = 5, | ||
462 | }; | 420 | }; |
463 | 421 | ||
464 | #define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg} | 422 | #define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg} |
@@ -501,7 +459,7 @@ static int may_context_mount_sb_relabel(u32 sid, | |||
501 | struct superblock_security_struct *sbsec, | 459 | struct superblock_security_struct *sbsec, |
502 | const struct cred *cred) | 460 | const struct cred *cred) |
503 | { | 461 | { |
504 | const struct task_security_struct *tsec = cred->security; | 462 | const struct task_security_struct *tsec = selinux_cred(cred); |
505 | int rc; | 463 | int rc; |
506 | 464 | ||
507 | rc = avc_has_perm(&selinux_state, | 465 | rc = avc_has_perm(&selinux_state, |
@@ -520,7 +478,7 @@ static int may_context_mount_inode_relabel(u32 sid, | |||
520 | struct superblock_security_struct *sbsec, | 478 | struct superblock_security_struct *sbsec, |
521 | const struct cred *cred) | 479 | const struct cred *cred) |
522 | { | 480 | { |
523 | const struct task_security_struct *tsec = cred->security; | 481 | const struct task_security_struct *tsec = selinux_cred(cred); |
524 | int rc; | 482 | int rc; |
525 | rc = avc_has_perm(&selinux_state, | 483 | rc = avc_has_perm(&selinux_state, |
526 | tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, | 484 | tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, |
@@ -534,16 +492,10 @@ static int may_context_mount_inode_relabel(u32 sid, | |||
534 | return rc; | 492 | return rc; |
535 | } | 493 | } |
536 | 494 | ||
537 | static int selinux_is_sblabel_mnt(struct super_block *sb) | 495 | static int selinux_is_genfs_special_handling(struct super_block *sb) |
538 | { | 496 | { |
539 | struct superblock_security_struct *sbsec = sb->s_security; | 497 | /* Special handling. Genfs but also in-core setxattr handler */ |
540 | 498 | return !strcmp(sb->s_type->name, "sysfs") || | |
541 | return sbsec->behavior == SECURITY_FS_USE_XATTR || | ||
542 | sbsec->behavior == SECURITY_FS_USE_TRANS || | ||
543 | sbsec->behavior == SECURITY_FS_USE_TASK || | ||
544 | sbsec->behavior == SECURITY_FS_USE_NATIVE || | ||
545 | /* Special handling. Genfs but also in-core setxattr handler */ | ||
546 | !strcmp(sb->s_type->name, "sysfs") || | ||
547 | !strcmp(sb->s_type->name, "pstore") || | 499 | !strcmp(sb->s_type->name, "pstore") || |
548 | !strcmp(sb->s_type->name, "debugfs") || | 500 | !strcmp(sb->s_type->name, "debugfs") || |
549 | !strcmp(sb->s_type->name, "tracefs") || | 501 | !strcmp(sb->s_type->name, "tracefs") || |
@@ -553,6 +505,34 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) | |||
553 | !strcmp(sb->s_type->name, "cgroup2"))); | 505 | !strcmp(sb->s_type->name, "cgroup2"))); |
554 | } | 506 | } |
555 | 507 | ||
508 | static int selinux_is_sblabel_mnt(struct super_block *sb) | ||
509 | { | ||
510 | struct superblock_security_struct *sbsec = sb->s_security; | ||
511 | |||
512 | /* | ||
513 | * IMPORTANT: Double-check logic in this function when adding a new | ||
514 | * SECURITY_FS_USE_* definition! | ||
515 | */ | ||
516 | BUILD_BUG_ON(SECURITY_FS_USE_MAX != 7); | ||
517 | |||
518 | switch (sbsec->behavior) { | ||
519 | case SECURITY_FS_USE_XATTR: | ||
520 | case SECURITY_FS_USE_TRANS: | ||
521 | case SECURITY_FS_USE_TASK: | ||
522 | case SECURITY_FS_USE_NATIVE: | ||
523 | return 1; | ||
524 | |||
525 | case SECURITY_FS_USE_GENFS: | ||
526 | return selinux_is_genfs_special_handling(sb); | ||
527 | |||
528 | /* Never allow relabeling on context mounts */ | ||
529 | case SECURITY_FS_USE_MNTPOINT: | ||
530 | case SECURITY_FS_USE_NONE: | ||
531 | default: | ||
532 | return 0; | ||
533 | } | ||
534 | } | ||
535 | |||
556 | static int sb_finish_set_opts(struct super_block *sb) | 536 | static int sb_finish_set_opts(struct super_block *sb) |
557 | { | 537 | { |
558 | struct superblock_security_struct *sbsec = sb->s_security; | 538 | struct superblock_security_struct *sbsec = sb->s_security; |
@@ -959,8 +939,11 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, | |||
959 | BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED)); | 939 | BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED)); |
960 | 940 | ||
961 | /* if fs is reusing a sb, make sure that the contexts match */ | 941 | /* if fs is reusing a sb, make sure that the contexts match */ |
962 | if (newsbsec->flags & SE_SBINITIALIZED) | 942 | if (newsbsec->flags & SE_SBINITIALIZED) { |
943 | if ((kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) | ||
944 | *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS; | ||
963 | return selinux_cmp_sb_context(oldsb, newsb); | 945 | return selinux_cmp_sb_context(oldsb, newsb); |
946 | } | ||
964 | 947 | ||
965 | mutex_lock(&newsbsec->lock); | 948 | mutex_lock(&newsbsec->lock); |
966 | 949 | ||
@@ -1089,6 +1072,7 @@ static int show_sid(struct seq_file *m, u32 sid) | |||
1089 | if (!rc) { | 1072 | if (!rc) { |
1090 | bool has_comma = context && strchr(context, ','); | 1073 | bool has_comma = context && strchr(context, ','); |
1091 | 1074 | ||
1075 | seq_putc(m, '='); | ||
1092 | if (has_comma) | 1076 | if (has_comma) |
1093 | seq_putc(m, '\"'); | 1077 | seq_putc(m, '\"'); |
1094 | seq_escape(m, context, "\"\n\\"); | 1078 | seq_escape(m, context, "\"\n\\"); |
@@ -1142,7 +1126,7 @@ static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb) | |||
1142 | } | 1126 | } |
1143 | if (sbsec->flags & SBLABEL_MNT) { | 1127 | if (sbsec->flags & SBLABEL_MNT) { |
1144 | seq_putc(m, ','); | 1128 | seq_putc(m, ','); |
1145 | seq_puts(m, LABELSUPP_STR); | 1129 | seq_puts(m, SECLABEL_STR); |
1146 | } | 1130 | } |
1147 | return 0; | 1131 | return 0; |
1148 | } | 1132 | } |
@@ -1374,7 +1358,7 @@ static int selinux_genfs_get_sid(struct dentry *dentry, | |||
1374 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) | 1358 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) |
1375 | { | 1359 | { |
1376 | struct superblock_security_struct *sbsec = NULL; | 1360 | struct superblock_security_struct *sbsec = NULL; |
1377 | struct inode_security_struct *isec = inode->i_security; | 1361 | struct inode_security_struct *isec = selinux_inode(inode); |
1378 | u32 task_sid, sid = 0; | 1362 | u32 task_sid, sid = 0; |
1379 | u16 sclass; | 1363 | u16 sclass; |
1380 | struct dentry *dentry; | 1364 | struct dentry *dentry; |
@@ -1621,7 +1605,7 @@ static inline u32 signal_to_av(int sig) | |||
1621 | 1605 | ||
1622 | /* Check whether a task is allowed to use a capability. */ | 1606 | /* Check whether a task is allowed to use a capability. */ |
1623 | static int cred_has_capability(const struct cred *cred, | 1607 | static int cred_has_capability(const struct cred *cred, |
1624 | int cap, int audit, bool initns) | 1608 | int cap, unsigned int opts, bool initns) |
1625 | { | 1609 | { |
1626 | struct common_audit_data ad; | 1610 | struct common_audit_data ad; |
1627 | struct av_decision avd; | 1611 | struct av_decision avd; |
@@ -1648,7 +1632,7 @@ static int cred_has_capability(const struct cred *cred, | |||
1648 | 1632 | ||
1649 | rc = avc_has_perm_noaudit(&selinux_state, | 1633 | rc = avc_has_perm_noaudit(&selinux_state, |
1650 | sid, sid, sclass, av, 0, &avd); | 1634 | sid, sid, sclass, av, 0, &avd); |
1651 | if (audit == SECURITY_CAP_AUDIT) { | 1635 | if (!(opts & CAP_OPT_NOAUDIT)) { |
1652 | int rc2 = avc_audit(&selinux_state, | 1636 | int rc2 = avc_audit(&selinux_state, |
1653 | sid, sid, sclass, av, &avd, rc, &ad, 0); | 1637 | sid, sid, sclass, av, &avd, rc, &ad, 0); |
1654 | if (rc2) | 1638 | if (rc2) |
@@ -1674,7 +1658,7 @@ static int inode_has_perm(const struct cred *cred, | |||
1674 | return 0; | 1658 | return 0; |
1675 | 1659 | ||
1676 | sid = cred_sid(cred); | 1660 | sid = cred_sid(cred); |
1677 | isec = inode->i_security; | 1661 | isec = selinux_inode(inode); |
1678 | 1662 | ||
1679 | return avc_has_perm(&selinux_state, | 1663 | return avc_has_perm(&selinux_state, |
1680 | sid, isec->sid, isec->sclass, perms, adp); | 1664 | sid, isec->sid, isec->sclass, perms, adp); |
@@ -1740,7 +1724,7 @@ static int file_has_perm(const struct cred *cred, | |||
1740 | struct file *file, | 1724 | struct file *file, |
1741 | u32 av) | 1725 | u32 av) |
1742 | { | 1726 | { |
1743 | struct file_security_struct *fsec = file->f_security; | 1727 | struct file_security_struct *fsec = selinux_file(file); |
1744 | struct inode *inode = file_inode(file); | 1728 | struct inode *inode = file_inode(file); |
1745 | struct common_audit_data ad; | 1729 | struct common_audit_data ad; |
1746 | u32 sid = cred_sid(cred); | 1730 | u32 sid = cred_sid(cred); |
@@ -1806,7 +1790,7 @@ static int may_create(struct inode *dir, | |||
1806 | struct dentry *dentry, | 1790 | struct dentry *dentry, |
1807 | u16 tclass) | 1791 | u16 tclass) |
1808 | { | 1792 | { |
1809 | const struct task_security_struct *tsec = current_security(); | 1793 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
1810 | struct inode_security_struct *dsec; | 1794 | struct inode_security_struct *dsec; |
1811 | struct superblock_security_struct *sbsec; | 1795 | struct superblock_security_struct *sbsec; |
1812 | u32 sid, newsid; | 1796 | u32 sid, newsid; |
@@ -1828,7 +1812,7 @@ static int may_create(struct inode *dir, | |||
1828 | if (rc) | 1812 | if (rc) |
1829 | return rc; | 1813 | return rc; |
1830 | 1814 | ||
1831 | rc = selinux_determine_inode_label(current_security(), dir, | 1815 | rc = selinux_determine_inode_label(selinux_cred(current_cred()), dir, |
1832 | &dentry->d_name, tclass, &newsid); | 1816 | &dentry->d_name, tclass, &newsid); |
1833 | if (rc) | 1817 | if (rc) |
1834 | return rc; | 1818 | return rc; |
@@ -2084,7 +2068,7 @@ static int selinux_binder_transfer_file(struct task_struct *from, | |||
2084 | struct file *file) | 2068 | struct file *file) |
2085 | { | 2069 | { |
2086 | u32 sid = task_sid(to); | 2070 | u32 sid = task_sid(to); |
2087 | struct file_security_struct *fsec = file->f_security; | 2071 | struct file_security_struct *fsec = selinux_file(file); |
2088 | struct dentry *dentry = file->f_path.dentry; | 2072 | struct dentry *dentry = file->f_path.dentry; |
2089 | struct inode_security_struct *isec; | 2073 | struct inode_security_struct *isec; |
2090 | struct common_audit_data ad; | 2074 | struct common_audit_data ad; |
@@ -2168,9 +2152,9 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
2168 | */ | 2152 | */ |
2169 | 2153 | ||
2170 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, | 2154 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, |
2171 | int cap, int audit) | 2155 | int cap, unsigned int opts) |
2172 | { | 2156 | { |
2173 | return cred_has_capability(cred, cap, audit, ns == &init_user_ns); | 2157 | return cred_has_capability(cred, cap, opts, ns == &init_user_ns); |
2174 | } | 2158 | } |
2175 | 2159 | ||
2176 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | 2160 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) |
@@ -2244,7 +2228,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
2244 | int rc, cap_sys_admin = 0; | 2228 | int rc, cap_sys_admin = 0; |
2245 | 2229 | ||
2246 | rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, | 2230 | rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, |
2247 | SECURITY_CAP_NOAUDIT, true); | 2231 | CAP_OPT_NOAUDIT, true); |
2248 | if (rc == 0) | 2232 | if (rc == 0) |
2249 | cap_sys_admin = 1; | 2233 | cap_sys_admin = 1; |
2250 | 2234 | ||
@@ -2335,8 +2319,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2335 | if (bprm->called_set_creds) | 2319 | if (bprm->called_set_creds) |
2336 | return 0; | 2320 | return 0; |
2337 | 2321 | ||
2338 | old_tsec = current_security(); | 2322 | old_tsec = selinux_cred(current_cred()); |
2339 | new_tsec = bprm->cred->security; | 2323 | new_tsec = selinux_cred(bprm->cred); |
2340 | isec = inode_security(inode); | 2324 | isec = inode_security(inode); |
2341 | 2325 | ||
2342 | /* Default to the current task SID. */ | 2326 | /* Default to the current task SID. */ |
@@ -2500,7 +2484,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) | |||
2500 | struct rlimit *rlim, *initrlim; | 2484 | struct rlimit *rlim, *initrlim; |
2501 | int rc, i; | 2485 | int rc, i; |
2502 | 2486 | ||
2503 | new_tsec = bprm->cred->security; | 2487 | new_tsec = selinux_cred(bprm->cred); |
2504 | if (new_tsec->sid == new_tsec->osid) | 2488 | if (new_tsec->sid == new_tsec->osid) |
2505 | return; | 2489 | return; |
2506 | 2490 | ||
@@ -2543,7 +2527,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) | |||
2543 | */ | 2527 | */ |
2544 | static void selinux_bprm_committed_creds(struct linux_binprm *bprm) | 2528 | static void selinux_bprm_committed_creds(struct linux_binprm *bprm) |
2545 | { | 2529 | { |
2546 | const struct task_security_struct *tsec = current_security(); | 2530 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
2547 | struct itimerval itimer; | 2531 | struct itimerval itimer; |
2548 | u32 osid, sid; | 2532 | u32 osid, sid; |
2549 | int rc, i; | 2533 | int rc, i; |
@@ -2761,6 +2745,76 @@ static int selinux_umount(struct vfsmount *mnt, int flags) | |||
2761 | FILESYSTEM__UNMOUNT, NULL); | 2745 | FILESYSTEM__UNMOUNT, NULL); |
2762 | } | 2746 | } |
2763 | 2747 | ||
2748 | static int selinux_fs_context_dup(struct fs_context *fc, | ||
2749 | struct fs_context *src_fc) | ||
2750 | { | ||
2751 | const struct selinux_mnt_opts *src = src_fc->security; | ||
2752 | struct selinux_mnt_opts *opts; | ||
2753 | |||
2754 | if (!src) | ||
2755 | return 0; | ||
2756 | |||
2757 | fc->security = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL); | ||
2758 | if (!fc->security) | ||
2759 | return -ENOMEM; | ||
2760 | |||
2761 | opts = fc->security; | ||
2762 | |||
2763 | if (src->fscontext) { | ||
2764 | opts->fscontext = kstrdup(src->fscontext, GFP_KERNEL); | ||
2765 | if (!opts->fscontext) | ||
2766 | return -ENOMEM; | ||
2767 | } | ||
2768 | if (src->context) { | ||
2769 | opts->context = kstrdup(src->context, GFP_KERNEL); | ||
2770 | if (!opts->context) | ||
2771 | return -ENOMEM; | ||
2772 | } | ||
2773 | if (src->rootcontext) { | ||
2774 | opts->rootcontext = kstrdup(src->rootcontext, GFP_KERNEL); | ||
2775 | if (!opts->rootcontext) | ||
2776 | return -ENOMEM; | ||
2777 | } | ||
2778 | if (src->defcontext) { | ||
2779 | opts->defcontext = kstrdup(src->defcontext, GFP_KERNEL); | ||
2780 | if (!opts->defcontext) | ||
2781 | return -ENOMEM; | ||
2782 | } | ||
2783 | return 0; | ||
2784 | } | ||
2785 | |||
2786 | static const struct fs_parameter_spec selinux_param_specs[] = { | ||
2787 | fsparam_string(CONTEXT_STR, Opt_context), | ||
2788 | fsparam_string(DEFCONTEXT_STR, Opt_defcontext), | ||
2789 | fsparam_string(FSCONTEXT_STR, Opt_fscontext), | ||
2790 | fsparam_string(ROOTCONTEXT_STR, Opt_rootcontext), | ||
2791 | fsparam_flag (SECLABEL_STR, Opt_seclabel), | ||
2792 | {} | ||
2793 | }; | ||
2794 | |||
2795 | static const struct fs_parameter_description selinux_fs_parameters = { | ||
2796 | .name = "SELinux", | ||
2797 | .specs = selinux_param_specs, | ||
2798 | }; | ||
2799 | |||
2800 | static int selinux_fs_context_parse_param(struct fs_context *fc, | ||
2801 | struct fs_parameter *param) | ||
2802 | { | ||
2803 | struct fs_parse_result result; | ||
2804 | int opt, rc; | ||
2805 | |||
2806 | opt = fs_parse(fc, &selinux_fs_parameters, param, &result); | ||
2807 | if (opt < 0) | ||
2808 | return opt; | ||
2809 | |||
2810 | rc = selinux_add_opt(opt, param->string, &fc->security); | ||
2811 | if (!rc) { | ||
2812 | param->string = NULL; | ||
2813 | rc = 1; | ||
2814 | } | ||
2815 | return rc; | ||
2816 | } | ||
2817 | |||
2764 | /* inode security operations */ | 2818 | /* inode security operations */ |
2765 | 2819 | ||
2766 | static int selinux_inode_alloc_security(struct inode *inode) | 2820 | static int selinux_inode_alloc_security(struct inode *inode) |
@@ -2780,7 +2834,7 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode, | |||
2780 | u32 newsid; | 2834 | u32 newsid; |
2781 | int rc; | 2835 | int rc; |
2782 | 2836 | ||
2783 | rc = selinux_determine_inode_label(current_security(), | 2837 | rc = selinux_determine_inode_label(selinux_cred(current_cred()), |
2784 | d_inode(dentry->d_parent), name, | 2838 | d_inode(dentry->d_parent), name, |
2785 | inode_mode_to_security_class(mode), | 2839 | inode_mode_to_security_class(mode), |
2786 | &newsid); | 2840 | &newsid); |
@@ -2800,14 +2854,14 @@ static int selinux_dentry_create_files_as(struct dentry *dentry, int mode, | |||
2800 | int rc; | 2854 | int rc; |
2801 | struct task_security_struct *tsec; | 2855 | struct task_security_struct *tsec; |
2802 | 2856 | ||
2803 | rc = selinux_determine_inode_label(old->security, | 2857 | rc = selinux_determine_inode_label(selinux_cred(old), |
2804 | d_inode(dentry->d_parent), name, | 2858 | d_inode(dentry->d_parent), name, |
2805 | inode_mode_to_security_class(mode), | 2859 | inode_mode_to_security_class(mode), |
2806 | &newsid); | 2860 | &newsid); |
2807 | if (rc) | 2861 | if (rc) |
2808 | return rc; | 2862 | return rc; |
2809 | 2863 | ||
2810 | tsec = new->security; | 2864 | tsec = selinux_cred(new); |
2811 | tsec->create_sid = newsid; | 2865 | tsec->create_sid = newsid; |
2812 | return 0; | 2866 | return 0; |
2813 | } | 2867 | } |
@@ -2817,7 +2871,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
2817 | const char **name, | 2871 | const char **name, |
2818 | void **value, size_t *len) | 2872 | void **value, size_t *len) |
2819 | { | 2873 | { |
2820 | const struct task_security_struct *tsec = current_security(); | 2874 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
2821 | struct superblock_security_struct *sbsec; | 2875 | struct superblock_security_struct *sbsec; |
2822 | u32 newsid, clen; | 2876 | u32 newsid, clen; |
2823 | int rc; | 2877 | int rc; |
@@ -2827,7 +2881,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
2827 | 2881 | ||
2828 | newsid = tsec->create_sid; | 2882 | newsid = tsec->create_sid; |
2829 | 2883 | ||
2830 | rc = selinux_determine_inode_label(current_security(), | 2884 | rc = selinux_determine_inode_label(selinux_cred(current_cred()), |
2831 | dir, qstr, | 2885 | dir, qstr, |
2832 | inode_mode_to_security_class(inode->i_mode), | 2886 | inode_mode_to_security_class(inode->i_mode), |
2833 | &newsid); | 2887 | &newsid); |
@@ -2836,7 +2890,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
2836 | 2890 | ||
2837 | /* Possibly defer initialization to selinux_complete_init. */ | 2891 | /* Possibly defer initialization to selinux_complete_init. */ |
2838 | if (sbsec->flags & SE_SBINITIALIZED) { | 2892 | if (sbsec->flags & SE_SBINITIALIZED) { |
2839 | struct inode_security_struct *isec = inode->i_security; | 2893 | struct inode_security_struct *isec = selinux_inode(inode); |
2840 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 2894 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
2841 | isec->sid = newsid; | 2895 | isec->sid = newsid; |
2842 | isec->initialized = LABEL_INITIALIZED; | 2896 | isec->initialized = LABEL_INITIALIZED; |
@@ -2925,9 +2979,8 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode, | |||
2925 | if (IS_ERR(isec)) | 2979 | if (IS_ERR(isec)) |
2926 | return PTR_ERR(isec); | 2980 | return PTR_ERR(isec); |
2927 | 2981 | ||
2928 | return avc_has_perm_flags(&selinux_state, | 2982 | return avc_has_perm(&selinux_state, |
2929 | sid, isec->sid, isec->sclass, FILE__READ, &ad, | 2983 | sid, isec->sid, isec->sclass, FILE__READ, &ad); |
2930 | rcu ? MAY_NOT_BLOCK : 0); | ||
2931 | } | 2984 | } |
2932 | 2985 | ||
2933 | static noinline int audit_inode_permission(struct inode *inode, | 2986 | static noinline int audit_inode_permission(struct inode *inode, |
@@ -2936,7 +2989,7 @@ static noinline int audit_inode_permission(struct inode *inode, | |||
2936 | unsigned flags) | 2989 | unsigned flags) |
2937 | { | 2990 | { |
2938 | struct common_audit_data ad; | 2991 | struct common_audit_data ad; |
2939 | struct inode_security_struct *isec = inode->i_security; | 2992 | struct inode_security_struct *isec = selinux_inode(inode); |
2940 | int rc; | 2993 | int rc; |
2941 | 2994 | ||
2942 | ad.type = LSM_AUDIT_DATA_INODE; | 2995 | ad.type = LSM_AUDIT_DATA_INODE; |
@@ -2982,7 +3035,9 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
2982 | return PTR_ERR(isec); | 3035 | return PTR_ERR(isec); |
2983 | 3036 | ||
2984 | rc = avc_has_perm_noaudit(&selinux_state, | 3037 | rc = avc_has_perm_noaudit(&selinux_state, |
2985 | sid, isec->sid, isec->sclass, perms, 0, &avd); | 3038 | sid, isec->sid, isec->sclass, perms, |
3039 | (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0, | ||
3040 | &avd); | ||
2986 | audited = avc_audit_required(perms, &avd, rc, | 3041 | audited = avc_audit_required(perms, &avd, rc, |
2987 | from_access ? FILE__AUDIT_ACCESS : 0, | 3042 | from_access ? FILE__AUDIT_ACCESS : 0, |
2988 | &denied); | 3043 | &denied); |
@@ -3031,11 +3086,11 @@ static int selinux_inode_getattr(const struct path *path) | |||
3031 | static bool has_cap_mac_admin(bool audit) | 3086 | static bool has_cap_mac_admin(bool audit) |
3032 | { | 3087 | { |
3033 | const struct cred *cred = current_cred(); | 3088 | const struct cred *cred = current_cred(); |
3034 | int cap_audit = audit ? SECURITY_CAP_AUDIT : SECURITY_CAP_NOAUDIT; | 3089 | unsigned int opts = audit ? CAP_OPT_NONE : CAP_OPT_NOAUDIT; |
3035 | 3090 | ||
3036 | if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, cap_audit)) | 3091 | if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, opts)) |
3037 | return false; | 3092 | return false; |
3038 | if (cred_has_capability(cred, CAP_MAC_ADMIN, cap_audit, true)) | 3093 | if (cred_has_capability(cred, CAP_MAC_ADMIN, opts, true)) |
3039 | return false; | 3094 | return false; |
3040 | return true; | 3095 | return true; |
3041 | } | 3096 | } |
@@ -3241,12 +3296,16 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, | |||
3241 | const void *value, size_t size, int flags) | 3296 | const void *value, size_t size, int flags) |
3242 | { | 3297 | { |
3243 | struct inode_security_struct *isec = inode_security_novalidate(inode); | 3298 | struct inode_security_struct *isec = inode_security_novalidate(inode); |
3299 | struct superblock_security_struct *sbsec = inode->i_sb->s_security; | ||
3244 | u32 newsid; | 3300 | u32 newsid; |
3245 | int rc; | 3301 | int rc; |
3246 | 3302 | ||
3247 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) | 3303 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) |
3248 | return -EOPNOTSUPP; | 3304 | return -EOPNOTSUPP; |
3249 | 3305 | ||
3306 | if (!(sbsec->flags & SBLABEL_MNT)) | ||
3307 | return -EOPNOTSUPP; | ||
3308 | |||
3250 | if (!value || !size) | 3309 | if (!value || !size) |
3251 | return -EACCES; | 3310 | return -EACCES; |
3252 | 3311 | ||
@@ -3289,7 +3348,7 @@ static int selinux_inode_copy_up(struct dentry *src, struct cred **new) | |||
3289 | return -ENOMEM; | 3348 | return -ENOMEM; |
3290 | } | 3349 | } |
3291 | 3350 | ||
3292 | tsec = new_creds->security; | 3351 | tsec = selinux_cred(new_creds); |
3293 | /* Get label from overlay inode and set it in create_sid */ | 3352 | /* Get label from overlay inode and set it in create_sid */ |
3294 | selinux_inode_getsecid(d_inode(src), &sid); | 3353 | selinux_inode_getsecid(d_inode(src), &sid); |
3295 | tsec->create_sid = sid; | 3354 | tsec->create_sid = sid; |
@@ -3330,7 +3389,7 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) | |||
3330 | static int selinux_file_permission(struct file *file, int mask) | 3389 | static int selinux_file_permission(struct file *file, int mask) |
3331 | { | 3390 | { |
3332 | struct inode *inode = file_inode(file); | 3391 | struct inode *inode = file_inode(file); |
3333 | struct file_security_struct *fsec = file->f_security; | 3392 | struct file_security_struct *fsec = selinux_file(file); |
3334 | struct inode_security_struct *isec; | 3393 | struct inode_security_struct *isec; |
3335 | u32 sid = current_sid(); | 3394 | u32 sid = current_sid(); |
3336 | 3395 | ||
@@ -3352,11 +3411,6 @@ static int selinux_file_alloc_security(struct file *file) | |||
3352 | return file_alloc_security(file); | 3411 | return file_alloc_security(file); |
3353 | } | 3412 | } |
3354 | 3413 | ||
3355 | static void selinux_file_free_security(struct file *file) | ||
3356 | { | ||
3357 | file_free_security(file); | ||
3358 | } | ||
3359 | |||
3360 | /* | 3414 | /* |
3361 | * Check whether a task has the ioctl permission and cmd | 3415 | * Check whether a task has the ioctl permission and cmd |
3362 | * operation to an inode. | 3416 | * operation to an inode. |
@@ -3365,7 +3419,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file, | |||
3365 | u32 requested, u16 cmd) | 3419 | u32 requested, u16 cmd) |
3366 | { | 3420 | { |
3367 | struct common_audit_data ad; | 3421 | struct common_audit_data ad; |
3368 | struct file_security_struct *fsec = file->f_security; | 3422 | struct file_security_struct *fsec = selinux_file(file); |
3369 | struct inode *inode = file_inode(file); | 3423 | struct inode *inode = file_inode(file); |
3370 | struct inode_security_struct *isec; | 3424 | struct inode_security_struct *isec; |
3371 | struct lsm_ioctlop_audit ioctl; | 3425 | struct lsm_ioctlop_audit ioctl; |
@@ -3435,7 +3489,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, | |||
3435 | case KDSKBENT: | 3489 | case KDSKBENT: |
3436 | case KDSKBSENT: | 3490 | case KDSKBSENT: |
3437 | error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, | 3491 | error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, |
3438 | SECURITY_CAP_AUDIT, true); | 3492 | CAP_OPT_NONE, true); |
3439 | break; | 3493 | break; |
3440 | 3494 | ||
3441 | /* default case assumes that the command will go | 3495 | /* default case assumes that the command will go |
@@ -3617,7 +3671,7 @@ static void selinux_file_set_fowner(struct file *file) | |||
3617 | { | 3671 | { |
3618 | struct file_security_struct *fsec; | 3672 | struct file_security_struct *fsec; |
3619 | 3673 | ||
3620 | fsec = file->f_security; | 3674 | fsec = selinux_file(file); |
3621 | fsec->fown_sid = current_sid(); | 3675 | fsec->fown_sid = current_sid(); |
3622 | } | 3676 | } |
3623 | 3677 | ||
@@ -3632,7 +3686,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk, | |||
3632 | /* struct fown_struct is never outside the context of a struct file */ | 3686 | /* struct fown_struct is never outside the context of a struct file */ |
3633 | file = container_of(fown, struct file, f_owner); | 3687 | file = container_of(fown, struct file, f_owner); |
3634 | 3688 | ||
3635 | fsec = file->f_security; | 3689 | fsec = selinux_file(file); |
3636 | 3690 | ||
3637 | if (!signum) | 3691 | if (!signum) |
3638 | perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */ | 3692 | perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */ |
@@ -3656,7 +3710,7 @@ static int selinux_file_open(struct file *file) | |||
3656 | struct file_security_struct *fsec; | 3710 | struct file_security_struct *fsec; |
3657 | struct inode_security_struct *isec; | 3711 | struct inode_security_struct *isec; |
3658 | 3712 | ||
3659 | fsec = file->f_security; | 3713 | fsec = selinux_file(file); |
3660 | isec = inode_security(file_inode(file)); | 3714 | isec = inode_security(file_inode(file)); |
3661 | /* | 3715 | /* |
3662 | * Save inode label and policy sequence number | 3716 | * Save inode label and policy sequence number |
@@ -3690,52 +3744,15 @@ static int selinux_task_alloc(struct task_struct *task, | |||
3690 | } | 3744 | } |
3691 | 3745 | ||
3692 | /* | 3746 | /* |
3693 | * allocate the SELinux part of blank credentials | ||
3694 | */ | ||
3695 | static int selinux_cred_alloc_blank(struct cred *cred, gfp_t gfp) | ||
3696 | { | ||
3697 | struct task_security_struct *tsec; | ||
3698 | |||
3699 | tsec = kzalloc(sizeof(struct task_security_struct), gfp); | ||
3700 | if (!tsec) | ||
3701 | return -ENOMEM; | ||
3702 | |||
3703 | cred->security = tsec; | ||
3704 | return 0; | ||
3705 | } | ||
3706 | |||
3707 | /* | ||
3708 | * detach and free the LSM part of a set of credentials | ||
3709 | */ | ||
3710 | static void selinux_cred_free(struct cred *cred) | ||
3711 | { | ||
3712 | struct task_security_struct *tsec = cred->security; | ||
3713 | |||
3714 | /* | ||
3715 | * cred->security == NULL if security_cred_alloc_blank() or | ||
3716 | * security_prepare_creds() returned an error. | ||
3717 | */ | ||
3718 | BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE); | ||
3719 | cred->security = (void *) 0x7UL; | ||
3720 | kfree(tsec); | ||
3721 | } | ||
3722 | |||
3723 | /* | ||
3724 | * prepare a new set of credentials for modification | 3747 | * prepare a new set of credentials for modification |
3725 | */ | 3748 | */ |
3726 | static int selinux_cred_prepare(struct cred *new, const struct cred *old, | 3749 | static int selinux_cred_prepare(struct cred *new, const struct cred *old, |
3727 | gfp_t gfp) | 3750 | gfp_t gfp) |
3728 | { | 3751 | { |
3729 | const struct task_security_struct *old_tsec; | 3752 | const struct task_security_struct *old_tsec = selinux_cred(old); |
3730 | struct task_security_struct *tsec; | 3753 | struct task_security_struct *tsec = selinux_cred(new); |
3731 | |||
3732 | old_tsec = old->security; | ||
3733 | |||
3734 | tsec = kmemdup(old_tsec, sizeof(struct task_security_struct), gfp); | ||
3735 | if (!tsec) | ||
3736 | return -ENOMEM; | ||
3737 | 3754 | ||
3738 | new->security = tsec; | 3755 | *tsec = *old_tsec; |
3739 | return 0; | 3756 | return 0; |
3740 | } | 3757 | } |
3741 | 3758 | ||
@@ -3744,8 +3761,8 @@ static int selinux_cred_prepare(struct cred *new, const struct cred *old, | |||
3744 | */ | 3761 | */ |
3745 | static void selinux_cred_transfer(struct cred *new, const struct cred *old) | 3762 | static void selinux_cred_transfer(struct cred *new, const struct cred *old) |
3746 | { | 3763 | { |
3747 | const struct task_security_struct *old_tsec = old->security; | 3764 | const struct task_security_struct *old_tsec = selinux_cred(old); |
3748 | struct task_security_struct *tsec = new->security; | 3765 | struct task_security_struct *tsec = selinux_cred(new); |
3749 | 3766 | ||
3750 | *tsec = *old_tsec; | 3767 | *tsec = *old_tsec; |
3751 | } | 3768 | } |
@@ -3761,7 +3778,7 @@ static void selinux_cred_getsecid(const struct cred *c, u32 *secid) | |||
3761 | */ | 3778 | */ |
3762 | static int selinux_kernel_act_as(struct cred *new, u32 secid) | 3779 | static int selinux_kernel_act_as(struct cred *new, u32 secid) |
3763 | { | 3780 | { |
3764 | struct task_security_struct *tsec = new->security; | 3781 | struct task_security_struct *tsec = selinux_cred(new); |
3765 | u32 sid = current_sid(); | 3782 | u32 sid = current_sid(); |
3766 | int ret; | 3783 | int ret; |
3767 | 3784 | ||
@@ -3786,7 +3803,7 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid) | |||
3786 | static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) | 3803 | static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) |
3787 | { | 3804 | { |
3788 | struct inode_security_struct *isec = inode_security(inode); | 3805 | struct inode_security_struct *isec = inode_security(inode); |
3789 | struct task_security_struct *tsec = new->security; | 3806 | struct task_security_struct *tsec = selinux_cred(new); |
3790 | u32 sid = current_sid(); | 3807 | u32 sid = current_sid(); |
3791 | int ret; | 3808 | int ret; |
3792 | 3809 | ||
@@ -3832,7 +3849,7 @@ static int selinux_kernel_module_from_file(struct file *file) | |||
3832 | ad.type = LSM_AUDIT_DATA_FILE; | 3849 | ad.type = LSM_AUDIT_DATA_FILE; |
3833 | ad.u.file = file; | 3850 | ad.u.file = file; |
3834 | 3851 | ||
3835 | fsec = file->f_security; | 3852 | fsec = selinux_file(file); |
3836 | if (sid != fsec->sid) { | 3853 | if (sid != fsec->sid) { |
3837 | rc = avc_has_perm(&selinux_state, | 3854 | rc = avc_has_perm(&selinux_state, |
3838 | sid, fsec->sid, SECCLASS_FD, FD__USE, &ad); | 3855 | sid, fsec->sid, SECCLASS_FD, FD__USE, &ad); |
@@ -3998,7 +4015,7 @@ static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info, | |||
3998 | static void selinux_task_to_inode(struct task_struct *p, | 4015 | static void selinux_task_to_inode(struct task_struct *p, |
3999 | struct inode *inode) | 4016 | struct inode *inode) |
4000 | { | 4017 | { |
4001 | struct inode_security_struct *isec = inode->i_security; | 4018 | struct inode_security_struct *isec = selinux_inode(inode); |
4002 | u32 sid = task_sid(p); | 4019 | u32 sid = task_sid(p); |
4003 | 4020 | ||
4004 | spin_lock(&isec->lock); | 4021 | spin_lock(&isec->lock); |
@@ -4335,7 +4352,7 @@ static int sock_has_perm(struct sock *sk, u32 perms) | |||
4335 | static int selinux_socket_create(int family, int type, | 4352 | static int selinux_socket_create(int family, int type, |
4336 | int protocol, int kern) | 4353 | int protocol, int kern) |
4337 | { | 4354 | { |
4338 | const struct task_security_struct *tsec = current_security(); | 4355 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
4339 | u32 newsid; | 4356 | u32 newsid; |
4340 | u16 secclass; | 4357 | u16 secclass; |
4341 | int rc; | 4358 | int rc; |
@@ -4355,7 +4372,7 @@ static int selinux_socket_create(int family, int type, | |||
4355 | static int selinux_socket_post_create(struct socket *sock, int family, | 4372 | static int selinux_socket_post_create(struct socket *sock, int family, |
4356 | int type, int protocol, int kern) | 4373 | int type, int protocol, int kern) |
4357 | { | 4374 | { |
4358 | const struct task_security_struct *tsec = current_security(); | 4375 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
4359 | struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock)); | 4376 | struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock)); |
4360 | struct sk_security_struct *sksec; | 4377 | struct sk_security_struct *sksec; |
4361 | u16 sclass = socket_type_to_security_class(family, type, protocol); | 4378 | u16 sclass = socket_type_to_security_class(family, type, protocol); |
@@ -4531,7 +4548,7 @@ err_af: | |||
4531 | } | 4548 | } |
4532 | 4549 | ||
4533 | /* This supports connect(2) and SCTP connect services such as sctp_connectx(3) | 4550 | /* This supports connect(2) and SCTP connect services such as sctp_connectx(3) |
4534 | * and sctp_sendmsg(3) as described in Documentation/security/LSM-sctp.rst | 4551 | * and sctp_sendmsg(3) as described in Documentation/security/SCTP.rst |
4535 | */ | 4552 | */ |
4536 | static int selinux_socket_connect_helper(struct socket *sock, | 4553 | static int selinux_socket_connect_helper(struct socket *sock, |
4537 | struct sockaddr *address, int addrlen) | 4554 | struct sockaddr *address, int addrlen) |
@@ -5120,6 +5137,9 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, | |||
5120 | return -EINVAL; | 5137 | return -EINVAL; |
5121 | } | 5138 | } |
5122 | 5139 | ||
5140 | if (walk_size + len > addrlen) | ||
5141 | return -EINVAL; | ||
5142 | |||
5123 | err = -EINVAL; | 5143 | err = -EINVAL; |
5124 | switch (optname) { | 5144 | switch (optname) { |
5125 | /* Bind checks */ | 5145 | /* Bind checks */ |
@@ -5236,7 +5256,7 @@ static int selinux_secmark_relabel_packet(u32 sid) | |||
5236 | const struct task_security_struct *__tsec; | 5256 | const struct task_security_struct *__tsec; |
5237 | u32 tsid; | 5257 | u32 tsid; |
5238 | 5258 | ||
5239 | __tsec = current_security(); | 5259 | __tsec = selinux_cred(current_cred()); |
5240 | tsid = __tsec->sid; | 5260 | tsid = __tsec->sid; |
5241 | 5261 | ||
5242 | return avc_has_perm(&selinux_state, | 5262 | return avc_has_perm(&selinux_state, |
@@ -5711,51 +5731,22 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | |||
5711 | return selinux_nlmsg_perm(sk, skb); | 5731 | return selinux_nlmsg_perm(sk, skb); |
5712 | } | 5732 | } |
5713 | 5733 | ||
5714 | static int ipc_alloc_security(struct kern_ipc_perm *perm, | 5734 | static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass) |
5715 | u16 sclass) | ||
5716 | { | 5735 | { |
5717 | struct ipc_security_struct *isec; | ||
5718 | |||
5719 | isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); | ||
5720 | if (!isec) | ||
5721 | return -ENOMEM; | ||
5722 | |||
5723 | isec->sclass = sclass; | 5736 | isec->sclass = sclass; |
5724 | isec->sid = current_sid(); | 5737 | isec->sid = current_sid(); |
5725 | perm->security = isec; | ||
5726 | |||
5727 | return 0; | ||
5728 | } | ||
5729 | |||
5730 | static void ipc_free_security(struct kern_ipc_perm *perm) | ||
5731 | { | ||
5732 | struct ipc_security_struct *isec = perm->security; | ||
5733 | perm->security = NULL; | ||
5734 | kfree(isec); | ||
5735 | } | 5738 | } |
5736 | 5739 | ||
5737 | static int msg_msg_alloc_security(struct msg_msg *msg) | 5740 | static int msg_msg_alloc_security(struct msg_msg *msg) |
5738 | { | 5741 | { |
5739 | struct msg_security_struct *msec; | 5742 | struct msg_security_struct *msec; |
5740 | 5743 | ||
5741 | msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL); | 5744 | msec = selinux_msg_msg(msg); |
5742 | if (!msec) | ||
5743 | return -ENOMEM; | ||
5744 | |||
5745 | msec->sid = SECINITSID_UNLABELED; | 5745 | msec->sid = SECINITSID_UNLABELED; |
5746 | msg->security = msec; | ||
5747 | 5746 | ||
5748 | return 0; | 5747 | return 0; |
5749 | } | 5748 | } |
5750 | 5749 | ||
5751 | static void msg_msg_free_security(struct msg_msg *msg) | ||
5752 | { | ||
5753 | struct msg_security_struct *msec = msg->security; | ||
5754 | |||
5755 | msg->security = NULL; | ||
5756 | kfree(msec); | ||
5757 | } | ||
5758 | |||
5759 | static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | 5750 | static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, |
5760 | u32 perms) | 5751 | u32 perms) |
5761 | { | 5752 | { |
@@ -5763,7 +5754,7 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | |||
5763 | struct common_audit_data ad; | 5754 | struct common_audit_data ad; |
5764 | u32 sid = current_sid(); | 5755 | u32 sid = current_sid(); |
5765 | 5756 | ||
5766 | isec = ipc_perms->security; | 5757 | isec = selinux_ipc(ipc_perms); |
5767 | 5758 | ||
5768 | ad.type = LSM_AUDIT_DATA_IPC; | 5759 | ad.type = LSM_AUDIT_DATA_IPC; |
5769 | ad.u.ipc_id = ipc_perms->key; | 5760 | ad.u.ipc_id = ipc_perms->key; |
@@ -5777,11 +5768,6 @@ static int selinux_msg_msg_alloc_security(struct msg_msg *msg) | |||
5777 | return msg_msg_alloc_security(msg); | 5768 | return msg_msg_alloc_security(msg); |
5778 | } | 5769 | } |
5779 | 5770 | ||
5780 | static void selinux_msg_msg_free_security(struct msg_msg *msg) | ||
5781 | { | ||
5782 | msg_msg_free_security(msg); | ||
5783 | } | ||
5784 | |||
5785 | /* message queue security operations */ | 5771 | /* message queue security operations */ |
5786 | static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) | 5772 | static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) |
5787 | { | 5773 | { |
@@ -5790,11 +5776,8 @@ static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) | |||
5790 | u32 sid = current_sid(); | 5776 | u32 sid = current_sid(); |
5791 | int rc; | 5777 | int rc; |
5792 | 5778 | ||
5793 | rc = ipc_alloc_security(msq, SECCLASS_MSGQ); | 5779 | isec = selinux_ipc(msq); |
5794 | if (rc) | 5780 | ipc_init_security(isec, SECCLASS_MSGQ); |
5795 | return rc; | ||
5796 | |||
5797 | isec = msq->security; | ||
5798 | 5781 | ||
5799 | ad.type = LSM_AUDIT_DATA_IPC; | 5782 | ad.type = LSM_AUDIT_DATA_IPC; |
5800 | ad.u.ipc_id = msq->key; | 5783 | ad.u.ipc_id = msq->key; |
@@ -5802,16 +5785,7 @@ static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) | |||
5802 | rc = avc_has_perm(&selinux_state, | 5785 | rc = avc_has_perm(&selinux_state, |
5803 | sid, isec->sid, SECCLASS_MSGQ, | 5786 | sid, isec->sid, SECCLASS_MSGQ, |
5804 | MSGQ__CREATE, &ad); | 5787 | MSGQ__CREATE, &ad); |
5805 | if (rc) { | 5788 | return rc; |
5806 | ipc_free_security(msq); | ||
5807 | return rc; | ||
5808 | } | ||
5809 | return 0; | ||
5810 | } | ||
5811 | |||
5812 | static void selinux_msg_queue_free_security(struct kern_ipc_perm *msq) | ||
5813 | { | ||
5814 | ipc_free_security(msq); | ||
5815 | } | 5789 | } |
5816 | 5790 | ||
5817 | static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) | 5791 | static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) |
@@ -5820,7 +5794,7 @@ static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) | |||
5820 | struct common_audit_data ad; | 5794 | struct common_audit_data ad; |
5821 | u32 sid = current_sid(); | 5795 | u32 sid = current_sid(); |
5822 | 5796 | ||
5823 | isec = msq->security; | 5797 | isec = selinux_ipc(msq); |
5824 | 5798 | ||
5825 | ad.type = LSM_AUDIT_DATA_IPC; | 5799 | ad.type = LSM_AUDIT_DATA_IPC; |
5826 | ad.u.ipc_id = msq->key; | 5800 | ad.u.ipc_id = msq->key; |
@@ -5869,8 +5843,8 @@ static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *m | |||
5869 | u32 sid = current_sid(); | 5843 | u32 sid = current_sid(); |
5870 | int rc; | 5844 | int rc; |
5871 | 5845 | ||
5872 | isec = msq->security; | 5846 | isec = selinux_ipc(msq); |
5873 | msec = msg->security; | 5847 | msec = selinux_msg_msg(msg); |
5874 | 5848 | ||
5875 | /* | 5849 | /* |
5876 | * First time through, need to assign label to the message | 5850 | * First time through, need to assign label to the message |
@@ -5917,8 +5891,8 @@ static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *m | |||
5917 | u32 sid = task_sid(target); | 5891 | u32 sid = task_sid(target); |
5918 | int rc; | 5892 | int rc; |
5919 | 5893 | ||
5920 | isec = msq->security; | 5894 | isec = selinux_ipc(msq); |
5921 | msec = msg->security; | 5895 | msec = selinux_msg_msg(msg); |
5922 | 5896 | ||
5923 | ad.type = LSM_AUDIT_DATA_IPC; | 5897 | ad.type = LSM_AUDIT_DATA_IPC; |
5924 | ad.u.ipc_id = msq->key; | 5898 | ad.u.ipc_id = msq->key; |
@@ -5941,11 +5915,8 @@ static int selinux_shm_alloc_security(struct kern_ipc_perm *shp) | |||
5941 | u32 sid = current_sid(); | 5915 | u32 sid = current_sid(); |
5942 | int rc; | 5916 | int rc; |
5943 | 5917 | ||
5944 | rc = ipc_alloc_security(shp, SECCLASS_SHM); | 5918 | isec = selinux_ipc(shp); |
5945 | if (rc) | 5919 | ipc_init_security(isec, SECCLASS_SHM); |
5946 | return rc; | ||
5947 | |||
5948 | isec = shp->security; | ||
5949 | 5920 | ||
5950 | ad.type = LSM_AUDIT_DATA_IPC; | 5921 | ad.type = LSM_AUDIT_DATA_IPC; |
5951 | ad.u.ipc_id = shp->key; | 5922 | ad.u.ipc_id = shp->key; |
@@ -5953,16 +5924,7 @@ static int selinux_shm_alloc_security(struct kern_ipc_perm *shp) | |||
5953 | rc = avc_has_perm(&selinux_state, | 5924 | rc = avc_has_perm(&selinux_state, |
5954 | sid, isec->sid, SECCLASS_SHM, | 5925 | sid, isec->sid, SECCLASS_SHM, |
5955 | SHM__CREATE, &ad); | 5926 | SHM__CREATE, &ad); |
5956 | if (rc) { | 5927 | return rc; |
5957 | ipc_free_security(shp); | ||
5958 | return rc; | ||
5959 | } | ||
5960 | return 0; | ||
5961 | } | ||
5962 | |||
5963 | static void selinux_shm_free_security(struct kern_ipc_perm *shp) | ||
5964 | { | ||
5965 | ipc_free_security(shp); | ||
5966 | } | 5928 | } |
5967 | 5929 | ||
5968 | static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) | 5930 | static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) |
@@ -5971,7 +5933,7 @@ static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) | |||
5971 | struct common_audit_data ad; | 5933 | struct common_audit_data ad; |
5972 | u32 sid = current_sid(); | 5934 | u32 sid = current_sid(); |
5973 | 5935 | ||
5974 | isec = shp->security; | 5936 | isec = selinux_ipc(shp); |
5975 | 5937 | ||
5976 | ad.type = LSM_AUDIT_DATA_IPC; | 5938 | ad.type = LSM_AUDIT_DATA_IPC; |
5977 | ad.u.ipc_id = shp->key; | 5939 | ad.u.ipc_id = shp->key; |
@@ -6038,11 +6000,8 @@ static int selinux_sem_alloc_security(struct kern_ipc_perm *sma) | |||
6038 | u32 sid = current_sid(); | 6000 | u32 sid = current_sid(); |
6039 | int rc; | 6001 | int rc; |
6040 | 6002 | ||
6041 | rc = ipc_alloc_security(sma, SECCLASS_SEM); | 6003 | isec = selinux_ipc(sma); |
6042 | if (rc) | 6004 | ipc_init_security(isec, SECCLASS_SEM); |
6043 | return rc; | ||
6044 | |||
6045 | isec = sma->security; | ||
6046 | 6005 | ||
6047 | ad.type = LSM_AUDIT_DATA_IPC; | 6006 | ad.type = LSM_AUDIT_DATA_IPC; |
6048 | ad.u.ipc_id = sma->key; | 6007 | ad.u.ipc_id = sma->key; |
@@ -6050,16 +6009,7 @@ static int selinux_sem_alloc_security(struct kern_ipc_perm *sma) | |||
6050 | rc = avc_has_perm(&selinux_state, | 6009 | rc = avc_has_perm(&selinux_state, |
6051 | sid, isec->sid, SECCLASS_SEM, | 6010 | sid, isec->sid, SECCLASS_SEM, |
6052 | SEM__CREATE, &ad); | 6011 | SEM__CREATE, &ad); |
6053 | if (rc) { | 6012 | return rc; |
6054 | ipc_free_security(sma); | ||
6055 | return rc; | ||
6056 | } | ||
6057 | return 0; | ||
6058 | } | ||
6059 | |||
6060 | static void selinux_sem_free_security(struct kern_ipc_perm *sma) | ||
6061 | { | ||
6062 | ipc_free_security(sma); | ||
6063 | } | 6013 | } |
6064 | 6014 | ||
6065 | static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) | 6015 | static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) |
@@ -6068,7 +6018,7 @@ static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) | |||
6068 | struct common_audit_data ad; | 6018 | struct common_audit_data ad; |
6069 | u32 sid = current_sid(); | 6019 | u32 sid = current_sid(); |
6070 | 6020 | ||
6071 | isec = sma->security; | 6021 | isec = selinux_ipc(sma); |
6072 | 6022 | ||
6073 | ad.type = LSM_AUDIT_DATA_IPC; | 6023 | ad.type = LSM_AUDIT_DATA_IPC; |
6074 | ad.u.ipc_id = sma->key; | 6024 | ad.u.ipc_id = sma->key; |
@@ -6154,7 +6104,7 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
6154 | 6104 | ||
6155 | static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | 6105 | static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) |
6156 | { | 6106 | { |
6157 | struct ipc_security_struct *isec = ipcp->security; | 6107 | struct ipc_security_struct *isec = selinux_ipc(ipcp); |
6158 | *secid = isec->sid; | 6108 | *secid = isec->sid; |
6159 | } | 6109 | } |
6160 | 6110 | ||
@@ -6173,7 +6123,7 @@ static int selinux_getprocattr(struct task_struct *p, | |||
6173 | unsigned len; | 6123 | unsigned len; |
6174 | 6124 | ||
6175 | rcu_read_lock(); | 6125 | rcu_read_lock(); |
6176 | __tsec = __task_cred(p)->security; | 6126 | __tsec = selinux_cred(__task_cred(p)); |
6177 | 6127 | ||
6178 | if (current != p) { | 6128 | if (current != p) { |
6179 | error = avc_has_perm(&selinux_state, | 6129 | error = avc_has_perm(&selinux_state, |
@@ -6296,7 +6246,7 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) | |||
6296 | operation. See selinux_bprm_set_creds for the execve | 6246 | operation. See selinux_bprm_set_creds for the execve |
6297 | checks and may_create for the file creation checks. The | 6247 | checks and may_create for the file creation checks. The |
6298 | operation will then fail if the context is not permitted. */ | 6248 | operation will then fail if the context is not permitted. */ |
6299 | tsec = new->security; | 6249 | tsec = selinux_cred(new); |
6300 | if (!strcmp(name, "exec")) { | 6250 | if (!strcmp(name, "exec")) { |
6301 | tsec->exec_sid = sid; | 6251 | tsec->exec_sid = sid; |
6302 | } else if (!strcmp(name, "fscreate")) { | 6252 | } else if (!strcmp(name, "fscreate")) { |
@@ -6380,7 +6330,7 @@ static void selinux_release_secctx(char *secdata, u32 seclen) | |||
6380 | 6330 | ||
6381 | static void selinux_inode_invalidate_secctx(struct inode *inode) | 6331 | static void selinux_inode_invalidate_secctx(struct inode *inode) |
6382 | { | 6332 | { |
6383 | struct inode_security_struct *isec = inode->i_security; | 6333 | struct inode_security_struct *isec = selinux_inode(inode); |
6384 | 6334 | ||
6385 | spin_lock(&isec->lock); | 6335 | spin_lock(&isec->lock); |
6386 | isec->initialized = LABEL_INVALID; | 6336 | isec->initialized = LABEL_INVALID; |
@@ -6392,7 +6342,10 @@ static void selinux_inode_invalidate_secctx(struct inode *inode) | |||
6392 | */ | 6342 | */ |
6393 | static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) | 6343 | static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) |
6394 | { | 6344 | { |
6395 | return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); | 6345 | int rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, |
6346 | ctx, ctxlen, 0); | ||
6347 | /* Do not return error when suppressing label (SBLABEL_MNT not set). */ | ||
6348 | return rc == -EOPNOTSUPP ? 0 : rc; | ||
6396 | } | 6349 | } |
6397 | 6350 | ||
6398 | /* | 6351 | /* |
@@ -6425,7 +6378,7 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred, | |||
6425 | if (!ksec) | 6378 | if (!ksec) |
6426 | return -ENOMEM; | 6379 | return -ENOMEM; |
6427 | 6380 | ||
6428 | tsec = cred->security; | 6381 | tsec = selinux_cred(cred); |
6429 | if (tsec->keycreate_sid) | 6382 | if (tsec->keycreate_sid) |
6430 | ksec->sid = tsec->keycreate_sid; | 6383 | ksec->sid = tsec->keycreate_sid; |
6431 | else | 6384 | else |
@@ -6688,6 +6641,14 @@ static void selinux_bpf_prog_free(struct bpf_prog_aux *aux) | |||
6688 | } | 6641 | } |
6689 | #endif | 6642 | #endif |
6690 | 6643 | ||
6644 | struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = { | ||
6645 | .lbs_cred = sizeof(struct task_security_struct), | ||
6646 | .lbs_file = sizeof(struct file_security_struct), | ||
6647 | .lbs_inode = sizeof(struct inode_security_struct), | ||
6648 | .lbs_ipc = sizeof(struct ipc_security_struct), | ||
6649 | .lbs_msg_msg = sizeof(struct msg_security_struct), | ||
6650 | }; | ||
6651 | |||
6691 | static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | 6652 | static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { |
6692 | LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), | 6653 | LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), |
6693 | LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), | 6654 | LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), |
@@ -6710,6 +6671,9 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6710 | LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), | 6671 | LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), |
6711 | LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), | 6672 | LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), |
6712 | 6673 | ||
6674 | LSM_HOOK_INIT(fs_context_dup, selinux_fs_context_dup), | ||
6675 | LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param), | ||
6676 | |||
6713 | LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), | 6677 | LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), |
6714 | LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), | 6678 | LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), |
6715 | LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts), | 6679 | LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts), |
@@ -6757,7 +6721,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6757 | 6721 | ||
6758 | LSM_HOOK_INIT(file_permission, selinux_file_permission), | 6722 | LSM_HOOK_INIT(file_permission, selinux_file_permission), |
6759 | LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), | 6723 | LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), |
6760 | LSM_HOOK_INIT(file_free_security, selinux_file_free_security), | ||
6761 | LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), | 6724 | LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), |
6762 | LSM_HOOK_INIT(mmap_file, selinux_mmap_file), | 6725 | LSM_HOOK_INIT(mmap_file, selinux_mmap_file), |
6763 | LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr), | 6726 | LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr), |
@@ -6771,8 +6734,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6771 | LSM_HOOK_INIT(file_open, selinux_file_open), | 6734 | LSM_HOOK_INIT(file_open, selinux_file_open), |
6772 | 6735 | ||
6773 | LSM_HOOK_INIT(task_alloc, selinux_task_alloc), | 6736 | LSM_HOOK_INIT(task_alloc, selinux_task_alloc), |
6774 | LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank), | ||
6775 | LSM_HOOK_INIT(cred_free, selinux_cred_free), | ||
6776 | LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), | 6737 | LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), |
6777 | LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer), | 6738 | LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer), |
6778 | LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid), | 6739 | LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid), |
@@ -6800,24 +6761,20 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6800 | LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid), | 6761 | LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid), |
6801 | 6762 | ||
6802 | LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security), | 6763 | LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security), |
6803 | LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security), | ||
6804 | 6764 | ||
6805 | LSM_HOOK_INIT(msg_queue_alloc_security, | 6765 | LSM_HOOK_INIT(msg_queue_alloc_security, |
6806 | selinux_msg_queue_alloc_security), | 6766 | selinux_msg_queue_alloc_security), |
6807 | LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security), | ||
6808 | LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate), | 6767 | LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate), |
6809 | LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl), | 6768 | LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl), |
6810 | LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd), | 6769 | LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd), |
6811 | LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv), | 6770 | LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv), |
6812 | 6771 | ||
6813 | LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security), | 6772 | LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security), |
6814 | LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security), | ||
6815 | LSM_HOOK_INIT(shm_associate, selinux_shm_associate), | 6773 | LSM_HOOK_INIT(shm_associate, selinux_shm_associate), |
6816 | LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl), | 6774 | LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl), |
6817 | LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat), | 6775 | LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat), |
6818 | 6776 | ||
6819 | LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), | 6777 | LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), |
6820 | LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security), | ||
6821 | LSM_HOOK_INIT(sem_associate, selinux_sem_associate), | 6778 | LSM_HOOK_INIT(sem_associate, selinux_sem_associate), |
6822 | LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl), | 6779 | LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl), |
6823 | LSM_HOOK_INIT(sem_semop, selinux_sem_semop), | 6780 | LSM_HOOK_INIT(sem_semop, selinux_sem_semop), |
@@ -6928,16 +6885,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6928 | 6885 | ||
6929 | static __init int selinux_init(void) | 6886 | static __init int selinux_init(void) |
6930 | { | 6887 | { |
6931 | if (!security_module_enable("selinux")) { | ||
6932 | selinux_enabled = 0; | ||
6933 | return 0; | ||
6934 | } | ||
6935 | |||
6936 | if (!selinux_enabled) { | ||
6937 | pr_info("SELinux: Disabled at boot.\n"); | ||
6938 | return 0; | ||
6939 | } | ||
6940 | |||
6941 | pr_info("SELinux: Initializing.\n"); | 6888 | pr_info("SELinux: Initializing.\n"); |
6942 | 6889 | ||
6943 | memset(&selinux_state, 0, sizeof(selinux_state)); | 6890 | memset(&selinux_state, 0, sizeof(selinux_state)); |
@@ -6951,12 +6898,6 @@ static __init int selinux_init(void) | |||
6951 | 6898 | ||
6952 | default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); | 6899 | default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); |
6953 | 6900 | ||
6954 | sel_inode_cache = kmem_cache_create("selinux_inode_security", | ||
6955 | sizeof(struct inode_security_struct), | ||
6956 | 0, SLAB_PANIC, NULL); | ||
6957 | file_security_cache = kmem_cache_create("selinux_file_security", | ||
6958 | sizeof(struct file_security_struct), | ||
6959 | 0, SLAB_PANIC, NULL); | ||
6960 | avc_init(); | 6901 | avc_init(); |
6961 | 6902 | ||
6962 | avtab_cache_init(); | 6903 | avtab_cache_init(); |
@@ -6978,6 +6919,8 @@ static __init int selinux_init(void) | |||
6978 | else | 6919 | else |
6979 | pr_debug("SELinux: Starting in permissive mode\n"); | 6920 | pr_debug("SELinux: Starting in permissive mode\n"); |
6980 | 6921 | ||
6922 | fs_validate_description(&selinux_fs_parameters); | ||
6923 | |||
6981 | return 0; | 6924 | return 0; |
6982 | } | 6925 | } |
6983 | 6926 | ||
@@ -6999,6 +6942,9 @@ void selinux_complete_init(void) | |||
6999 | all processes and objects when they are created. */ | 6942 | all processes and objects when they are created. */ |
7000 | DEFINE_LSM(selinux) = { | 6943 | DEFINE_LSM(selinux) = { |
7001 | .name = "selinux", | 6944 | .name = "selinux", |
6945 | .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE, | ||
6946 | .enabled = &selinux_enabled, | ||
6947 | .blobs = &selinux_blob_sizes, | ||
7002 | .init = selinux_init, | 6948 | .init = selinux_init, |
7003 | }; | 6949 | }; |
7004 | 6950 | ||