summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Xu (Hello71) <alex_y_xu@yahoo.ca>2021-04-11 13:54:00 -0400
committerAlex Xu (Hello71) <alex_y_xu@yahoo.ca>2021-04-11 13:54:27 -0400
commit5900c3d1b2132bb1c7a8bc8db2a75ff0944f0fd7 (patch)
tree62de6fd395011c1ae75d69d353c47f00695be768
parentc196a5db821735b000a2e0ddc8f57623146a64d2 (diff)
downloadtmpoverlay-5900c3d1b2132bb1c7a8bc8db2a75ff0944f0fd7.tar.xz
tmpoverlay-5900c3d1b2132bb1c7a8bc8db2a75ff0944f0fd7.zip
use ls instead of stat -c
-rw-r--r--README.rst4
-rwxr-xr-xtmpoverlay30
2 files changed, 20 insertions, 14 deletions
diff --git a/README.rst b/README.rst
index adf5f69..07e05e2 100644
--- a/README.rst
+++ b/README.rst
@@ -7,7 +7,7 @@ overlayfs mounts.
Features
--------
-- minimal requirements (sh, mount, getopt, stat)
+- minimal requirements (sh, mount, getopt)
Benefits over manually calling ``mkdir /tmp/x; mount ...``
@@ -39,7 +39,5 @@ POSIX-only shells:
- ``mount -t overlay`` is obviously required
- ``getopt --`` is required for proper handling of options containing spaces
-- ``stat -c`` is required to obtain upperdir owner and permissions, because
- parsing ls -l is ridiculous.
- ``getfattr`` is used for xattr copying but in case of failure, the system is
assumed to not support xattrs and setfattr is skipped.
diff --git a/tmpoverlay b/tmpoverlay
index 87a3cdb..10662f5 100755
--- a/tmpoverlay
+++ b/tmpoverlay
@@ -202,23 +202,31 @@ try_ovl_opt() {
ovl_opts="$new_ovl_opts"
}
try_ovl_opt index on
-# redirect_dir/metacopy are unsafe with untrusted non-bottom layers
+# redirect_dir and metacopy are unsafe with untrusted non-bottom layers
+# nfs_export conflicts with metacopy
[ "${lowerdir#*:}" = "$lowerdir" ] && \
! chk_ovl_opt userxattr on && \
try_ovl_opt redirect_dir on && \
{ chk_ovl_opt nfs_export on || try_ovl_opt metacopy on; }
try_ovl_opt volatile
-# try to match perms/attrs. this is not race-free but it's impossible without
-# atomic (CAS) chown/chmod/setfattr. chown --from is not atomic, not portable,
-# and also doesn't cover chmod/setfattr.
+logv 'copying lowerdir owner/perms to upperdir'
lastlowerdir=${lowerdir##*:}
-logv 'copying lowerdir owner to upperdir'
-owner=$(stat -c %u:%g "$lastlowerdir") || die
-chown "$owner" "$upperdir" || die
-logv 'copying lowerdir perms to upperdir'
-mode=$(stat -c %a "$lastlowerdir") || die
-chmod "$mode" "$upperdir" || die
+# stat -c isn't posix -.-
+ls=$(ls -dn "$lastlowerdir/.") || die
+tmp=${ls#* * }
+owner=${tmp%% *}
+tmp=${tmp#* }
+group=${tmp%% *}
+chown "$owner:$group" "$upperdir" || die
+mode=${ls%% *}
+[ "${#mode}" = 10 ] || die "bad ls permission format"
+mode=${mode#?}
+umode=${mode%??????}
+ugmode=${mode%???}
+gmode=${ugmode#???}
+omode=${mode#??????}
+chmod "u=$umode,g=$gmode,o=$omode" "$upperdir" || die
# -m - covers ACLs (system.posix_acl_access) and file caps
# (security.capability). theoretically someone might have get/setcap and/or
# get/setfacl but not get/setxattr, but this is unlikely since libcap/acl
@@ -229,7 +237,7 @@ if attrs=$(cd "$lastlowerdir" && getfattr -d -m - . 2>/dev/null); then
printf '%s\n' "$attrs" | (cd "$upperdir"; setfattr --restore=-) || die
fi
else
- log 'getfattr not found or failed, skipping xattrs'
+ log 'getfattr failed, skipping xattrs'
fi
logv 'mounting overlay'