| 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 " |