For reproducible builds, it is necessary to control the random seed used for hashing. Document the extended option for this feature. Fixes: e1f71006 ("AOSP: mke2fs, libext2fs: make filesystem image reproducible") Signed-off-by: Ralph Siemsen --- misc/mke2fs.8.in | 4 ++++ misc/mke2fs.c | 1 + 2 files changed, 5 insertions(+) diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in index 13ddef47..14bae326 100644 --- a/misc/mke2fs.8.in +++ b/misc/mke2fs.8.in @@ -320,6 +320,10 @@ In the default configuration, the .I strict flag is disabled. .TP +.BI hash_seed= UUID +Use the specified UUID as the seed for hashing, rather than generating a +random seed each time. Intended for use with reproducible builds. +.TP .B lazy_itable_init\fR[\fB= \fI<0 to disable, 1 to enable>\fR] If enabled and the uninit_bg feature is enabled, the inode table will not be fully initialized by diff --git a/misc/mke2fs.c b/misc/mke2fs.c index 7f81a513..3a8ff5b1 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -1180,6 +1180,7 @@ static void parse_extended_opts(struct ext2_super_block *param, "\trevision=\n" "\tencoding=\n" "\tencoding_flags=\n" + "\thash_seed=\n" "\tquotatype=\n" "\tassume_storage_prezeroed=<0 to disable, 1 to enable>\n\n"), badopt ? badopt : ""); -- 2.45.2.121.gc2b3f2b3cd The '-E' option for specifying extended attributes can now be used multiple times. The existing support for multiple attributes encoded as comma-separated string is maintained for each '-E' option. Prior to this change, if multiple '-E' options were specified, then only the last one was used. Earlier ones were silently ignored. Signed-off-by: Ralph Siemsen --- misc/mke2fs.8.in | 4 +++- misc/mke2fs.c | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in index 14bae326..99ecc64b 100644 --- a/misc/mke2fs.8.in +++ b/misc/mke2fs.8.in @@ -268,7 +268,9 @@ Cause a kernel panic. .TP .BI \-E " extended-options" Set extended options for the file system. Extended options are comma -separated, and may take an argument using the equals ('=') sign. The +separated, and may take an argument using the equals ('=') sign. Multiple +.B \-E +options may also be used. The .B \-E option used to be .B \-R diff --git a/misc/mke2fs.c b/misc/mke2fs.c index 3a8ff5b1..a54f83ad 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -1653,7 +1653,7 @@ static void PRS(int argc, char *argv[]) int default_csum_seed = 0; errcode_t retval; char * oldpath = getenv("PATH"); - char * extended_opts = 0; + struct str_list extended_opts; char * fs_type = 0; char * usage_types = 0; /* @@ -1751,6 +1751,13 @@ profile_error: journal_size = -1; } + retval = init_list(&extended_opts); + if (retval) { + com_err(program_name, retval, "%s", + _("in malloc for extended_opts")); + exit(1); + } + while ((c = getopt (argc, argv, "b:cd:e:g:i:jl:m:no:qr:s:t:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:Vz:")) != EOF) { switch (c) { @@ -1796,7 +1803,7 @@ profile_error: _("'-R' is deprecated, use '-E' instead")); /* fallthrough */ case 'E': - extended_opts = optarg; + push_string(&extended_opts, optarg); break; case 'e': if (strcmp(optarg, "continue") == 0) @@ -2615,8 +2622,9 @@ profile_error: free(tmp); } - if (extended_opts) - parse_extended_opts(&fs_param, extended_opts); + /* Get options from commandline */ + for (cpp = extended_opts.list; *cpp; cpp++) + parse_extended_opts(&fs_param, *cpp); if (fs_param.s_rev_level == EXT2_GOOD_OLD_REV) { if (fs_features) { -- 2.45.2.121.gc2b3f2b3cd 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 99ecc64b..ffe02eb0 100644 --- a/misc/mke2fs.8.in +++ b/misc/mke2fs.8.in @@ -428,6 +428,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 a54f83ad..6eca46a4 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 Signed-off-by: Ralph Siemsen --- misc/mke2fs.8.in | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in index ffe02eb0..94d82082 100644 --- a/misc/mke2fs.8.in +++ b/misc/mke2fs.8.in @@ -739,6 +739,7 @@ the manual page Quiet execution. Useful if .B mke2fs is run in a script. +.TP .B \-S Write superblock and group descriptors only. This is an extreme measure to be taken only in the very unlikely case that all of -- 2.45.2.121.gc2b3f2b3cd