LSM/SELinux: Interfaces to allow FS to control mount options

Introduce new LSM interfaces to allow an FS to deal with their own mount
options. This includes a new string parsing function exported from the
LSM that an FS can use to get a security data blob and a new security
data blob. This is particularly useful for an FS which uses binary
mount data, like NFS, which does not pass strings into the vfs to be
handled by the loaded LSM. Also fix a BUG() in both SELinux and SMACK
when dealing with binary mount data. If the binary mount data is less
than one page the copy_page() in security_sb_copy_data() can cause an
illegal page fault and boom. Remove all NFSisms from the SELinux code
since they were broken by past NFS changes.

Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: Casey Schaufler <casey@schaufler-ca.com>
Signed-off-by: James Morris <jmorris@namei.org>

authored by Eric Paris and committed by James Morris e0007529 29e8c3c3

+211 -141
+2 -2
fs/super.c
··· 870 870 if (!mnt) 871 871 goto out; 872 872 873 - if (data) { 873 + if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { 874 874 secdata = alloc_secdata(); 875 875 if (!secdata) 876 876 goto out_mnt; 877 877 878 - error = security_sb_copy_data(type, data, secdata); 878 + error = security_sb_copy_data(data, secdata); 879 879 if (error) 880 880 goto out_free_secdata; 881 881 }
+74 -25
include/linux/security.h
··· 34 34 #include <linux/xfrm.h> 35 35 #include <net/flow.h> 36 36 37 - /* only a char in selinux superblock security struct flags */ 38 - #define FSCONTEXT_MNT 0x01 39 - #define CONTEXT_MNT 0x02 40 - #define ROOTCONTEXT_MNT 0x04 41 - #define DEFCONTEXT_MNT 0x08 42 - 43 37 extern unsigned securebits; 44 38 45 39 struct ctl_table; ··· 107 113 #define LSM_UNSAFE_PTRACE_CAP 4 108 114 109 115 #ifdef CONFIG_SECURITY 116 + 117 + struct security_mnt_opts { 118 + char **mnt_opts; 119 + int *mnt_opts_flags; 120 + int num_mnt_opts; 121 + }; 122 + 123 + static inline void security_init_mnt_opts(struct security_mnt_opts *opts) 124 + { 125 + opts->mnt_opts = NULL; 126 + opts->mnt_opts_flags = NULL; 127 + opts->num_mnt_opts = 0; 128 + } 129 + 130 + static inline void security_free_mnt_opts(struct security_mnt_opts *opts) 131 + { 132 + int i; 133 + if (opts->mnt_opts) 134 + for(i = 0; i < opts->num_mnt_opts; i++) 135 + kfree(opts->mnt_opts[i]); 136 + kfree(opts->mnt_opts); 137 + opts->mnt_opts = NULL; 138 + kfree(opts->mnt_opts_flags); 139 + opts->mnt_opts_flags = NULL; 140 + opts->num_mnt_opts = 0; 141 + } 110 142 111 143 /** 112 144 * struct security_operations - main security structure ··· 282 262 * @sb_get_mnt_opts: 283 263 * Get the security relevant mount options used for a superblock 284 264 * @sb the superblock to get security mount options from 285 - * @mount_options array for pointers to mount options 286 - * @mount_flags array of ints specifying what each mount options is 287 - * @num_opts number of options in the arrays 265 + * @opts binary data structure containing all lsm mount data 288 266 * @sb_set_mnt_opts: 289 267 * Set the security relevant mount options used for a superblock 290 268 * @sb the superblock to set security mount options for 291 - * @mount_options array for pointers to mount options 292 - * @mount_flags array of ints specifying what each mount options is 293 - * @num_opts number of options in the arrays 269 + * @opts binary data structure containing all lsm mount data 294 270 * @sb_clone_mnt_opts: 295 271 * Copy all security options from a given superblock to another 296 272 * @oldsb old superblock which contain information to clone 297 273 * @newsb new superblock which needs filled in 274 + * @sb_parse_opts_str: 275 + * Parse a string of security data filling in the opts structure 276 + * @options string containing all mount options known by the LSM 277 + * @opts binary data structure usable by the LSM 298 278 * 299 279 * Security hooks for inode operations. 300 280 * ··· 1258 1238 1259 1239 int (*sb_alloc_security) (struct super_block * sb); 1260 1240 void (*sb_free_security) (struct super_block * sb); 1261 - int (*sb_copy_data)(struct file_system_type *type, 1262 - void *orig, void *copy); 1241 + int (*sb_copy_data)(char *orig, char *copy); 1263 1242 int (*sb_kern_mount) (struct super_block *sb, void *data); 1264 1243 int (*sb_statfs) (struct dentry *dentry); 1265 1244 int (*sb_mount) (char *dev_name, struct nameidata * nd, ··· 1276 1257 void (*sb_post_pivotroot) (struct nameidata * old_nd, 1277 1258 struct nameidata * new_nd); 1278 1259 int (*sb_get_mnt_opts) (const struct super_block *sb, 1279 - char ***mount_options, int **flags, 1280 - int *num_opts); 1281 - int (*sb_set_mnt_opts) (struct super_block *sb, char **mount_options, 1282 - int *flags, int num_opts); 1260 + struct security_mnt_opts *opts); 1261 + int (*sb_set_mnt_opts) (struct super_block *sb, 1262 + struct security_mnt_opts *opts); 1283 1263 void (*sb_clone_mnt_opts) (const struct super_block *oldsb, 1284 1264 struct super_block *newsb); 1265 + int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts); 1285 1266 1286 1267 int (*inode_alloc_security) (struct inode *inode); 1287 1268 void (*inode_free_security) (struct inode *inode); ··· 1526 1507 int security_bprm_secureexec(struct linux_binprm *bprm); 1527 1508 int security_sb_alloc(struct super_block *sb); 1528 1509 void security_sb_free(struct super_block *sb); 1529 - int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy); 1510 + int security_sb_copy_data(char *orig, char *copy); 1530 1511 int security_sb_kern_mount(struct super_block *sb, void *data); 1531 1512 int security_sb_statfs(struct dentry *dentry); 1532 1513 int security_sb_mount(char *dev_name, struct nameidata *nd, ··· 1539 1520 void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd); 1540 1521 int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); 1541 1522 void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); 1542 - int security_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options, 1543 - int **flags, int *num_opts); 1544 - int security_sb_set_mnt_opts(struct super_block *sb, char **mount_options, 1545 - int *flags, int num_opts); 1523 + int security_sb_get_mnt_opts(const struct super_block *sb, 1524 + struct security_mnt_opts *opts); 1525 + int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts); 1546 1526 void security_sb_clone_mnt_opts(const struct super_block *oldsb, 1547 1527 struct super_block *newsb); 1528 + int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts); 1548 1529 1549 1530 int security_inode_alloc(struct inode *inode); 1550 1531 void security_inode_free(struct inode *inode); ··· 1654 1635 void security_release_secctx(char *secdata, u32 seclen); 1655 1636 1656 1637 #else /* CONFIG_SECURITY */ 1638 + struct security_mnt_opts { 1639 + }; 1640 + 1641 + static inline void security_init_mnt_opts(struct security_mnt_opts *opts) 1642 + { 1643 + } 1644 + 1645 + static inline void security_free_mnt_opts(struct security_mnt_opts *opts) 1646 + { 1647 + } 1657 1648 1658 1649 /* 1659 1650 * This is the default capabilities functionality. Most of these functions ··· 1791 1762 static inline void security_sb_free (struct super_block *sb) 1792 1763 { } 1793 1764 1794 - static inline int security_sb_copy_data (struct file_system_type *type, 1795 - void *orig, void *copy) 1765 + static inline int security_sb_copy_data (char *orig, char *copy) 1796 1766 { 1797 1767 return 0; 1798 1768 } ··· 1847 1819 static inline void security_sb_post_pivotroot (struct nameidata *old_nd, 1848 1820 struct nameidata *new_nd) 1849 1821 { } 1822 + static inline int security_sb_get_mnt_opts(const struct super_block *sb, 1823 + struct security_mnt_opts *opts) 1824 + { 1825 + security_init_mnt_opts(opts); 1826 + return 0; 1827 + } 1828 + 1829 + static inline int security_sb_set_mnt_opts(struct super_block *sb, 1830 + struct security_mnt_opts *opts) 1831 + { 1832 + return 0; 1833 + } 1834 + 1835 + static inline void security_sb_clone_mnt_opts(const struct super_block *oldsb, 1836 + struct super_block *newsb) 1837 + { } 1838 + 1839 + static inline int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) 1840 + { 1841 + return 0; 1842 + } 1850 1843 1851 1844 static inline int security_inode_alloc (struct inode *inode) 1852 1845 {
+13 -10
security/dummy.c
··· 181 181 return; 182 182 } 183 183 184 - static int dummy_sb_copy_data (struct file_system_type *type, 185 - void *orig, void *copy) 184 + static int dummy_sb_copy_data (char *orig, char *copy) 186 185 { 187 186 return 0; 188 187 } ··· 244 245 return; 245 246 } 246 247 247 - static int dummy_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options, 248 - int **flags, int *num_opts) 248 + static int dummy_sb_get_mnt_opts(const struct super_block *sb, 249 + struct security_mnt_opts *opts) 249 250 { 250 - *mount_options = NULL; 251 - *flags = NULL; 252 - *num_opts = 0; 251 + security_init_mnt_opts(opts); 253 252 return 0; 254 253 } 255 254 256 - static int dummy_sb_set_mnt_opts(struct super_block *sb, char **mount_options, 257 - int *flags, int num_opts) 255 + static int dummy_sb_set_mnt_opts(struct super_block *sb, 256 + struct security_mnt_opts *opts) 258 257 { 259 - if (unlikely(num_opts)) 258 + if (unlikely(opts->num_mnt_opts)) 260 259 return -EOPNOTSUPP; 261 260 return 0; 262 261 } ··· 263 266 struct super_block *newsb) 264 267 { 265 268 return; 269 + } 270 + 271 + static int dummy_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) 272 + { 273 + return 0; 266 274 } 267 275 268 276 static int dummy_inode_alloc_security (struct inode *inode) ··· 1030 1028 set_to_dummy_if_null(ops, sb_get_mnt_opts); 1031 1029 set_to_dummy_if_null(ops, sb_set_mnt_opts); 1032 1030 set_to_dummy_if_null(ops, sb_clone_mnt_opts); 1031 + set_to_dummy_if_null(ops, sb_parse_opts_str); 1033 1032 set_to_dummy_if_null(ops, inode_alloc_security); 1034 1033 set_to_dummy_if_null(ops, inode_free_security); 1035 1034 set_to_dummy_if_null(ops, inode_init_security);
+15 -8
security/security.c
··· 244 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 253 int security_sb_kern_mount(struct super_block *sb, void *data) 253 254 { ··· 307 306 } 308 307 309 308 int security_sb_get_mnt_opts(const struct super_block *sb, 310 - char ***mount_options, 311 - int **flags, int *num_opts) 309 + struct security_mnt_opts *opts) 312 310 { 313 - return security_ops->sb_get_mnt_opts(sb, mount_options, flags, num_opts); 311 + return security_ops->sb_get_mnt_opts(sb, opts); 314 312 } 315 313 316 314 int security_sb_set_mnt_opts(struct super_block *sb, 317 - char **mount_options, 318 - int *flags, int num_opts) 315 + struct security_mnt_opts *opts) 319 316 { 320 - return security_ops->sb_set_mnt_opts(sb, mount_options, flags, num_opts); 317 + return security_ops->sb_set_mnt_opts(sb, opts); 321 318 } 319 + EXPORT_SYMBOL(security_sb_set_mnt_opts); 322 320 323 321 void security_sb_clone_mnt_opts(const struct super_block *oldsb, 324 322 struct super_block *newsb) 325 323 { 326 324 security_ops->sb_clone_mnt_opts(oldsb, newsb); 327 325 } 326 + EXPORT_SYMBOL(security_sb_clone_mnt_opts); 327 + 328 + int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) 329 + { 330 + return security_ops->sb_parse_opts_str(options, opts); 331 + } 332 + EXPORT_SYMBOL(security_sb_parse_opts_str); 328 333 329 334 int security_inode_alloc(struct inode *inode) 330 335 {
+101 -88
security/selinux/hooks.c
··· 443 443 * mount options, or whatever. 444 444 */ 445 445 static int selinux_get_mnt_opts(const struct super_block *sb, 446 - char ***mount_options, int **mnt_opts_flags, 447 - int *num_opts) 446 + struct security_mnt_opts *opts) 448 447 { 449 448 int rc = 0, i; 450 449 struct superblock_security_struct *sbsec = sb->s_security; ··· 451 452 u32 len; 452 453 char tmp; 453 454 454 - *num_opts = 0; 455 - *mount_options = NULL; 456 - *mnt_opts_flags = NULL; 455 + security_init_mnt_opts(opts); 457 456 458 457 if (!sbsec->initialized) 459 458 return -EINVAL; ··· 467 470 /* count the number of mount options for this sb */ 468 471 for (i = 0; i < 8; i++) { 469 472 if (tmp & 0x01) 470 - (*num_opts)++; 473 + opts->num_mnt_opts++; 471 474 tmp >>= 1; 472 475 } 473 476 474 - *mount_options = kcalloc(*num_opts, sizeof(char *), GFP_ATOMIC); 475 - if (!*mount_options) { 477 + opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); 478 + if (!opts->mnt_opts) { 476 479 rc = -ENOMEM; 477 480 goto out_free; 478 481 } 479 482 480 - *mnt_opts_flags = kcalloc(*num_opts, sizeof(int), GFP_ATOMIC); 481 - if (!*mnt_opts_flags) { 483 + opts->mnt_opts_flags = kcalloc(opts->num_mnt_opts, sizeof(int), GFP_ATOMIC); 484 + if (!opts->mnt_opts_flags) { 482 485 rc = -ENOMEM; 483 486 goto out_free; 484 487 } ··· 488 491 rc = security_sid_to_context(sbsec->sid, &context, &len); 489 492 if (rc) 490 493 goto out_free; 491 - (*mount_options)[i] = context; 492 - (*mnt_opts_flags)[i++] = FSCONTEXT_MNT; 494 + opts->mnt_opts[i] = context; 495 + opts->mnt_opts_flags[i++] = FSCONTEXT_MNT; 493 496 } 494 497 if (sbsec->flags & CONTEXT_MNT) { 495 498 rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len); 496 499 if (rc) 497 500 goto out_free; 498 - (*mount_options)[i] = context; 499 - (*mnt_opts_flags)[i++] = CONTEXT_MNT; 501 + opts->mnt_opts[i] = context; 502 + opts->mnt_opts_flags[i++] = CONTEXT_MNT; 500 503 } 501 504 if (sbsec->flags & DEFCONTEXT_MNT) { 502 505 rc = security_sid_to_context(sbsec->def_sid, &context, &len); 503 506 if (rc) 504 507 goto out_free; 505 - (*mount_options)[i] = context; 506 - (*mnt_opts_flags)[i++] = DEFCONTEXT_MNT; 508 + opts->mnt_opts[i] = context; 509 + opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; 507 510 } 508 511 if (sbsec->flags & ROOTCONTEXT_MNT) { 509 512 struct inode *root = sbsec->sb->s_root->d_inode; ··· 512 515 rc = security_sid_to_context(isec->sid, &context, &len); 513 516 if (rc) 514 517 goto out_free; 515 - (*mount_options)[i] = context; 516 - (*mnt_opts_flags)[i++] = ROOTCONTEXT_MNT; 518 + opts->mnt_opts[i] = context; 519 + opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; 517 520 } 518 521 519 - BUG_ON(i != *num_opts); 522 + BUG_ON(i != opts->num_mnt_opts); 520 523 521 524 return 0; 522 525 523 526 out_free: 524 - /* don't leak context string if security_sid_to_context had an error */ 525 - if (*mount_options && i) 526 - for (; i > 0; i--) 527 - kfree((*mount_options)[i-1]); 528 - kfree(*mount_options); 529 - *mount_options = NULL; 530 - kfree(*mnt_opts_flags); 531 - *mnt_opts_flags = NULL; 532 - *num_opts = 0; 527 + security_free_mnt_opts(opts); 533 528 return rc; 534 529 } 535 530 ··· 542 553 return 1; 543 554 return 0; 544 555 } 556 + 545 557 /* 546 558 * Allow filesystems with binary mount data to explicitly set mount point 547 559 * labeling information. 548 560 */ 549 - static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options, 550 - int *flags, int num_opts) 561 + static int selinux_set_mnt_opts(struct super_block *sb, 562 + struct security_mnt_opts *opts) 551 563 { 552 564 int rc = 0, i; 553 565 struct task_security_struct *tsec = current->security; ··· 558 568 struct inode_security_struct *root_isec = inode->i_security; 559 569 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; 560 570 u32 defcontext_sid = 0; 571 + char **mount_options = opts->mnt_opts; 572 + int *flags = opts->mnt_opts_flags; 573 + int num_opts = opts->num_mnt_opts; 561 574 562 575 mutex_lock(&sbsec->lock); 563 576 ··· 580 587 "the security server is initialized\n"); 581 588 goto out; 582 589 } 590 + 591 + /* 592 + * Binary mount data FS will come through this function twice. Once 593 + * from an explicit call and once from the generic calls from the vfs. 594 + * Since the generic VFS calls will not contain any security mount data 595 + * we need to skip the double mount verification. 596 + * 597 + * This does open a hole in which we will not notice if the first 598 + * mount using this sb set explict options and a second mount using 599 + * this sb does not set any security options. (The first options 600 + * will be used for both mounts) 601 + */ 602 + if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) 603 + && (num_opts == 0)) 604 + goto out; 583 605 584 606 /* 585 607 * parse the mount options, check if they are valid sids. ··· 800 792 mutex_unlock(&newsbsec->lock); 801 793 } 802 794 803 - /* 804 - * string mount options parsing and call set the sbsec 805 - */ 806 - static int superblock_doinit(struct super_block *sb, void *data) 795 + int selinux_parse_opts_str(char *options, struct security_mnt_opts *opts) 807 796 { 797 + char *p; 808 798 char *context = NULL, *defcontext = NULL; 809 799 char *fscontext = NULL, *rootcontext = NULL; 810 - int rc = 0; 811 - char *p, *options = data; 812 - /* selinux only know about a fixed number of mount options */ 813 - char *mnt_opts[NUM_SEL_MNT_OPTS]; 814 - int mnt_opts_flags[NUM_SEL_MNT_OPTS], num_mnt_opts = 0; 800 + int rc, num_mnt_opts = 0; 815 801 816 - if (!data) 817 - goto out; 818 - 819 - /* with the nfs patch this will become a goto out; */ 820 - if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) { 821 - const char *name = sb->s_type->name; 822 - /* NFS we understand. */ 823 - if (!strcmp(name, "nfs")) { 824 - struct nfs_mount_data *d = data; 825 - 826 - if (d->version != NFS_MOUNT_VERSION) 827 - goto out; 828 - 829 - if (d->context[0]) { 830 - context = kstrdup(d->context, GFP_KERNEL); 831 - if (!context) { 832 - rc = -ENOMEM; 833 - goto out; 834 - } 835 - } 836 - goto build_flags; 837 - } else 838 - goto out; 839 - } 802 + opts->num_mnt_opts = 0; 840 803 841 804 /* Standard string-based options. */ 842 805 while ((p = strsep(&options, "|")) != NULL) { ··· 880 901 } 881 902 } 882 903 883 - build_flags: 884 - if (fscontext) { 885 - mnt_opts[num_mnt_opts] = fscontext; 886 - mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT; 887 - } 888 - if (context) { 889 - mnt_opts[num_mnt_opts] = context; 890 - mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT; 891 - } 892 - if (rootcontext) { 893 - mnt_opts[num_mnt_opts] = rootcontext; 894 - mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT; 895 - } 896 - if (defcontext) { 897 - mnt_opts[num_mnt_opts] = defcontext; 898 - mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT; 904 + rc = -ENOMEM; 905 + opts->mnt_opts = kcalloc(NUM_SEL_MNT_OPTS, sizeof(char *), GFP_ATOMIC); 906 + if (!opts->mnt_opts) 907 + goto out_err; 908 + 909 + opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int), GFP_ATOMIC); 910 + if (!opts->mnt_opts_flags) { 911 + kfree(opts->mnt_opts); 912 + goto out_err; 899 913 } 900 914 901 - out: 902 - rc = selinux_set_mnt_opts(sb, mnt_opts, mnt_opts_flags, num_mnt_opts); 915 + if (fscontext) { 916 + opts->mnt_opts[num_mnt_opts] = fscontext; 917 + opts->mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT; 918 + } 919 + if (context) { 920 + opts->mnt_opts[num_mnt_opts] = context; 921 + opts->mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT; 922 + } 923 + if (rootcontext) { 924 + opts->mnt_opts[num_mnt_opts] = rootcontext; 925 + opts->mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT; 926 + } 927 + if (defcontext) { 928 + opts->mnt_opts[num_mnt_opts] = defcontext; 929 + opts->mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT; 930 + } 931 + 932 + opts->num_mnt_opts = num_mnt_opts; 933 + return 0; 934 + 903 935 out_err: 904 936 kfree(context); 905 937 kfree(defcontext); 906 938 kfree(fscontext); 907 939 kfree(rootcontext); 940 + return rc; 941 + } 942 + /* 943 + * string mount options parsing and call set the sbsec 944 + */ 945 + static int superblock_doinit(struct super_block *sb, void *data) 946 + { 947 + int rc = 0; 948 + char *options = data; 949 + struct security_mnt_opts opts; 950 + 951 + security_init_mnt_opts(&opts); 952 + 953 + if (!data) 954 + goto out; 955 + 956 + BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA); 957 + 958 + rc = selinux_parse_opts_str(options, &opts); 959 + if (rc) 960 + goto out_err; 961 + 962 + out: 963 + rc = selinux_set_mnt_opts(sb, &opts); 964 + 965 + out_err: 966 + security_free_mnt_opts(&opts); 908 967 return rc; 909 968 } 910 969 ··· 2270 2253 } 2271 2254 } 2272 2255 2273 - static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void *copy) 2256 + static int selinux_sb_copy_data(char *orig, char *copy) 2274 2257 { 2275 2258 int fnosec, fsec, rc = 0; 2276 2259 char *in_save, *in_curr, *in_end; ··· 2279 2262 2280 2263 in_curr = orig; 2281 2264 sec_curr = copy; 2282 - 2283 - /* Binary mount data: just copy */ 2284 - if (type->fs_flags & FS_BINARY_MOUNTDATA) { 2285 - copy_page(sec_curr, in_curr); 2286 - goto out; 2287 - } 2288 2265 2289 2266 nosec = (char *)get_zeroed_page(GFP_KERNEL); 2290 2267 if (!nosec) { ··· 5262 5251 .sb_get_mnt_opts = selinux_get_mnt_opts, 5263 5252 .sb_set_mnt_opts = selinux_set_mnt_opts, 5264 5253 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, 5254 + .sb_parse_opts_str = selinux_parse_opts_str, 5255 + 5265 5256 5266 5257 .inode_alloc_security = selinux_inode_alloc_security, 5267 5258 .inode_free_security = selinux_inode_free_security,
+5
security/selinux/include/security.h
··· 35 35 #define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP 36 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 43 struct netlbl_lsm_secattr; 39 44 40 45 extern int selinux_enabled;
+1 -8
security/smack/smack_lsm.c
··· 189 189 * Copy the Smack specific mount options out of the mount 190 190 * options list. 191 191 */ 192 - static int smack_sb_copy_data(struct file_system_type *type, void *orig, 193 - void *smackopts) 192 + static int smack_sb_copy_data(char *orig, char *smackopts) 194 193 { 195 194 char *cp, *commap, *otheropts, *dp; 196 - 197 - /* Binary mount data: just copy */ 198 - if (type->fs_flags & FS_BINARY_MOUNTDATA) { 199 - copy_page(smackopts, orig); 200 - return 0; 201 - } 202 195 203 196 otheropts = (char *)get_zeroed_page(GFP_KERNEL); 204 197 if (otheropts == NULL)