Skip to content

Commit 28a90c6

Browse files
committed
Require absolute path for local API
Signed-off-by: Jan Rodák <[email protected]>
1 parent e732ee5 commit 28a90c6

File tree

7 files changed

+19
-9
lines changed

7 files changed

+19
-9
lines changed

internal/localapi/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package localapi
22

3+
import "errors"
4+
35
// LocalAPIMap is a map of local paths to their target paths in the VM
46
type LocalAPIMap struct {
57
ClientPath string `json:"ClientPath,omitempty"`
68
RemotePath string `json:"RemotePath,omitempty"`
79
}
10+
11+
var ErrPathNotAbsolute = errors.New("path is not absolute")

internal/localapi/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ func IsHyperVProvider(ctx context.Context) (bool, error) {
259259
// It returns an error if the path is not absolute or does not exist on the filesystem.
260260
func ValidatePathForLocalAPI(path string) error {
261261
if !filepath.IsAbs(path) {
262-
return fmt.Errorf("path %q is not absolute", path)
262+
return fmt.Errorf("%w: %q", ErrPathNotAbsolute, path)
263263
}
264264

265265
if err := fileutils.Exists(path); err != nil {

pkg/api/handlers/libpod/artifacts.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ func AddLocalArtifact(w http.ResponseWriter, r *http.Request) {
270270
switch err := localapi.ValidatePathForLocalAPI(cleanPath); {
271271
case err == nil:
272272
// no error -> continue
273+
case errors.Is(err, localapi.ErrPathNotAbsolute):
274+
utils.Error(w, http.StatusBadRequest, err)
275+
return
273276
case errors.Is(err, fs.ErrNotExist):
274277
utils.Error(w, http.StatusNotFound, fmt.Errorf("file does not exist: %q", cleanPath))
275278
return

pkg/api/handlers/libpod/images.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"strings"
1717

1818
"github.com/containers/buildah"
19+
"github.com/containers/podman/v6/internal/localapi"
1920
"github.com/containers/podman/v6/libpod"
2021
"github.com/containers/podman/v6/libpod/define"
2122
"github.com/containers/podman/v6/pkg/api/handlers"
@@ -41,7 +42,6 @@ import (
4142
"go.podman.io/storage"
4243
"go.podman.io/storage/pkg/archive"
4344
"go.podman.io/storage/pkg/chrootarchive"
44-
"go.podman.io/storage/pkg/fileutils"
4545
"go.podman.io/storage/pkg/idtools"
4646
)
4747

@@ -396,10 +396,13 @@ func ImagesLocalLoad(w http.ResponseWriter, r *http.Request) {
396396

397397
cleanPath := filepath.Clean(query.Path)
398398
// Check if the path exists on server side.
399-
// Note: fileutils.Exists returns nil if the file exists, not an error.
400-
switch err := fileutils.Exists(cleanPath); {
399+
// Note: localapi.ValidatePathForLocalAPI returns nil if the file exists and path is absolute, not an error.
400+
switch err := localapi.ValidatePathForLocalAPI(cleanPath); {
401401
case err == nil:
402402
// no error -> continue
403+
case errors.Is(err, localapi.ErrPathNotAbsolute):
404+
utils.Error(w, http.StatusBadRequest, err)
405+
return
403406
case errors.Is(err, fs.ErrNotExist):
404407
utils.Error(w, http.StatusNotFound, fmt.Errorf("file does not exist: %q", cleanPath))
405408
return

pkg/api/server/register_images.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
952952
// name: path
953953
// type: string
954954
// required: true
955-
// description: Path to the image archive file on the server filesystem
955+
// description: Absolute path to the image archive file on the server filesystem
956956
// produces:
957957
// - application/json
958958
// responses:

test/apiv2/10-images.at

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ t GET libpod/images/quay.io/libpod/busybox:latest/exists 204
502502

503503
# Test with directory instead of file
504504
mkdir -p ${TMPD}/testdir
505-
t POST libpod/local/images/load?path="${TMPD}/testdir" 500
505+
t POST libpod/local/images/load?path="${TMPD}/testdir" 400
506506

507507
cleanLoad
508508

@@ -512,6 +512,6 @@ t POST libpod/local/images/load?invalid=arg 400
512512

513513
t POST libpod/local/images/load?path="" 400
514514

515-
t POST libpod/local/images/load?path="../../../etc/passwd" 404
515+
t POST libpod/local/images/load?path="../../../etc/passwd" 400
516516

517517
# vim: filetype=sh

test/apiv2/python/rest_api/test_v2_0_0_artifact.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,12 +390,12 @@ def test_add_local_with_not_absolute_path(self):
390390
rjson = r.json()
391391

392392
# Assert correct response code
393-
self.assertEqual(r.status_code, 500, r.text)
393+
self.assertEqual(r.status_code, 400, r.text)
394394

395395
# Assert return error response is json and contains correct message
396396
self.assertEqual(
397397
rjson["cause"],
398-
'path "../../etc/passwd" is not absolute',
398+
'path is not absolute',
399399
)
400400

401401
def test_inspect(self):

0 commit comments

Comments
 (0)