blob: 01384c6fb7be51b0fb15cd06ba3bbadf5cad92dd [file] [log] [blame]
From c823262013500cd027c9088980510202b6e30c0c Mon Sep 17 00:00:00 2001
From: Phillip Lougher <phillip@squashfs.org.uk>
Date: Tue, 2 Jul 2019 02:32:37 +0100
Subject: [PATCH] mksquashfs: Add new -root-mode <mode> option
The impetus for adding yet another build tweak option, is
a bug report raised on Github back in 2017.
Simply put, when Mksquashfs is run with multiple sources on
the command line, it constructs a root directory containing
all the sources listed. So far so good.
But, this containing root directory is conjured out of thin-air,
it is not read from the source(s). So what permissions and
ownership should this root directory have? I choose to have the
directory owned and group owned by the user running Mksquashfs, with
the permissions set to octal 0777.
This is ancient behaviour, which dates back to even before Squashfs 1.0
was released in October 2002.
Fast forward to this bug report in 2017. It appears the reporter
is constructing Mksquashfs images using multiple sources on the
command line, and thus getting a root directory constructed above.
Their installer is then copying the filesystem, and getting a
root filesystem that is by default (due to the above 0777 permissions),
writable by anyone. They would like the permissions to be set to
0755.
Now, it can be argued that is not a fault of Squashfs. If they
want 0755 permissions, then it should not be beyond the wit of man
to alter them later.
But there again setting to 0777 was a completely arbitary choice on
my behalf many years ago. I see no point in trying to argue this
is the correct setting.
But I can't change the default behaviour of Mksquashfs now, given
it's been like that way for 17 years since the beginning, and who
knows how many things rely on that behaviour.
So perhaps the obvious way forward is to add another build option,
which allows people to change the default permissions if necesssary.
As implemented, the new option allows the permissions on the root
directory to be changed for all scenarios, irrespective of the
origin of the permissions, whether 0777 in the above case or
read from the filesystem (in the case where a single directory
is specified on the Mksquashfs command line, and where the permissions
of the root directory is copied from that source directory).
Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
---
squashfs-tools/mksquashfs.c | 44 +++++++++++++++++++++++++++++++++----
1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c
index 68a2277..b713d64 100644
--- a/squashfs-tools/mksquashfs.c
+++ b/squashfs-tools/mksquashfs.c
@@ -265,6 +265,10 @@ pthread_mutex_t fragment_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t pos_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t dup_mutex = PTHREAD_MUTEX_INITIALIZER;
+/* Root mode option */
+int root_mode_opt = FALSE;
+mode_t root_mode;
+
/* user options that control parallelisation */
int processors = -1;
int bwriter_size;
@@ -3136,7 +3140,7 @@ void dir_scan(squashfs_inode *inode, char *pathname,
* command line
*/
memset(&buf, 0, sizeof(buf));
- buf.st_mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR;
+ buf.st_mode = (root_mode_opt) ? root_mode | S_IFDIR : S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR;
buf.st_uid = getuid();
buf.st_gid = getgid();
buf.st_mtime = time(NULL);
@@ -3148,6 +3152,9 @@ void dir_scan(squashfs_inode *inode, char *pathname,
/* source directory has disappeared? */
BAD_ERROR("Cannot stat source directory %s because %s\n",
pathname, strerror(errno));
+ if(root_mode_opt)
+ buf.st_mode = root_mode | S_IFDIR;
+
dir_ent->inode = lookup_inode(&buf);
}
@@ -4755,14 +4762,14 @@ void write_filesystem_tables(struct squashfs_super_block *sBlk, int nopad)
}
-int parse_numberll(char *start, long long *res, int size)
+int _parse_numberll(char *start, long long *res, int size, int base)
{
char *end;
long long number;
errno = 0; /* To distinguish success/failure after call */
- number = strtoll(start, &end, 10);
+ number = strtoll(start, &end, base);
/*
* check for strtoll underflow or overflow in conversion, and other
@@ -4840,6 +4847,12 @@ int parse_numberll(char *start, long long *res, int size)
}
+int parse_numberll(char *start, long long *res, int size)
+{
+ return _parse_numberll(start, res, size, 10);
+}
+
+
int parse_number(char *start, int *res, int size)
{
long long number;
@@ -4862,6 +4875,21 @@ int parse_num(char *arg, int *res)
}
+int parse_mode(char *arg, mode_t *res)
+{
+ long long number;
+
+ if(!_parse_numberll(arg, &number, 0, 8))
+ return 0;
+
+ if(number > 07777)
+ return 0;
+
+ *res = (mode_t) number;
+ return 1;
+}
+
+
int get_physical_memory()
{
/* Long longs are used here because with PAE, a 32-bit
@@ -4987,7 +5015,14 @@ int main(int argc, char *argv[])
comp = lookup_compressor(COMP_DEFAULT);
for(i = source + 2; i < argc; i++) {
- if(strcmp(argv[i], "-action") == 0 ||
+ if(strcmp(argv[i], "-root-mode") == 0) {
+ if((++i == argc) || !parse_mode(argv[i], &root_mode)) {
+ ERROR("%s: -root-mode missing or invalid mode,"
+ " octal number <= 07777 expected\n", argv[0]);
+ exit(1);
+ }
+ root_mode_opt = TRUE;
+ } else if(strcmp(argv[i], "-action") == 0 ||
strcmp(argv[i], "-a") ==0) {
if(++i == argc) {
ERROR("%s: %s missing action\n",
@@ -5306,6 +5341,7 @@ printOptions:
ERROR("-no-duplicates\t\tdo not perform duplicate "
"checking\n");
ERROR("-all-root\t\tmake all files owned by root\n");
+ ERROR("-root-mode <mode>\tset root directory permissions to octal <mode>\n");
ERROR("-force-uid uid\t\tset all file uids to uid\n");
ERROR("-force-gid gid\t\tset all file gids to gid\n");
ERROR("-nopad\t\t\tdo not pad filesystem to a multiple "