diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/dummy.c | 23 | ||||
-rw-r--r-- | security/security.c | 23 | ||||
-rw-r--r-- | security/selinux/hooks.c | 175 | ||||
-rw-r--r-- | security/selinux/include/security.h | 5 | ||||
-rw-r--r-- | security/smack/smack.h | 8 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 9 | ||||
-rw-r--r-- | security/smack/smackfs.c | 31 |
7 files changed, 148 insertions, 126 deletions
diff --git a/security/dummy.c b/security/dummy.c index 649326bf64ea..78d8f92310a4 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -181,8 +181,7 @@ static void dummy_sb_free_security (struct super_block *sb) | |||
181 | return; | 181 | return; |
182 | } | 182 | } |
183 | 183 | ||
184 | static int dummy_sb_copy_data (struct file_system_type *type, | 184 | static int dummy_sb_copy_data (char *orig, char *copy) |
185 | void *orig, void *copy) | ||
186 | { | 185 | { |
187 | return 0; | 186 | return 0; |
188 | } | 187 | } |
@@ -245,19 +244,17 @@ static void dummy_sb_post_pivotroot (struct nameidata *old_nd, struct nameidata | |||
245 | return; | 244 | return; |
246 | } | 245 | } |
247 | 246 | ||
248 | static int dummy_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options, | 247 | static int dummy_sb_get_mnt_opts(const struct super_block *sb, |
249 | int **flags, int *num_opts) | 248 | struct security_mnt_opts *opts) |
250 | { | 249 | { |
251 | *mount_options = NULL; | 250 | security_init_mnt_opts(opts); |
252 | *flags = NULL; | ||
253 | *num_opts = 0; | ||
254 | return 0; | 251 | return 0; |
255 | } | 252 | } |
256 | 253 | ||
257 | static int dummy_sb_set_mnt_opts(struct super_block *sb, char **mount_options, | 254 | static int dummy_sb_set_mnt_opts(struct super_block *sb, |
258 | int *flags, int num_opts) | 255 | struct security_mnt_opts *opts) |
259 | { | 256 | { |
260 | if (unlikely(num_opts)) | 257 | if (unlikely(opts->num_mnt_opts)) |
261 | return -EOPNOTSUPP; | 258 | return -EOPNOTSUPP; |
262 | return 0; | 259 | return 0; |
263 | } | 260 | } |
@@ -268,6 +265,11 @@ static void dummy_sb_clone_mnt_opts(const struct super_block *oldsb, | |||
268 | return; | 265 | return; |
269 | } | 266 | } |
270 | 267 | ||
268 | static int dummy_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) | ||
269 | { | ||
270 | return 0; | ||
271 | } | ||
272 | |||
271 | static int dummy_inode_alloc_security (struct inode *inode) | 273 | static int dummy_inode_alloc_security (struct inode *inode) |
272 | { | 274 | { |
273 | return 0; | 275 | return 0; |
@@ -1028,6 +1030,7 @@ void security_fixup_ops (struct security_operations *ops) | |||
1028 | set_to_dummy_if_null(ops, sb_get_mnt_opts); | 1030 | set_to_dummy_if_null(ops, sb_get_mnt_opts); |
1029 | set_to_dummy_if_null(ops, sb_set_mnt_opts); | 1031 | set_to_dummy_if_null(ops, sb_set_mnt_opts); |
1030 | set_to_dummy_if_null(ops, sb_clone_mnt_opts); | 1032 | set_to_dummy_if_null(ops, sb_clone_mnt_opts); |
1033 | set_to_dummy_if_null(ops, sb_parse_opts_str); | ||
1031 | set_to_dummy_if_null(ops, inode_alloc_security); | 1034 | set_to_dummy_if_null(ops, inode_alloc_security); |
1032 | set_to_dummy_if_null(ops, inode_free_security); | 1035 | set_to_dummy_if_null(ops, inode_free_security); |
1033 | set_to_dummy_if_null(ops, inode_init_security); | 1036 | set_to_dummy_if_null(ops, inode_init_security); |
diff --git a/security/security.c b/security/security.c index d15e56cbaade..b1387a6b416d 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -244,10 +244,11 @@ void security_sb_free(struct super_block *sb) | |||
244 | security_ops->sb_free_security(sb); | 244 | security_ops->sb_free_security(sb); |
245 | } | 245 | } |
246 | 246 | ||
247 | int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy) | 247 | int security_sb_copy_data(char *orig, char *copy) |
248 | { | 248 | { |
249 | return security_ops->sb_copy_data(type, orig, copy); | 249 | return security_ops->sb_copy_data(orig, copy); |
250 | } | 250 | } |
251 | EXPORT_SYMBOL(security_sb_copy_data); | ||
251 | 252 | ||
252 | int security_sb_kern_mount(struct super_block *sb, void *data) | 253 | int security_sb_kern_mount(struct super_block *sb, void *data) |
253 | { | 254 | { |
@@ -306,24 +307,30 @@ void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_ | |||
306 | } | 307 | } |
307 | 308 | ||
308 | int security_sb_get_mnt_opts(const struct super_block *sb, | 309 | int security_sb_get_mnt_opts(const struct super_block *sb, |
309 | char ***mount_options, | 310 | struct security_mnt_opts *opts) |
310 | int **flags, int *num_opts) | ||
311 | { | 311 | { |
312 | return security_ops->sb_get_mnt_opts(sb, mount_options, flags, num_opts); | 312 | return security_ops->sb_get_mnt_opts(sb, opts); |
313 | } | 313 | } |
314 | 314 | ||
315 | int security_sb_set_mnt_opts(struct super_block *sb, | 315 | int security_sb_set_mnt_opts(struct super_block *sb, |
316 | char **mount_options, | 316 | struct security_mnt_opts *opts) |
317 | int *flags, int num_opts) | ||
318 | { | 317 | { |
319 | return security_ops->sb_set_mnt_opts(sb, mount_options, flags, num_opts); | 318 | return security_ops->sb_set_mnt_opts(sb, opts); |
320 | } | 319 | } |
320 | EXPORT_SYMBOL(security_sb_set_mnt_opts); | ||
321 | 321 | ||
322 | void security_sb_clone_mnt_opts(const struct super_block *oldsb, | 322 | void security_sb_clone_mnt_opts(const struct super_block *oldsb, |
323 | struct super_block *newsb) | 323 | struct super_block *newsb) |
324 | { | 324 | { |
325 | security_ops->sb_clone_mnt_opts(oldsb, newsb); | 325 | security_ops->sb_clone_mnt_opts(oldsb, newsb); |
326 | } | 326 | } |
327 | EXPORT_SYMBOL(security_sb_clone_mnt_opts); | ||
328 | |||
329 | int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) | ||
330 | { | ||
331 | return security_ops->sb_parse_opts_str(options, opts); | ||
332 | } | ||
333 | EXPORT_SYMBOL(security_sb_parse_opts_str); | ||
327 | 334 | ||
328 | int security_inode_alloc(struct inode *inode) | 335 | int security_inode_alloc(struct inode *inode) |
329 | { | 336 | { |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 75c2e99bfb81..4bf4807f2d44 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -443,8 +443,7 @@ out: | |||
443 | * mount options, or whatever. | 443 | * mount options, or whatever. |
444 | */ | 444 | */ |
445 | static int selinux_get_mnt_opts(const struct super_block *sb, | 445 | static int selinux_get_mnt_opts(const struct super_block *sb, |
446 | char ***mount_options, int **mnt_opts_flags, | 446 | struct security_mnt_opts *opts) |
447 | int *num_opts) | ||
448 | { | 447 | { |
449 | int rc = 0, i; | 448 | int rc = 0, i; |
450 | struct superblock_security_struct *sbsec = sb->s_security; | 449 | struct superblock_security_struct *sbsec = sb->s_security; |
@@ -452,9 +451,7 @@ static int selinux_get_mnt_opts(const struct super_block *sb, | |||
452 | u32 len; | 451 | u32 len; |
453 | char tmp; | 452 | char tmp; |
454 | 453 | ||
455 | *num_opts = 0; | 454 | security_init_mnt_opts(opts); |
456 | *mount_options = NULL; | ||
457 | *mnt_opts_flags = NULL; | ||
458 | 455 | ||
459 | if (!sbsec->initialized) | 456 | if (!sbsec->initialized) |
460 | return -EINVAL; | 457 | return -EINVAL; |
@@ -470,18 +467,18 @@ static int selinux_get_mnt_opts(const struct super_block *sb, | |||
470 | /* count the number of mount options for this sb */ | 467 | /* count the number of mount options for this sb */ |
471 | for (i = 0; i < 8; i++) { | 468 | for (i = 0; i < 8; i++) { |
472 | if (tmp & 0x01) | 469 | if (tmp & 0x01) |
473 | (*num_opts)++; | 470 | opts->num_mnt_opts++; |
474 | tmp >>= 1; | 471 | tmp >>= 1; |
475 | } | 472 | } |
476 | 473 | ||
477 | *mount_options = kcalloc(*num_opts, sizeof(char *), GFP_ATOMIC); | 474 | opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); |
478 | if (!*mount_options) { | 475 | if (!opts->mnt_opts) { |
479 | rc = -ENOMEM; | 476 | rc = -ENOMEM; |
480 | goto out_free; | 477 | goto out_free; |
481 | } | 478 | } |
482 | 479 | ||
483 | *mnt_opts_flags = kcalloc(*num_opts, sizeof(int), GFP_ATOMIC); | 480 | opts->mnt_opts_flags = kcalloc(opts->num_mnt_opts, sizeof(int), GFP_ATOMIC); |
484 | if (!*mnt_opts_flags) { | 481 | if (!opts->mnt_opts_flags) { |
485 | rc = -ENOMEM; | 482 | rc = -ENOMEM; |
486 | goto out_free; | 483 | goto out_free; |
487 | } | 484 | } |
@@ -491,22 +488,22 @@ static int selinux_get_mnt_opts(const struct super_block *sb, | |||
491 | rc = security_sid_to_context(sbsec->sid, &context, &len); | 488 | rc = security_sid_to_context(sbsec->sid, &context, &len); |
492 | if (rc) | 489 | if (rc) |
493 | goto out_free; | 490 | goto out_free; |
494 | (*mount_options)[i] = context; | 491 | opts->mnt_opts[i] = context; |
495 | (*mnt_opts_flags)[i++] = FSCONTEXT_MNT; | 492 | opts->mnt_opts_flags[i++] = FSCONTEXT_MNT; |
496 | } | 493 | } |
497 | if (sbsec->flags & CONTEXT_MNT) { | 494 | if (sbsec->flags & CONTEXT_MNT) { |
498 | rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len); | 495 | rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len); |
499 | if (rc) | 496 | if (rc) |
500 | goto out_free; | 497 | goto out_free; |
501 | (*mount_options)[i] = context; | 498 | opts->mnt_opts[i] = context; |
502 | (*mnt_opts_flags)[i++] = CONTEXT_MNT; | 499 | opts->mnt_opts_flags[i++] = CONTEXT_MNT; |
503 | } | 500 | } |
504 | if (sbsec->flags & DEFCONTEXT_MNT) { | 501 | if (sbsec->flags & DEFCONTEXT_MNT) { |
505 | rc = security_sid_to_context(sbsec->def_sid, &context, &len); | 502 | rc = security_sid_to_context(sbsec->def_sid, &context, &len); |
506 | if (rc) | 503 | if (rc) |
507 | goto out_free; | 504 | goto out_free; |
508 | (*mount_options)[i] = context; | 505 | opts->mnt_opts[i] = context; |
509 | (*mnt_opts_flags)[i++] = DEFCONTEXT_MNT; | 506 | opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; |
510 | } | 507 | } |
511 | if (sbsec->flags & ROOTCONTEXT_MNT) { | 508 | if (sbsec->flags & ROOTCONTEXT_MNT) { |
512 | struct inode *root = sbsec->sb->s_root->d_inode; | 509 | struct inode *root = sbsec->sb->s_root->d_inode; |
@@ -515,24 +512,16 @@ static int selinux_get_mnt_opts(const struct super_block *sb, | |||
515 | rc = security_sid_to_context(isec->sid, &context, &len); | 512 | rc = security_sid_to_context(isec->sid, &context, &len); |
516 | if (rc) | 513 | if (rc) |
517 | goto out_free; | 514 | goto out_free; |
518 | (*mount_options)[i] = context; | 515 | opts->mnt_opts[i] = context; |
519 | (*mnt_opts_flags)[i++] = ROOTCONTEXT_MNT; | 516 | opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; |
520 | } | 517 | } |
521 | 518 | ||
522 | BUG_ON(i != *num_opts); | 519 | BUG_ON(i != opts->num_mnt_opts); |
523 | 520 | ||
524 | return 0; | 521 | return 0; |
525 | 522 | ||
526 | out_free: | 523 | out_free: |
527 | /* don't leak context string if security_sid_to_context had an error */ | 524 | security_free_mnt_opts(opts); |
528 | if (*mount_options && i) | ||
529 | for (; i > 0; i--) | ||
530 | kfree((*mount_options)[i-1]); | ||
531 | kfree(*mount_options); | ||
532 | *mount_options = NULL; | ||
533 | kfree(*mnt_opts_flags); | ||
534 | *mnt_opts_flags = NULL; | ||
535 | *num_opts = 0; | ||
536 | return rc; | 525 | return rc; |
537 | } | 526 | } |
538 | 527 | ||
@@ -553,12 +542,13 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag, | |||
553 | return 1; | 542 | return 1; |
554 | return 0; | 543 | return 0; |
555 | } | 544 | } |
545 | |||
556 | /* | 546 | /* |
557 | * Allow filesystems with binary mount data to explicitly set mount point | 547 | * Allow filesystems with binary mount data to explicitly set mount point |
558 | * labeling information. | 548 | * labeling information. |
559 | */ | 549 | */ |
560 | static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options, | 550 | static int selinux_set_mnt_opts(struct super_block *sb, |
561 | int *flags, int num_opts) | 551 | struct security_mnt_opts *opts) |
562 | { | 552 | { |
563 | int rc = 0, i; | 553 | int rc = 0, i; |
564 | struct task_security_struct *tsec = current->security; | 554 | struct task_security_struct *tsec = current->security; |
@@ -568,6 +558,9 @@ static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options, | |||
568 | struct inode_security_struct *root_isec = inode->i_security; | 558 | struct inode_security_struct *root_isec = inode->i_security; |
569 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; | 559 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; |
570 | u32 defcontext_sid = 0; | 560 | u32 defcontext_sid = 0; |
561 | char **mount_options = opts->mnt_opts; | ||
562 | int *flags = opts->mnt_opts_flags; | ||
563 | int num_opts = opts->num_mnt_opts; | ||
571 | 564 | ||
572 | mutex_lock(&sbsec->lock); | 565 | mutex_lock(&sbsec->lock); |
573 | 566 | ||
@@ -589,6 +582,21 @@ static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options, | |||
589 | } | 582 | } |
590 | 583 | ||
591 | /* | 584 | /* |
585 | * Binary mount data FS will come through this function twice. Once | ||
586 | * from an explicit call and once from the generic calls from the vfs. | ||
587 | * Since the generic VFS calls will not contain any security mount data | ||
588 | * we need to skip the double mount verification. | ||
589 | * | ||
590 | * This does open a hole in which we will not notice if the first | ||
591 | * mount using this sb set explict options and a second mount using | ||
592 | * this sb does not set any security options. (The first options | ||
593 | * will be used for both mounts) | ||
594 | */ | ||
595 | if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) | ||
596 | && (num_opts == 0)) | ||
597 | goto out; | ||
598 | |||
599 | /* | ||
592 | * parse the mount options, check if they are valid sids. | 600 | * parse the mount options, check if they are valid sids. |
593 | * also check if someone is trying to mount the same sb more | 601 | * also check if someone is trying to mount the same sb more |
594 | * than once with different security options. | 602 | * than once with different security options. |
@@ -792,43 +800,14 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb, | |||
792 | mutex_unlock(&newsbsec->lock); | 800 | mutex_unlock(&newsbsec->lock); |
793 | } | 801 | } |
794 | 802 | ||
795 | /* | 803 | int selinux_parse_opts_str(char *options, struct security_mnt_opts *opts) |
796 | * string mount options parsing and call set the sbsec | ||
797 | */ | ||
798 | static int superblock_doinit(struct super_block *sb, void *data) | ||
799 | { | 804 | { |
805 | char *p; | ||
800 | char *context = NULL, *defcontext = NULL; | 806 | char *context = NULL, *defcontext = NULL; |
801 | char *fscontext = NULL, *rootcontext = NULL; | 807 | char *fscontext = NULL, *rootcontext = NULL; |
802 | int rc = 0; | 808 | int rc, num_mnt_opts = 0; |
803 | char *p, *options = data; | ||
804 | /* selinux only know about a fixed number of mount options */ | ||
805 | char *mnt_opts[NUM_SEL_MNT_OPTS]; | ||
806 | int mnt_opts_flags[NUM_SEL_MNT_OPTS], num_mnt_opts = 0; | ||
807 | |||
808 | if (!data) | ||
809 | goto out; | ||
810 | 809 | ||
811 | /* with the nfs patch this will become a goto out; */ | 810 | opts->num_mnt_opts = 0; |
812 | if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) { | ||
813 | const char *name = sb->s_type->name; | ||
814 | /* NFS we understand. */ | ||
815 | if (!strcmp(name, "nfs")) { | ||
816 | struct nfs_mount_data *d = data; | ||
817 | |||
818 | if (d->version != NFS_MOUNT_VERSION) | ||
819 | goto out; | ||
820 | |||
821 | if (d->context[0]) { | ||
822 | context = kstrdup(d->context, GFP_KERNEL); | ||
823 | if (!context) { | ||
824 | rc = -ENOMEM; | ||
825 | goto out; | ||
826 | } | ||
827 | } | ||
828 | goto build_flags; | ||
829 | } else | ||
830 | goto out; | ||
831 | } | ||
832 | 811 | ||
833 | /* Standard string-based options. */ | 812 | /* Standard string-based options. */ |
834 | while ((p = strsep(&options, "|")) != NULL) { | 813 | while ((p = strsep(&options, "|")) != NULL) { |
@@ -901,26 +880,37 @@ static int superblock_doinit(struct super_block *sb, void *data) | |||
901 | } | 880 | } |
902 | } | 881 | } |
903 | 882 | ||
904 | build_flags: | 883 | rc = -ENOMEM; |
884 | opts->mnt_opts = kcalloc(NUM_SEL_MNT_OPTS, sizeof(char *), GFP_ATOMIC); | ||
885 | if (!opts->mnt_opts) | ||
886 | goto out_err; | ||
887 | |||
888 | opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int), GFP_ATOMIC); | ||
889 | if (!opts->mnt_opts_flags) { | ||
890 | kfree(opts->mnt_opts); | ||
891 | goto out_err; | ||
892 | } | ||
893 | |||
905 | if (fscontext) { | 894 | if (fscontext) { |
906 | mnt_opts[num_mnt_opts] = fscontext; | 895 | opts->mnt_opts[num_mnt_opts] = fscontext; |
907 | mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT; | 896 | opts->mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT; |
908 | } | 897 | } |
909 | if (context) { | 898 | if (context) { |
910 | mnt_opts[num_mnt_opts] = context; | 899 | opts->mnt_opts[num_mnt_opts] = context; |
911 | mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT; | 900 | opts->mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT; |
912 | } | 901 | } |
913 | if (rootcontext) { | 902 | if (rootcontext) { |
914 | mnt_opts[num_mnt_opts] = rootcontext; | 903 | opts->mnt_opts[num_mnt_opts] = rootcontext; |
915 | mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT; | 904 | opts->mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT; |
916 | } | 905 | } |
917 | if (defcontext) { | 906 | if (defcontext) { |
918 | mnt_opts[num_mnt_opts] = defcontext; | 907 | opts->mnt_opts[num_mnt_opts] = defcontext; |
919 | mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT; | 908 | opts->mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT; |
920 | } | 909 | } |
921 | 910 | ||
922 | out: | 911 | opts->num_mnt_opts = num_mnt_opts; |
923 | rc = selinux_set_mnt_opts(sb, mnt_opts, mnt_opts_flags, num_mnt_opts); | 912 | return 0; |
913 | |||
924 | out_err: | 914 | out_err: |
925 | kfree(context); | 915 | kfree(context); |
926 | kfree(defcontext); | 916 | kfree(defcontext); |
@@ -928,6 +918,33 @@ out_err: | |||
928 | kfree(rootcontext); | 918 | kfree(rootcontext); |
929 | return rc; | 919 | return rc; |
930 | } | 920 | } |
921 | /* | ||
922 | * string mount options parsing and call set the sbsec | ||
923 | */ | ||
924 | static int superblock_doinit(struct super_block *sb, void *data) | ||
925 | { | ||
926 | int rc = 0; | ||
927 | char *options = data; | ||
928 | struct security_mnt_opts opts; | ||
929 | |||
930 | security_init_mnt_opts(&opts); | ||
931 | |||
932 | if (!data) | ||
933 | goto out; | ||
934 | |||
935 | BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA); | ||
936 | |||
937 | rc = selinux_parse_opts_str(options, &opts); | ||
938 | if (rc) | ||
939 | goto out_err; | ||
940 | |||
941 | out: | ||
942 | rc = selinux_set_mnt_opts(sb, &opts); | ||
943 | |||
944 | out_err: | ||
945 | security_free_mnt_opts(&opts); | ||
946 | return rc; | ||
947 | } | ||
931 | 948 | ||
932 | static inline u16 inode_mode_to_security_class(umode_t mode) | 949 | static inline u16 inode_mode_to_security_class(umode_t mode) |
933 | { | 950 | { |
@@ -2253,7 +2270,7 @@ static inline void take_selinux_option(char **to, char *from, int *first, | |||
2253 | } | 2270 | } |
2254 | } | 2271 | } |
2255 | 2272 | ||
2256 | static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void *copy) | 2273 | static int selinux_sb_copy_data(char *orig, char *copy) |
2257 | { | 2274 | { |
2258 | int fnosec, fsec, rc = 0; | 2275 | int fnosec, fsec, rc = 0; |
2259 | char *in_save, *in_curr, *in_end; | 2276 | char *in_save, *in_curr, *in_end; |
@@ -2263,12 +2280,6 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void | |||
2263 | in_curr = orig; | 2280 | in_curr = orig; |
2264 | sec_curr = copy; | 2281 | sec_curr = copy; |
2265 | 2282 | ||
2266 | /* Binary mount data: just copy */ | ||
2267 | if (type->fs_flags & FS_BINARY_MOUNTDATA) { | ||
2268 | copy_page(sec_curr, in_curr); | ||
2269 | goto out; | ||
2270 | } | ||
2271 | |||
2272 | nosec = (char *)get_zeroed_page(GFP_KERNEL); | 2283 | nosec = (char *)get_zeroed_page(GFP_KERNEL); |
2273 | if (!nosec) { | 2284 | if (!nosec) { |
2274 | rc = -ENOMEM; | 2285 | rc = -ENOMEM; |
@@ -5251,6 +5262,8 @@ static struct security_operations selinux_ops = { | |||
5251 | .sb_get_mnt_opts = selinux_get_mnt_opts, | 5262 | .sb_get_mnt_opts = selinux_get_mnt_opts, |
5252 | .sb_set_mnt_opts = selinux_set_mnt_opts, | 5263 | .sb_set_mnt_opts = selinux_set_mnt_opts, |
5253 | .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, | 5264 | .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, |
5265 | .sb_parse_opts_str = selinux_parse_opts_str, | ||
5266 | |||
5254 | 5267 | ||
5255 | .inode_alloc_security = selinux_inode_alloc_security, | 5268 | .inode_alloc_security = selinux_inode_alloc_security, |
5256 | .inode_free_security = selinux_inode_free_security, | 5269 | .inode_free_security = selinux_inode_free_security, |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 837ce420d2f6..f7d2f03781f2 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -35,6 +35,11 @@ | |||
35 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP | 35 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | #define CONTEXT_MNT 0x01 | ||
39 | #define FSCONTEXT_MNT 0x02 | ||
40 | #define ROOTCONTEXT_MNT 0x04 | ||
41 | #define DEFCONTEXT_MNT 0x08 | ||
42 | |||
38 | struct netlbl_lsm_secattr; | 43 | struct netlbl_lsm_secattr; |
39 | 44 | ||
40 | extern int selinux_enabled; | 45 | extern int selinux_enabled; |
diff --git a/security/smack/smack.h b/security/smack/smack.h index a21a0e907ab3..62c1e982849d 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
@@ -26,14 +26,6 @@ | |||
26 | #define SMK_MAXLEN 23 | 26 | #define SMK_MAXLEN 23 |
27 | #define SMK_LABELLEN (SMK_MAXLEN+1) | 27 | #define SMK_LABELLEN (SMK_MAXLEN+1) |
28 | 28 | ||
29 | /* | ||
30 | * How many kinds of access are there? | ||
31 | * Here's your answer. | ||
32 | */ | ||
33 | #define SMK_ACCESSDASH '-' | ||
34 | #define SMK_ACCESSLOW "rwxa" | ||
35 | #define SMK_ACCESSKINDS (sizeof(SMK_ACCESSLOW) - 1) | ||
36 | |||
37 | struct superblock_smack { | 29 | struct superblock_smack { |
38 | char *smk_root; | 30 | char *smk_root; |
39 | char *smk_floor; | 31 | char *smk_floor; |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 770eb067e165..0241fd359675 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -189,17 +189,10 @@ static void smack_sb_free_security(struct super_block *sb) | |||
189 | * Copy the Smack specific mount options out of the mount | 189 | * Copy the Smack specific mount options out of the mount |
190 | * options list. | 190 | * options list. |
191 | */ | 191 | */ |
192 | static int smack_sb_copy_data(struct file_system_type *type, void *orig, | 192 | static int smack_sb_copy_data(char *orig, char *smackopts) |
193 | void *smackopts) | ||
194 | { | 193 | { |
195 | char *cp, *commap, *otheropts, *dp; | 194 | char *cp, *commap, *otheropts, *dp; |
196 | 195 | ||
197 | /* Binary mount data: just copy */ | ||
198 | if (type->fs_flags & FS_BINARY_MOUNTDATA) { | ||
199 | copy_page(smackopts, orig); | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | otheropts = (char *)get_zeroed_page(GFP_KERNEL); | 196 | otheropts = (char *)get_zeroed_page(GFP_KERNEL); |
204 | if (otheropts == NULL) | 197 | if (otheropts == NULL) |
205 | return -ENOMEM; | 198 | return -ENOMEM; |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 358c92c1a153..afe7c9b0732a 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -81,10 +81,23 @@ static struct semaphore smack_write_sem; | |||
81 | /* | 81 | /* |
82 | * Values for parsing cipso rules | 82 | * Values for parsing cipso rules |
83 | * SMK_DIGITLEN: Length of a digit field in a rule. | 83 | * SMK_DIGITLEN: Length of a digit field in a rule. |
84 | * SMK_CIPSOMEN: Minimum possible cipso rule length. | 84 | * SMK_CIPSOMIN: Minimum possible cipso rule length. |
85 | * SMK_CIPSOMAX: Maximum possible cipso rule length. | ||
85 | */ | 86 | */ |
86 | #define SMK_DIGITLEN 4 | 87 | #define SMK_DIGITLEN 4 |
87 | #define SMK_CIPSOMIN (SMK_MAXLEN + 2 * SMK_DIGITLEN) | 88 | #define SMK_CIPSOMIN (SMK_LABELLEN + 2 * SMK_DIGITLEN) |
89 | #define SMK_CIPSOMAX (SMK_CIPSOMIN + SMACK_CIPSO_MAXCATNUM * SMK_DIGITLEN) | ||
90 | |||
91 | /* | ||
92 | * Values for parsing MAC rules | ||
93 | * SMK_ACCESS: Maximum possible combination of access permissions | ||
94 | * SMK_ACCESSLEN: Maximum length for a rule access field | ||
95 | * SMK_LOADLEN: Smack rule length | ||
96 | */ | ||
97 | #define SMK_ACCESS "rwxa" | ||
98 | #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) | ||
99 | #define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) | ||
100 | |||
88 | 101 | ||
89 | /* | 102 | /* |
90 | * Seq_file read operations for /smack/load | 103 | * Seq_file read operations for /smack/load |
@@ -229,14 +242,10 @@ static void smk_set_access(struct smack_rule *srp) | |||
229 | * The format is exactly: | 242 | * The format is exactly: |
230 | * char subject[SMK_LABELLEN] | 243 | * char subject[SMK_LABELLEN] |
231 | * char object[SMK_LABELLEN] | 244 | * char object[SMK_LABELLEN] |
232 | * char access[SMK_ACCESSKINDS] | 245 | * char access[SMK_ACCESSLEN] |
233 | * | ||
234 | * Anything following is commentary and ignored. | ||
235 | * | 246 | * |
236 | * writes must be SMK_LABELLEN+SMK_LABELLEN+4 bytes. | 247 | * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes. |
237 | */ | 248 | */ |
238 | #define MINIMUM_LOAD (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSKINDS) | ||
239 | |||
240 | static ssize_t smk_write_load(struct file *file, const char __user *buf, | 249 | static ssize_t smk_write_load(struct file *file, const char __user *buf, |
241 | size_t count, loff_t *ppos) | 250 | size_t count, loff_t *ppos) |
242 | { | 251 | { |
@@ -253,7 +262,7 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf, | |||
253 | return -EPERM; | 262 | return -EPERM; |
254 | if (*ppos != 0) | 263 | if (*ppos != 0) |
255 | return -EINVAL; | 264 | return -EINVAL; |
256 | if (count < MINIMUM_LOAD) | 265 | if (count != SMK_LOADLEN) |
257 | return -EINVAL; | 266 | return -EINVAL; |
258 | 267 | ||
259 | data = kzalloc(count, GFP_KERNEL); | 268 | data = kzalloc(count, GFP_KERNEL); |
@@ -513,7 +522,7 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf, | |||
513 | return -EPERM; | 522 | return -EPERM; |
514 | if (*ppos != 0) | 523 | if (*ppos != 0) |
515 | return -EINVAL; | 524 | return -EINVAL; |
516 | if (count <= SMK_CIPSOMIN) | 525 | if (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX) |
517 | return -EINVAL; | 526 | return -EINVAL; |
518 | 527 | ||
519 | data = kzalloc(count + 1, GFP_KERNEL); | 528 | data = kzalloc(count + 1, GFP_KERNEL); |
@@ -547,7 +556,7 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf, | |||
547 | if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) | 556 | if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) |
548 | goto out; | 557 | goto out; |
549 | 558 | ||
550 | if (count <= (SMK_CIPSOMIN + catlen * SMK_DIGITLEN)) | 559 | if (count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN)) |
551 | goto out; | 560 | goto out; |
552 | 561 | ||
553 | memset(mapcatset, 0, sizeof(mapcatset)); | 562 | memset(mapcatset, 0, sizeof(mapcatset)); |