Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-2.6:
NFS: use new LSM interfaces to explicitly set mount options
LSM/SELinux: Interfaces to allow FS to control mount options

+276 -143
+3
fs/nfs/internal.h
··· 3 */ 4 5 #include <linux/mount.h> 6 7 struct nfs_string; 8 ··· 58 char *export_path; 59 int protocol; 60 } nfs_server; 61 }; 62 63 /* client.c */
··· 3 */ 4 5 #include <linux/mount.h> 6 + #include <linux/security.h> 7 8 struct nfs_string; 9 ··· 57 char *export_path; 58 int protocol; 59 } nfs_server; 60 + 61 + struct security_mnt_opts lsm_opts; 62 }; 63 64 /* client.c */
+62 -2
fs/nfs/super.c
··· 684 static int nfs_parse_mount_options(char *raw, 685 struct nfs_parsed_mount_data *mnt) 686 { 687 - char *p, *string; 688 unsigned short port = 0; 689 690 if (!raw) { 691 dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 692 return 1; 693 } 694 dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); 695 696 while ((p = strsep(&raw, ",")) != NULL) { 697 substring_t args[MAX_OPT_ARGS]; ··· 1057 out_nomem: 1058 printk(KERN_INFO "NFS: not enough memory to parse option\n"); 1059 return 0; 1060 - 1061 out_unrec_vers: 1062 printk(KERN_INFO "NFS: unrecognized NFS version number\n"); 1063 return 0; ··· 1232 args->namlen = data->namlen; 1233 args->bsize = data->bsize; 1234 args->auth_flavors[0] = data->pseudoflavor; 1235 break; 1236 default: { 1237 unsigned int len; ··· 1521 }; 1522 int error; 1523 1524 /* Validate the mount data */ 1525 error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name); 1526 if (error < 0) ··· 1562 goto error_splat_super; 1563 } 1564 1565 s->s_flags |= MS_ACTIVE; 1566 mnt->mnt_sb = s; 1567 mnt->mnt_root = mntroot; ··· 1574 out: 1575 kfree(data.nfs_server.hostname); 1576 kfree(data.mount_server.hostname); 1577 return error; 1578 1579 out_err_nosb: 1580 nfs_free_server(server); 1581 goto out; 1582 1583 error_splat_super: 1584 up_write(&s->s_umount); 1585 deactivate_super(s); ··· 1661 s->s_flags |= MS_ACTIVE; 1662 mnt->mnt_sb = s; 1663 mnt->mnt_root = mntroot; 1664 1665 dprintk("<-- nfs_xdev_get_sb() = 0\n"); 1666 return 0; ··· 1907 }; 1908 int error; 1909 1910 /* Validate the mount data */ 1911 error = nfs4_validate_mount_data(raw_data, &data, dev_name); 1912 if (error < 0) ··· 1957 kfree(data.client_address); 1958 kfree(data.nfs_server.export_path); 1959 kfree(data.nfs_server.hostname); 1960 return error; 1961 1962 out_free:
··· 684 static int nfs_parse_mount_options(char *raw, 685 struct nfs_parsed_mount_data *mnt) 686 { 687 + char *p, *string, *secdata; 688 unsigned short port = 0; 689 + int rc; 690 691 if (!raw) { 692 dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 693 return 1; 694 } 695 dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); 696 + 697 + secdata = alloc_secdata(); 698 + if (!secdata) 699 + goto out_nomem; 700 + 701 + rc = security_sb_copy_data(raw, secdata); 702 + if (rc) 703 + goto out_security_failure; 704 + 705 + rc = security_sb_parse_opts_str(secdata, &mnt->lsm_opts); 706 + if (rc) 707 + goto out_security_failure; 708 + 709 + free_secdata(secdata); 710 711 while ((p = strsep(&raw, ",")) != NULL) { 712 substring_t args[MAX_OPT_ARGS]; ··· 1042 out_nomem: 1043 printk(KERN_INFO "NFS: not enough memory to parse option\n"); 1044 return 0; 1045 + out_security_failure: 1046 + free_secdata(secdata); 1047 + printk(KERN_INFO "NFS: security options invalid: %d\n", rc); 1048 + return 0; 1049 out_unrec_vers: 1050 printk(KERN_INFO "NFS: unrecognized NFS version number\n"); 1051 return 0; ··· 1214 args->namlen = data->namlen; 1215 args->bsize = data->bsize; 1216 args->auth_flavors[0] = data->pseudoflavor; 1217 + 1218 + /* 1219 + * The legacy version 6 binary mount data from userspace has a 1220 + * field used only to transport selinux information into the 1221 + * the kernel. To continue to support that functionality we 1222 + * have a touch of selinux knowledge here in the NFS code. The 1223 + * userspace code converted context=blah to just blah so we are 1224 + * converting back to the full string selinux understands. 1225 + */ 1226 + if (data->context[0]){ 1227 + #ifdef CONFIG_SECURITY_SELINUX 1228 + int rc; 1229 + char *opts_str = kmalloc(sizeof(data->context) + 8, GFP_KERNEL); 1230 + if (!opts_str) 1231 + return -ENOMEM; 1232 + strcpy(opts_str, "context="); 1233 + data->context[NFS_MAX_CONTEXT_LEN] = '\0'; 1234 + strcat(opts_str, &data->context[0]); 1235 + rc = security_sb_parse_opts_str(opts_str, &args->lsm_opts); 1236 + kfree(opts_str); 1237 + if (rc) 1238 + return rc; 1239 + #else 1240 + return -EINVAL; 1241 + #endif 1242 + } 1243 + 1244 break; 1245 default: { 1246 unsigned int len; ··· 1476 }; 1477 int error; 1478 1479 + security_init_mnt_opts(&data.lsm_opts); 1480 + 1481 /* Validate the mount data */ 1482 error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name); 1483 if (error < 0) ··· 1515 goto error_splat_super; 1516 } 1517 1518 + error = security_sb_set_mnt_opts(s, &data.lsm_opts); 1519 + if (error) 1520 + goto error_splat_root; 1521 + 1522 s->s_flags |= MS_ACTIVE; 1523 mnt->mnt_sb = s; 1524 mnt->mnt_root = mntroot; ··· 1523 out: 1524 kfree(data.nfs_server.hostname); 1525 kfree(data.mount_server.hostname); 1526 + security_free_mnt_opts(&data.lsm_opts); 1527 return error; 1528 1529 out_err_nosb: 1530 nfs_free_server(server); 1531 goto out; 1532 1533 + error_splat_root: 1534 + dput(mntroot); 1535 error_splat_super: 1536 up_write(&s->s_umount); 1537 deactivate_super(s); ··· 1607 s->s_flags |= MS_ACTIVE; 1608 mnt->mnt_sb = s; 1609 mnt->mnt_root = mntroot; 1610 + 1611 + /* clone any lsm security options from the parent to the new sb */ 1612 + security_sb_clone_mnt_opts(data->sb, s); 1613 1614 dprintk("<-- nfs_xdev_get_sb() = 0\n"); 1615 return 0; ··· 1850 }; 1851 int error; 1852 1853 + security_init_mnt_opts(&data.lsm_opts); 1854 + 1855 /* Validate the mount data */ 1856 error = nfs4_validate_mount_data(raw_data, &data, dev_name); 1857 if (error < 0) ··· 1898 kfree(data.client_address); 1899 kfree(data.nfs_server.export_path); 1900 kfree(data.nfs_server.hostname); 1901 + security_free_mnt_opts(&data.lsm_opts); 1902 return error; 1903 1904 out_free:
+2 -2
fs/super.c
··· 870 if (!mnt) 871 goto out; 872 873 - if (data) { 874 secdata = alloc_secdata(); 875 if (!secdata) 876 goto out_mnt; 877 878 - error = security_sb_copy_data(type, data, secdata); 879 if (error) 880 goto out_free_secdata; 881 }
··· 870 if (!mnt) 871 goto out; 872 873 + if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { 874 secdata = alloc_secdata(); 875 if (!secdata) 876 goto out_mnt; 877 878 + error = security_sb_copy_data(data, secdata); 879 if (error) 880 goto out_free_secdata; 881 }
+74 -25
include/linux/security.h
··· 34 #include <linux/xfrm.h> 35 #include <net/flow.h> 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 extern unsigned securebits; 44 45 struct ctl_table; ··· 107 #define LSM_UNSAFE_PTRACE_CAP 4 108 109 #ifdef CONFIG_SECURITY 110 111 /** 112 * struct security_operations - main security structure ··· 282 * @sb_get_mnt_opts: 283 * Get the security relevant mount options used for a superblock 284 * @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 288 * @sb_set_mnt_opts: 289 * Set the security relevant mount options used for a superblock 290 * @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 294 * @sb_clone_mnt_opts: 295 * Copy all security options from a given superblock to another 296 * @oldsb old superblock which contain information to clone 297 * @newsb new superblock which needs filled in 298 * 299 * Security hooks for inode operations. 300 * ··· 1258 1259 int (*sb_alloc_security) (struct super_block * sb); 1260 void (*sb_free_security) (struct super_block * sb); 1261 - int (*sb_copy_data)(struct file_system_type *type, 1262 - void *orig, void *copy); 1263 int (*sb_kern_mount) (struct super_block *sb, void *data); 1264 int (*sb_statfs) (struct dentry *dentry); 1265 int (*sb_mount) (char *dev_name, struct nameidata * nd, ··· 1276 void (*sb_post_pivotroot) (struct nameidata * old_nd, 1277 struct nameidata * new_nd); 1278 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); 1283 void (*sb_clone_mnt_opts) (const struct super_block *oldsb, 1284 struct super_block *newsb); 1285 1286 int (*inode_alloc_security) (struct inode *inode); 1287 void (*inode_free_security) (struct inode *inode); ··· 1526 int security_bprm_secureexec(struct linux_binprm *bprm); 1527 int security_sb_alloc(struct super_block *sb); 1528 void security_sb_free(struct super_block *sb); 1529 - int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy); 1530 int security_sb_kern_mount(struct super_block *sb, void *data); 1531 int security_sb_statfs(struct dentry *dentry); 1532 int security_sb_mount(char *dev_name, struct nameidata *nd, ··· 1539 void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd); 1540 int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); 1541 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); 1546 void security_sb_clone_mnt_opts(const struct super_block *oldsb, 1547 struct super_block *newsb); 1548 1549 int security_inode_alloc(struct inode *inode); 1550 void security_inode_free(struct inode *inode); ··· 1654 void security_release_secctx(char *secdata, u32 seclen); 1655 1656 #else /* CONFIG_SECURITY */ 1657 1658 /* 1659 * This is the default capabilities functionality. Most of these functions ··· 1791 static inline void security_sb_free (struct super_block *sb) 1792 { } 1793 1794 - static inline int security_sb_copy_data (struct file_system_type *type, 1795 - void *orig, void *copy) 1796 { 1797 return 0; 1798 } ··· 1847 static inline void security_sb_post_pivotroot (struct nameidata *old_nd, 1848 struct nameidata *new_nd) 1849 { } 1850 1851 static inline int security_inode_alloc (struct inode *inode) 1852 {
··· 34 #include <linux/xfrm.h> 35 #include <net/flow.h> 36 37 extern unsigned securebits; 38 39 struct ctl_table; ··· 113 #define LSM_UNSAFE_PTRACE_CAP 4 114 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 + } 142 143 /** 144 * struct security_operations - main security structure ··· 262 * @sb_get_mnt_opts: 263 * Get the security relevant mount options used for a superblock 264 * @sb the superblock to get security mount options from 265 + * @opts binary data structure containing all lsm mount data 266 * @sb_set_mnt_opts: 267 * Set the security relevant mount options used for a superblock 268 * @sb the superblock to set security mount options for 269 + * @opts binary data structure containing all lsm mount data 270 * @sb_clone_mnt_opts: 271 * Copy all security options from a given superblock to another 272 * @oldsb old superblock which contain information to clone 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 278 * 279 * Security hooks for inode operations. 280 * ··· 1238 1239 int (*sb_alloc_security) (struct super_block * sb); 1240 void (*sb_free_security) (struct super_block * sb); 1241 + int (*sb_copy_data)(char *orig, char *copy); 1242 int (*sb_kern_mount) (struct super_block *sb, void *data); 1243 int (*sb_statfs) (struct dentry *dentry); 1244 int (*sb_mount) (char *dev_name, struct nameidata * nd, ··· 1257 void (*sb_post_pivotroot) (struct nameidata * old_nd, 1258 struct nameidata * new_nd); 1259 int (*sb_get_mnt_opts) (const struct super_block *sb, 1260 + struct security_mnt_opts *opts); 1261 + int (*sb_set_mnt_opts) (struct super_block *sb, 1262 + struct security_mnt_opts *opts); 1263 void (*sb_clone_mnt_opts) (const struct super_block *oldsb, 1264 struct super_block *newsb); 1265 + int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts); 1266 1267 int (*inode_alloc_security) (struct inode *inode); 1268 void (*inode_free_security) (struct inode *inode); ··· 1507 int security_bprm_secureexec(struct linux_binprm *bprm); 1508 int security_sb_alloc(struct super_block *sb); 1509 void security_sb_free(struct super_block *sb); 1510 + int security_sb_copy_data(char *orig, char *copy); 1511 int security_sb_kern_mount(struct super_block *sb, void *data); 1512 int security_sb_statfs(struct dentry *dentry); 1513 int security_sb_mount(char *dev_name, struct nameidata *nd, ··· 1520 void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd); 1521 int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); 1522 void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); 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); 1526 void security_sb_clone_mnt_opts(const struct super_block *oldsb, 1527 struct super_block *newsb); 1528 + int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts); 1529 1530 int security_inode_alloc(struct inode *inode); 1531 void security_inode_free(struct inode *inode); ··· 1635 void security_release_secctx(char *secdata, u32 seclen); 1636 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 + } 1648 1649 /* 1650 * This is the default capabilities functionality. Most of these functions ··· 1762 static inline void security_sb_free (struct super_block *sb) 1763 { } 1764 1765 + static inline int security_sb_copy_data (char *orig, char *copy) 1766 { 1767 return 0; 1768 } ··· 1819 static inline void security_sb_post_pivotroot (struct nameidata *old_nd, 1820 struct nameidata *new_nd) 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 + } 1843 1844 static inline int security_inode_alloc (struct inode *inode) 1845 {
+13 -10
security/dummy.c
··· 181 return; 182 } 183 184 - static int dummy_sb_copy_data (struct file_system_type *type, 185 - void *orig, void *copy) 186 { 187 return 0; 188 } ··· 244 return; 245 } 246 247 - static int dummy_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options, 248 - int **flags, int *num_opts) 249 { 250 - *mount_options = NULL; 251 - *flags = NULL; 252 - *num_opts = 0; 253 return 0; 254 } 255 256 - static int dummy_sb_set_mnt_opts(struct super_block *sb, char **mount_options, 257 - int *flags, int num_opts) 258 { 259 - if (unlikely(num_opts)) 260 return -EOPNOTSUPP; 261 return 0; 262 } ··· 263 struct super_block *newsb) 264 { 265 return; 266 } 267 268 static int dummy_inode_alloc_security (struct inode *inode) ··· 1030 set_to_dummy_if_null(ops, sb_get_mnt_opts); 1031 set_to_dummy_if_null(ops, sb_set_mnt_opts); 1032 set_to_dummy_if_null(ops, sb_clone_mnt_opts); 1033 set_to_dummy_if_null(ops, inode_alloc_security); 1034 set_to_dummy_if_null(ops, inode_free_security); 1035 set_to_dummy_if_null(ops, inode_init_security);
··· 181 return; 182 } 183 184 + static int dummy_sb_copy_data (char *orig, char *copy) 185 { 186 return 0; 187 } ··· 245 return; 246 } 247 248 + static int dummy_sb_get_mnt_opts(const struct super_block *sb, 249 + struct security_mnt_opts *opts) 250 { 251 + security_init_mnt_opts(opts); 252 return 0; 253 } 254 255 + static int dummy_sb_set_mnt_opts(struct super_block *sb, 256 + struct security_mnt_opts *opts) 257 { 258 + if (unlikely(opts->num_mnt_opts)) 259 return -EOPNOTSUPP; 260 return 0; 261 } ··· 266 struct super_block *newsb) 267 { 268 return; 269 + } 270 + 271 + static int dummy_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) 272 + { 273 + return 0; 274 } 275 276 static int dummy_inode_alloc_security (struct inode *inode) ··· 1028 set_to_dummy_if_null(ops, sb_get_mnt_opts); 1029 set_to_dummy_if_null(ops, sb_set_mnt_opts); 1030 set_to_dummy_if_null(ops, sb_clone_mnt_opts); 1031 + set_to_dummy_if_null(ops, sb_parse_opts_str); 1032 set_to_dummy_if_null(ops, inode_alloc_security); 1033 set_to_dummy_if_null(ops, inode_free_security); 1034 set_to_dummy_if_null(ops, inode_init_security);
+15 -8
security/security.c
··· 244 security_ops->sb_free_security(sb); 245 } 246 247 - int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy) 248 { 249 - return security_ops->sb_copy_data(type, orig, copy); 250 } 251 252 int security_sb_kern_mount(struct super_block *sb, void *data) 253 { ··· 307 } 308 309 int security_sb_get_mnt_opts(const struct super_block *sb, 310 - char ***mount_options, 311 - int **flags, int *num_opts) 312 { 313 - return security_ops->sb_get_mnt_opts(sb, mount_options, flags, num_opts); 314 } 315 316 int security_sb_set_mnt_opts(struct super_block *sb, 317 - char **mount_options, 318 - int *flags, int num_opts) 319 { 320 - return security_ops->sb_set_mnt_opts(sb, mount_options, flags, num_opts); 321 } 322 323 void security_sb_clone_mnt_opts(const struct super_block *oldsb, 324 struct super_block *newsb) 325 { 326 security_ops->sb_clone_mnt_opts(oldsb, newsb); 327 } 328 329 int security_inode_alloc(struct inode *inode) 330 {
··· 244 security_ops->sb_free_security(sb); 245 } 246 247 + int security_sb_copy_data(char *orig, char *copy) 248 { 249 + return security_ops->sb_copy_data(orig, copy); 250 } 251 + EXPORT_SYMBOL(security_sb_copy_data); 252 253 int security_sb_kern_mount(struct super_block *sb, void *data) 254 { ··· 306 } 307 308 int security_sb_get_mnt_opts(const struct super_block *sb, 309 + struct security_mnt_opts *opts) 310 { 311 + return security_ops->sb_get_mnt_opts(sb, opts); 312 } 313 314 int security_sb_set_mnt_opts(struct super_block *sb, 315 + struct security_mnt_opts *opts) 316 { 317 + return security_ops->sb_set_mnt_opts(sb, opts); 318 } 319 + EXPORT_SYMBOL(security_sb_set_mnt_opts); 320 321 void security_sb_clone_mnt_opts(const struct super_block *oldsb, 322 struct super_block *newsb) 323 { 324 security_ops->sb_clone_mnt_opts(oldsb, newsb); 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); 333 334 int security_inode_alloc(struct inode *inode) 335 {
+101 -88
security/selinux/hooks.c
··· 443 * mount options, or whatever. 444 */ 445 static int selinux_get_mnt_opts(const struct super_block *sb, 446 - char ***mount_options, int **mnt_opts_flags, 447 - int *num_opts) 448 { 449 int rc = 0, i; 450 struct superblock_security_struct *sbsec = sb->s_security; ··· 451 u32 len; 452 char tmp; 453 454 - *num_opts = 0; 455 - *mount_options = NULL; 456 - *mnt_opts_flags = NULL; 457 458 if (!sbsec->initialized) 459 return -EINVAL; ··· 467 /* count the number of mount options for this sb */ 468 for (i = 0; i < 8; i++) { 469 if (tmp & 0x01) 470 - (*num_opts)++; 471 tmp >>= 1; 472 } 473 474 - *mount_options = kcalloc(*num_opts, sizeof(char *), GFP_ATOMIC); 475 - if (!*mount_options) { 476 rc = -ENOMEM; 477 goto out_free; 478 } 479 480 - *mnt_opts_flags = kcalloc(*num_opts, sizeof(int), GFP_ATOMIC); 481 - if (!*mnt_opts_flags) { 482 rc = -ENOMEM; 483 goto out_free; 484 } ··· 488 rc = security_sid_to_context(sbsec->sid, &context, &len); 489 if (rc) 490 goto out_free; 491 - (*mount_options)[i] = context; 492 - (*mnt_opts_flags)[i++] = FSCONTEXT_MNT; 493 } 494 if (sbsec->flags & CONTEXT_MNT) { 495 rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len); 496 if (rc) 497 goto out_free; 498 - (*mount_options)[i] = context; 499 - (*mnt_opts_flags)[i++] = CONTEXT_MNT; 500 } 501 if (sbsec->flags & DEFCONTEXT_MNT) { 502 rc = security_sid_to_context(sbsec->def_sid, &context, &len); 503 if (rc) 504 goto out_free; 505 - (*mount_options)[i] = context; 506 - (*mnt_opts_flags)[i++] = DEFCONTEXT_MNT; 507 } 508 if (sbsec->flags & ROOTCONTEXT_MNT) { 509 struct inode *root = sbsec->sb->s_root->d_inode; ··· 512 rc = security_sid_to_context(isec->sid, &context, &len); 513 if (rc) 514 goto out_free; 515 - (*mount_options)[i] = context; 516 - (*mnt_opts_flags)[i++] = ROOTCONTEXT_MNT; 517 } 518 519 - BUG_ON(i != *num_opts); 520 521 return 0; 522 523 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; 533 return rc; 534 } 535 ··· 542 return 1; 543 return 0; 544 } 545 /* 546 * Allow filesystems with binary mount data to explicitly set mount point 547 * labeling information. 548 */ 549 - static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options, 550 - int *flags, int num_opts) 551 { 552 int rc = 0, i; 553 struct task_security_struct *tsec = current->security; ··· 558 struct inode_security_struct *root_isec = inode->i_security; 559 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; 560 u32 defcontext_sid = 0; 561 562 mutex_lock(&sbsec->lock); 563 ··· 580 "the security server is initialized\n"); 581 goto out; 582 } 583 584 /* 585 * parse the mount options, check if they are valid sids. ··· 800 mutex_unlock(&newsbsec->lock); 801 } 802 803 - /* 804 - * string mount options parsing and call set the sbsec 805 - */ 806 - static int superblock_doinit(struct super_block *sb, void *data) 807 { 808 char *context = NULL, *defcontext = NULL; 809 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; 815 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 - } 840 841 /* Standard string-based options. */ 842 while ((p = strsep(&options, "|")) != NULL) { ··· 880 } 881 } 882 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; 899 } 900 901 - out: 902 - rc = selinux_set_mnt_opts(sb, mnt_opts, mnt_opts_flags, num_mnt_opts); 903 out_err: 904 kfree(context); 905 kfree(defcontext); 906 kfree(fscontext); 907 kfree(rootcontext); 908 return rc; 909 } 910 ··· 2270 } 2271 } 2272 2273 - static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void *copy) 2274 { 2275 int fnosec, fsec, rc = 0; 2276 char *in_save, *in_curr, *in_end; ··· 2279 2280 in_curr = orig; 2281 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 2289 nosec = (char *)get_zeroed_page(GFP_KERNEL); 2290 if (!nosec) { ··· 5262 .sb_get_mnt_opts = selinux_get_mnt_opts, 5263 .sb_set_mnt_opts = selinux_set_mnt_opts, 5264 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, 5265 5266 .inode_alloc_security = selinux_inode_alloc_security, 5267 .inode_free_security = selinux_inode_free_security,
··· 443 * mount options, or whatever. 444 */ 445 static int selinux_get_mnt_opts(const struct super_block *sb, 446 + struct security_mnt_opts *opts) 447 { 448 int rc = 0, i; 449 struct superblock_security_struct *sbsec = sb->s_security; ··· 452 u32 len; 453 char tmp; 454 455 + security_init_mnt_opts(opts); 456 457 if (!sbsec->initialized) 458 return -EINVAL; ··· 470 /* count the number of mount options for this sb */ 471 for (i = 0; i < 8; i++) { 472 if (tmp & 0x01) 473 + opts->num_mnt_opts++; 474 tmp >>= 1; 475 } 476 477 + opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); 478 + if (!opts->mnt_opts) { 479 rc = -ENOMEM; 480 goto out_free; 481 } 482 483 + opts->mnt_opts_flags = kcalloc(opts->num_mnt_opts, sizeof(int), GFP_ATOMIC); 484 + if (!opts->mnt_opts_flags) { 485 rc = -ENOMEM; 486 goto out_free; 487 } ··· 491 rc = security_sid_to_context(sbsec->sid, &context, &len); 492 if (rc) 493 goto out_free; 494 + opts->mnt_opts[i] = context; 495 + opts->mnt_opts_flags[i++] = FSCONTEXT_MNT; 496 } 497 if (sbsec->flags & CONTEXT_MNT) { 498 rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len); 499 if (rc) 500 goto out_free; 501 + opts->mnt_opts[i] = context; 502 + opts->mnt_opts_flags[i++] = CONTEXT_MNT; 503 } 504 if (sbsec->flags & DEFCONTEXT_MNT) { 505 rc = security_sid_to_context(sbsec->def_sid, &context, &len); 506 if (rc) 507 goto out_free; 508 + opts->mnt_opts[i] = context; 509 + opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; 510 } 511 if (sbsec->flags & ROOTCONTEXT_MNT) { 512 struct inode *root = sbsec->sb->s_root->d_inode; ··· 515 rc = security_sid_to_context(isec->sid, &context, &len); 516 if (rc) 517 goto out_free; 518 + opts->mnt_opts[i] = context; 519 + opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; 520 } 521 522 + BUG_ON(i != opts->num_mnt_opts); 523 524 return 0; 525 526 out_free: 527 + security_free_mnt_opts(opts); 528 return rc; 529 } 530 ··· 553 return 1; 554 return 0; 555 } 556 + 557 /* 558 * Allow filesystems with binary mount data to explicitly set mount point 559 * labeling information. 560 */ 561 + static int selinux_set_mnt_opts(struct super_block *sb, 562 + struct security_mnt_opts *opts) 563 { 564 int rc = 0, i; 565 struct task_security_struct *tsec = current->security; ··· 568 struct inode_security_struct *root_isec = inode->i_security; 569 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; 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; 574 575 mutex_lock(&sbsec->lock); 576 ··· 587 "the security server is initialized\n"); 588 goto out; 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; 605 606 /* 607 * parse the mount options, check if they are valid sids. ··· 792 mutex_unlock(&newsbsec->lock); 793 } 794 795 + int selinux_parse_opts_str(char *options, struct security_mnt_opts *opts) 796 { 797 + char *p; 798 char *context = NULL, *defcontext = NULL; 799 char *fscontext = NULL, *rootcontext = NULL; 800 + int rc, num_mnt_opts = 0; 801 802 + opts->num_mnt_opts = 0; 803 804 /* Standard string-based options. */ 805 while ((p = strsep(&options, "|")) != NULL) { ··· 901 } 902 } 903 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; 913 } 914 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 + 935 out_err: 936 kfree(context); 937 kfree(defcontext); 938 kfree(fscontext); 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); 967 return rc; 968 } 969 ··· 2253 } 2254 } 2255 2256 + static int selinux_sb_copy_data(char *orig, char *copy) 2257 { 2258 int fnosec, fsec, rc = 0; 2259 char *in_save, *in_curr, *in_end; ··· 2262 2263 in_curr = orig; 2264 sec_curr = copy; 2265 2266 nosec = (char *)get_zeroed_page(GFP_KERNEL); 2267 if (!nosec) { ··· 5251 .sb_get_mnt_opts = selinux_get_mnt_opts, 5252 .sb_set_mnt_opts = selinux_set_mnt_opts, 5253 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, 5254 + .sb_parse_opts_str = selinux_parse_opts_str, 5255 + 5256 5257 .inode_alloc_security = selinux_inode_alloc_security, 5258 .inode_free_security = selinux_inode_free_security,
+5
security/selinux/include/security.h
··· 35 #define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP 36 #endif 37 38 struct netlbl_lsm_secattr; 39 40 extern int selinux_enabled;
··· 35 #define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP 36 #endif 37 38 + #define CONTEXT_MNT 0x01 39 + #define FSCONTEXT_MNT 0x02 40 + #define ROOTCONTEXT_MNT 0x04 41 + #define DEFCONTEXT_MNT 0x08 42 + 43 struct netlbl_lsm_secattr; 44 45 extern int selinux_enabled;
+1 -8
security/smack/smack_lsm.c
··· 189 * Copy the Smack specific mount options out of the mount 190 * options list. 191 */ 192 - static int smack_sb_copy_data(struct file_system_type *type, void *orig, 193 - void *smackopts) 194 { 195 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 203 otheropts = (char *)get_zeroed_page(GFP_KERNEL); 204 if (otheropts == NULL)
··· 189 * Copy the Smack specific mount options out of the mount 190 * options list. 191 */ 192 + static int smack_sb_copy_data(char *orig, char *smackopts) 193 { 194 char *cp, *commap, *otheropts, *dp; 195 196 otheropts = (char *)get_zeroed_page(GFP_KERNEL); 197 if (otheropts == NULL)