Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

btrfs: sanitize security_mnt_opts use

1) keeping a copy in btrfs_fs_info is completely pointless - we never
use it for anything. Getting rid of that allows for simpler calling
conventions for setup_security_options() (caller is responsible for
freeing mnt_opts in all cases).

2) on remount we want to use ->sb_remount(), not ->sb_set_mnt_opts(),
same as we would if not for FS_BINARY_MOUNTDATA. Behaviours *are*
close (in fact, selinux sb_set_mnt_opts() ought to punt to
sb_remount() in "already initialized" case), but let's handle
that uniformly. And the only reason why the original btrfs changes
didn't go for security_sb_remount() in btrfs_remount() case is that
it hadn't been exported. Let's export it for a while - it'll be
going away soon anyway.

Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro a65001e8 8d64124a

+10 -58
-4
fs/btrfs/ctree.h
··· 1100 1100 struct mutex unused_bg_unpin_mutex; 1101 1101 struct mutex delete_unused_bgs_mutex; 1102 1102 1103 - /* For btrfs to record security options */ 1104 - struct security_mnt_opts security_opts; 1105 - 1106 1103 /* 1107 1104 * Chunks that can't be freed yet (under a trim/discard operation) 1108 1105 * and will be latter freed. Protected by fs_info->chunk_mutex. ··· 2956 2959 kfree(fs_info->free_space_root); 2957 2960 kfree(fs_info->super_copy); 2958 2961 kfree(fs_info->super_for_commit); 2959 - security_free_mnt_opts(&fs_info->security_opts); 2960 2962 kvfree(fs_info); 2961 2963 } 2962 2964
+9 -54
fs/btrfs/super.c
··· 1458 1458 return root; 1459 1459 } 1460 1460 1461 - static int parse_security_options(char *orig_opts, 1462 - struct security_mnt_opts *sec_opts) 1463 - { 1464 - return security_sb_eat_lsm_opts(orig_opts, sec_opts); 1465 - } 1466 - 1467 - static int setup_security_options(struct btrfs_fs_info *fs_info, 1468 - struct super_block *sb, 1469 - struct security_mnt_opts *sec_opts) 1470 - { 1471 - int ret = 0; 1472 - 1473 - /* 1474 - * Call security_sb_set_mnt_opts() to check whether new sec_opts 1475 - * is valid. 1476 - */ 1477 - ret = security_sb_set_mnt_opts(sb, sec_opts, 0, NULL); 1478 - if (ret) 1479 - return ret; 1480 - 1481 - #ifdef CONFIG_SECURITY 1482 - if (!fs_info->security_opts.num_mnt_opts) { 1483 - /* first time security setup, copy sec_opts to fs_info */ 1484 - memcpy(&fs_info->security_opts, sec_opts, sizeof(*sec_opts)); 1485 - } else { 1486 - /* 1487 - * Since SELinux (the only one supporting security_mnt_opts) 1488 - * does NOT support changing context during remount/mount of 1489 - * the same sb, this must be the same or part of the same 1490 - * security options, just free it. 1491 - */ 1492 - security_free_mnt_opts(sec_opts); 1493 - } 1494 - #endif 1495 - return ret; 1496 - } 1497 - 1498 1461 /* 1499 1462 * Find a superblock for the given device / mount point. 1500 1463 * ··· 1481 1518 1482 1519 security_init_mnt_opts(&new_sec_opts); 1483 1520 if (data) { 1484 - error = parse_security_options(data, &new_sec_opts); 1521 + error = security_sb_eat_lsm_opts(data, &new_sec_opts); 1485 1522 if (error) 1486 1523 return ERR_PTR(error); 1487 1524 } ··· 1500 1537 1501 1538 fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); 1502 1539 fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); 1503 - security_init_mnt_opts(&fs_info->security_opts); 1504 1540 if (!fs_info->super_copy || !fs_info->super_for_commit) { 1505 1541 error = -ENOMEM; 1506 1542 goto error_fs_info; ··· 1550 1588 btrfs_sb(s)->bdev_holder = fs_type; 1551 1589 error = btrfs_fill_super(s, fs_devices, data); 1552 1590 } 1591 + if (!error) 1592 + error = security_sb_set_mnt_opts(s, &new_sec_opts, 0, NULL); 1593 + security_free_mnt_opts(&new_sec_opts); 1553 1594 if (error) { 1554 1595 deactivate_locked_super(s); 1555 - goto error_sec_opts; 1556 - } 1557 - 1558 - fs_info = btrfs_sb(s); 1559 - error = setup_security_options(fs_info, s, &new_sec_opts); 1560 - if (error) { 1561 - deactivate_locked_super(s); 1562 - goto error_sec_opts; 1596 + return ERR_PTR(error); 1563 1597 } 1564 1598 1565 1599 return dget(s->s_root); ··· 1727 1769 struct security_mnt_opts new_sec_opts; 1728 1770 1729 1771 security_init_mnt_opts(&new_sec_opts); 1730 - ret = parse_security_options(data, &new_sec_opts); 1772 + ret = security_sb_eat_lsm_opts(data, &new_sec_opts); 1773 + if (!ret) 1774 + ret = security_sb_remount(sb, &new_sec_opts); 1775 + security_free_mnt_opts(&new_sec_opts); 1731 1776 if (ret) 1732 1777 goto restore; 1733 - ret = setup_security_options(fs_info, sb, 1734 - &new_sec_opts); 1735 - if (ret) { 1736 - security_free_mnt_opts(&new_sec_opts); 1737 - goto restore; 1738 - } 1739 1778 } 1740 1779 1741 1780 ret = btrfs_parse_options(fs_info, data, *flags);
+1
security/security.c
··· 404 404 { 405 405 return call_int_hook(sb_remount, 0, sb, opts); 406 406 } 407 + EXPORT_SYMBOL(security_sb_remount); 407 408 408 409 int security_sb_kern_mount(struct super_block *sb) 409 410 {