Skip to content

Commit 24fb43e

Browse files
committed
fix(cp): fix root path validation and uid/gid preservation
- Fix sanitizeTarPath to handle root '/' as destination correctly - Remove omitempty from Uid/Gid fields so 0 values (root ownership) are sent to server - Update hypeman-go dependency with symlink fixes
1 parent 088d120 commit 24fb43e

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/gorilla/websocket v1.5.3
1313
github.com/itchyny/json2yaml v0.1.4
1414
github.com/muesli/reflow v0.3.0
15-
github.com/onkernel/hypeman-go v0.7.1-0.20251223032806-c8e386b69845
15+
github.com/onkernel/hypeman-go v0.7.1-0.20251223035311-40c729ef8c06
1616
github.com/tidwall/gjson v1.18.0
1717
github.com/tidwall/pretty v1.2.1
1818
github.com/urfave/cli-docs/v3 v3.0.0-alpha6

pkg/cmd/cp.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ type cpRequest struct {
2828
IsDir bool `json:"is_dir,omitempty"`
2929
Mode uint32 `json:"mode,omitempty"`
3030
FollowLinks bool `json:"follow_links,omitempty"`
31-
Uid uint32 `json:"uid,omitempty"`
32-
Gid uint32 `json:"gid,omitempty"`
31+
Uid uint32 `json:"uid"`
32+
Gid uint32 `json:"gid"`
3333
}
3434

3535
// cpFileHeader is received from the server when copying from guest
@@ -257,7 +257,13 @@ func sanitizeTarPath(basePath, entryName string) (string, error) {
257257
// Verify the result is under the base path
258258
// path.Clean removes trailing slashes, so compare cleaned versions
259259
cleanBase := path.Clean(basePath)
260-
if !strings.HasPrefix(targetPath, cleanBase+"/") && targetPath != cleanBase {
260+
// Special case: if basePath is "/" (root), any absolute path under it is valid
261+
if cleanBase == "/" {
262+
// For root destination, just ensure the target is an absolute path (which path.Join guarantees)
263+
if !strings.HasPrefix(targetPath, "/") {
264+
return "", fmt.Errorf("invalid tar entry: path escapes destination: %s", entryName)
265+
}
266+
} else if !strings.HasPrefix(targetPath, cleanBase+"/") && targetPath != cleanBase {
261267
return "", fmt.Errorf("invalid tar entry: path escapes destination: %s", entryName)
262268
}
263269

0 commit comments

Comments
 (0)