mirror of
https://github.com/containers/podman.git
synced 2026-11-08 09:02:51 -05:00
Merge pull request #29942 from Garvity/fix/image-scp-working-directory
Fix image scp from inaccessible working directories
This commit is contained in:
3 files changed
+61
-10
No files matched your search
@@ -958,10 +958,11 @@ func execTransferPodman(execUser *user.User, command []string, needToTag bool) (
|
||||
_ = cmdLogin.Wait()
|
||||
}()
|
||||
|
||||
cmd := exec.Command(command[0], command[1:]...)
|
||||
cmd.Env = []string{"PATH=" + os.Getenv("PATH"), "TERM=" + os.Getenv("TERM")}
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = os.Stdout
|
||||
// Use the physical path; $PWD may contain symlinks inaccessible to execUser.
|
||||
cwd, err := syscall.Getwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uid, err := strconv.ParseInt(execUser.Uid, 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -970,7 +971,7 @@ func execTransferPodman(execUser *user.User, command []string, needToTag bool) (
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
sysProcAttr := &syscall.SysProcAttr{
|
||||
Credential: &syscall.Credential{
|
||||
Uid: uint32(uid),
|
||||
Gid: uint32(gid),
|
||||
@@ -978,11 +979,28 @@ func execTransferPodman(execUser *user.User, command []string, needToTag bool) (
|
||||
NoSetGroups: false,
|
||||
},
|
||||
}
|
||||
if needToTag {
|
||||
cmd.Stdout = nil
|
||||
return cmd.Output()
|
||||
run := func(dir string) ([]byte, error) {
|
||||
cmd := exec.Command(command[0], command[1:]...)
|
||||
// An explicit directory makes exec check access after changing credentials.
|
||||
cmd.Dir = dir
|
||||
cmd.Env = []string{"PATH=" + os.Getenv("PATH"), "TERM=" + os.Getenv("TERM")}
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.SysProcAttr = sysProcAttr
|
||||
if needToTag {
|
||||
return cmd.Output()
|
||||
}
|
||||
cmd.Stdout = os.Stdout
|
||||
return nil, cmd.Run()
|
||||
}
|
||||
return nil, cmd.Run()
|
||||
|
||||
out, err := run(cwd)
|
||||
// Preserve relative paths when possible. Only retry a failure to start;
|
||||
// a command that has already run must not be executed a second time.
|
||||
var pathErr *os.PathError
|
||||
if cwd != "/" && errors.As(err, &pathErr) && pathErr.Op == "fork/exec" && errors.Is(err, fs.ErrPermission) {
|
||||
return run("/")
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
|
||||
func getSigFilename(sigStoreDirPath string) (string, error) {
|
||||
|
||||
@@ -113,12 +113,24 @@ verify_iid_and_name() {
|
||||
if [[ -z "$notme" ]]; then
|
||||
skip "To run this test, set PODMAN_ROOTLESS_USER to a safe username"
|
||||
fi
|
||||
_sudo() { command sudo -n -u "$notme" "$@"; }
|
||||
_sudo() (
|
||||
cd /
|
||||
command sudo -n -u "$notme" "$@"
|
||||
)
|
||||
fi
|
||||
|
||||
# If we can't sudo, we can't test.
|
||||
_sudo true || skip "cannot sudo to $notme"
|
||||
|
||||
# Verify that save, load, and tag work when the destination user cannot access the caller's working directory.
|
||||
if ! is_rootless; then
|
||||
local private_dir=$PODMAN_TMPDIR/scp-cwd
|
||||
mkdir -m 0700 "$private_dir"
|
||||
run _sudo test -x "$private_dir"
|
||||
assert "$status" -eq 1 "destination user cannot access the working directory"
|
||||
cd "$private_dir"
|
||||
fi
|
||||
|
||||
# Preserve digest of original image; we will compare against it later
|
||||
run_podman image inspect --format '{{.RepoDigests}}' $IMAGE
|
||||
src_digests=$output
|
||||
@@ -178,6 +190,23 @@ verify_iid_and_name() {
|
||||
run_podman rmi foobar:123
|
||||
}
|
||||
|
||||
@test "podman image scp transfer with relative paths" {
|
||||
skip_if_remote "only applicable under local podman"
|
||||
skip_if_rootless "tests local transfers between root-owned stores"
|
||||
|
||||
cd "$PODMAN_TMPDIR"
|
||||
local conf=registries-$(random_string).conf
|
||||
printf 'unqualified-search-registries = ["example.com"]\n' > "$conf"
|
||||
|
||||
# Both forms must resolve paths relative to the caller's directory.
|
||||
run_podman --registries-conf "./$conf" image scp root@localhost::$IMAGE root@localhost::
|
||||
run_podman --registries-conf="./$conf" image scp root@localhost::$IMAGE root@localhost::
|
||||
run_podman --registries-conf "$PODMAN_TMPDIR/$conf" image scp root@localhost::$IMAGE root@localhost::
|
||||
|
||||
# A command failure must be returned without retrying from another directory.
|
||||
run_podman 125 --registries-conf "./$conf" image scp root@localhost::example.com/no-such-image:missing root@localhost::
|
||||
assert "$output" =~ "image not known" "missing image error is preserved"
|
||||
}
|
||||
|
||||
@test "podman load - by image ID" {
|
||||
# FIXME: how to build a simple archive instead?
|
||||
|
||||
@@ -23,12 +23,16 @@ adjust+:
|
||||
summary: local rootful test
|
||||
test: bash ./system.sh
|
||||
duration: 60m
|
||||
require+:
|
||||
- systemd-container
|
||||
|
||||
/local-rootless:
|
||||
tag: [ local, rootless ]
|
||||
summary: rootless test
|
||||
test: bash ./system.sh rootless
|
||||
duration: 60m
|
||||
require+:
|
||||
- systemd-container
|
||||
|
||||
/remote-root:
|
||||
tag: [ remote, root ]
|
||||
|
||||
Reference in new issue
Block a user