From 2d6368c6dd03de47f81f956db1162e1cb53d8012 Mon Sep 17 00:00:00 2001 From: Michael Mikonos <127171689+mknos@users.noreply.github.com> Date: Sat, 23 Mar 2024 18:56:01 +0800 Subject: [PATCH] install: broken symbolic permissions (#514) * Test: running "perl install -m a=rx xargs build/" didn't install xargs with the correct permissions * Problem1: Return value of mod() was not saved into $bits * Problem2: When doing '=' operation, the value of the current permissions ($current) was being used incorrectly * Resetting permissions to 0 for '=' operation allows only the appropriate bits to be set, not extra ones based on source file stat() * Problem3: The permission bit for 'r' saved in $perms{$s} was lost because of assignment of permission for 'x'; code should use OR on $perms{$s} instead * Operators '+' and '=' should both apply OR to the permissions; the difference is that '+' applies to the Source file permissions whereas '=' applies to 0 %ls -l xargs # source permissions are 755 -rwxr-xr-x 1 pi pi 2481 Mar 6 16:14 xargs %perl install -m a=rx xargs build/ # patch applied; destination permissions are 555 %ls -l build/xargs -r-xr-xr-x 1 pi pi 2481 Mar 22 13:51 build/xargs --- bin/install | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bin/install b/bin/install index 514df902..64c6e523 100755 --- a/bin/install +++ b/bin/install @@ -245,7 +245,7 @@ sub install_files { my $bits; if ($symbolic) { - unless ( mod($mode, $targ) ) { + unless ( $bits = mod($mode, $targ) ) { die "$Program: invalid mode: $mode\n"; } $bits = oct $bits; @@ -373,6 +373,9 @@ sub mod ($$) { else {%perms = %umask;} next; } + if ($operator eq '=') { + %perms = ( 'u' => 0, 'g' => 0, 'o' => 0); + } # If we arrive here, $perms is a string. # We can iterate over the characters. @@ -433,9 +436,8 @@ sub mod ($$) { # Apply. foreach my $s (@set) { - do {$perms {$s} |= $bit; next} if $operator eq '+'; + do {$perms {$s} |= $bit; next} if ($operator eq '+' || $operator eq '=') ; do {$perms {$s} &= ~$bit; next} if $operator eq '-'; - do {$perms {$s} = $bit; next} if $operator eq '='; die "Weird operator `$operator' found\n"; # Should not happen. }