This option allows setting the SELinux security context (label) for the root directory. A common value would be system_u:object_r:root_t possibly with a level/range such as :s0 suffix (for MCS/MLS policy). Signed-off-by: Ralph Siemsen --- misc/mke2fs.8.in | 10 ++++++++ misc/mke2fs.c | 46 ++++++++++++++++++++++++++++++++++ tests/m_root_selinux/expect.1 | 57 +++++++++++++++++++++++++++++++++++++++++++ tests/m_root_selinux/script | 4 +++ 4 files changed, 117 insertions(+) diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in index 14bae326..6af71fd5 100644 --- a/misc/mke2fs.8.in +++ b/misc/mke2fs.8.in @@ -426,6 +426,16 @@ Specify the root directory permissions in octal format. If no permissions are specified then the root directory permissions would be set in accordance with the default filesystem umask. .TP +.BI root_selinux= label +Specify the root directory SELinux security context as +.IR label , +typically +.nh +.B system_u:object_r:root_t +with an optional level/range suffix such as +.B :s0 +for MCS/MLS policy types. +.TP .BI stride= stride-size Configure the file system for a RAID array with .I stride-size diff --git a/misc/mke2fs.c b/misc/mke2fs.c index 59c7be17..a16a808a 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -95,6 +95,7 @@ static int num_backups = 2; /* number of backup bg's for sparse_super2 */ static uid_t root_uid; static mode_t root_perms = (mode_t)-1; static gid_t root_gid; +static char *root_selinux = NULL; int journal_size; int journal_flags; int journal_fc_size; @@ -515,6 +516,35 @@ static void create_root_dir(ext2_filsys fs) exit(1); } } + + if (root_selinux) { + struct ext2_xattr_handle *handle; + retval = ext2fs_xattrs_open(fs, EXT2_ROOT_INO, &handle); + if (retval) { + com_err("ext2fs_xattrs_open", retval, + _("while setting root inode label")); + exit(1); + } + retval = ext2fs_xattrs_read(handle); + if (retval) { + com_err("ext2fs_xattrs_read", retval, + _("while setting root inode label")); + exit(1); + } + retval = ext2fs_xattr_set(handle, "security.selinux", + root_selinux, strlen(root_selinux)); + if (retval) { + com_err("ext2fs_xattr_set", retval, + _("while setting root inode label")); + exit(1); + } + retval = ext2fs_xattrs_close(&handle); + if (retval) { + com_err("ext2fs_xattrs_close", retval, + _("while setting root inode label")); + exit(1); + } + } } static void create_lost_and_found(ext2_filsys fs) @@ -1089,6 +1119,21 @@ static void parse_extended_opts(struct ext2_super_block *param, if (arg) { root_perms = strtoul(arg, &p, 8); } + } else if (!strcmp(token, "root_selinux")) { + if (arg) { + root_selinux = realloc(root_selinux, + strlen(arg) + 1); + if (!root_selinux) { + com_err(program_name, ENOMEM, "%s", + _("in malloc for root_selinux")); + exit(1); + } + strcpy(root_selinux, arg); + } else { + r_usage++; + badopt = token; + continue; + } } else if (!strcmp(token, "discard")) { discard = 1; } else if (!strcmp(token, "nodiscard")) { @@ -1174,6 +1219,7 @@ static void parse_extended_opts(struct ext2_super_block *param, "\tlazy_journal_init=<0 to disable, 1 to enable>\n" "\troot_owner=:\n" "\troot_perms=\n" + "\troot_selinux=\n" "\ttest_fs\n" "\tdiscard\n" "\tnodiscard\n" diff --git a/tests/m_root_selinux/expect.1 b/tests/m_root_selinux/expect.1 new file mode 100644 index 00000000..19a3d6ee --- /dev/null +++ b/tests/m_root_selinux/expect.1 @@ -0,0 +1,57 @@ +Creating filesystem with 1024 1k blocks and 128 inodes + +Allocating group tables: done +Writing inode tables: done +Writing superblocks and filesystem accounting information: done + +Filesystem features: ext_attr resize_inode dir_index filetype sparse_super +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +test_filesys: 11/128 files (0.0% non-contiguous), 54/1024 blocks +Exit status is 0 +Filesystem volume name: +Last mounted on: +Filesystem magic number: 0xEF53 +Filesystem revision #: 1 (dynamic) +Filesystem features: ext_attr resize_inode dir_index filetype sparse_super +Default mount options: (none) +Filesystem state: clean +Errors behavior: Continue +Filesystem OS type: Linux +Inode count: 128 +Block count: 1024 +Reserved block count: 51 +Overhead clusters: 40 +Free blocks: 970 +Free inodes: 117 +First block: 1 +Block size: 1024 +Fragment size: 1024 +Reserved GDT blocks: 3 +Blocks per group: 8192 +Fragments per group: 8192 +Inodes per group: 128 +Inode blocks per group: 32 +Mount count: 0 +Check interval: 15552000 (6 months) +Reserved blocks uid: 0 +Reserved blocks gid: 0 +First inode: 11 +Inode size: 256 +Required extra isize: 32 +Desired extra isize: 32 +Default directory hash: half_md4 + + +Group 0: (Blocks 1-1023) + Primary superblock at 1, Group descriptors at 2-2 + Reserved GDT blocks at 3-5 + Block bitmap at 6 (+5) + Inode bitmap at 7 (+6) + Inode table at 8-39 (+7) + 970 free blocks, 117 free inodes, 2 directories + Free blocks: 54-1023 + Free inodes: 12-128 diff --git a/tests/m_root_selinux/script b/tests/m_root_selinux/script new file mode 100644 index 00000000..4ac82918 --- /dev/null +++ b/tests/m_root_selinux/script @@ -0,0 +1,4 @@ +DESCRIPTION="root directory SELinux security context" +FS_SIZE=1024 +MKE2FS_OPTS="-E root_selinux=system_u:object_r:root_t" +. $cmd_dir/run_mke2fs -- 2.45.2.121.gc2b3f2b3cd