mirror of
https://github.com/hauler-dev/hauler.git
synced 2026-08-19 12:26:27 +00:00
fixed bug with store sync extraction into unwritable directory (#737)
(cherry picked from commit 29a5c697b1)
# Conflicts:
# internal/flags/cli.go
# internal/flags/store.go
# pkg/consts/consts.go
This commit is contained in:
@@ -135,12 +135,14 @@ func SyncCmd(ctx context.Context, o *flags.SyncOpts, s *store.Layout, rso *flags
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch product manifest for [%s]: %w", productName, err)
|
||||
}
|
||||
err = ExtractCmd(ctx, &flags.ExtractOpts{StoreRootOpts: o.StoreRootOpts}, s, fmt.Sprintf("hauler/%s-manifest.yaml:%s", parts[0], tag))
|
||||
// The manifest is output for the user, so it goes to workDir, not tempDir (removed when sync returns).
|
||||
workDir := flags.ResolveWorkDir(ro)
|
||||
err = ExtractCmd(ctx, &flags.ExtractOpts{StoreRootOpts: o.StoreRootOpts, DestinationDir: workDir}, s, fmt.Sprintf("hauler/%s-manifest.yaml:%s", parts[0], tag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileName := fmt.Sprintf("%s-manifest.yaml", parts[0])
|
||||
fi, err := os.Open(fileName)
|
||||
fi, err := os.Open(filepath.Join(workDir, fileName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -6,6 +6,11 @@ type CliRootOpts struct {
|
||||
LogLevel string
|
||||
HaulerDir string
|
||||
IgnoreErrors bool
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
AuditLevel string
|
||||
WorkDir string
|
||||
>>>>>>> 29a5c69 (fixed bug with store sync extraction into unwritable directory (#737))
|
||||
}
|
||||
|
||||
func AddRootFlags(cmd *cobra.Command, ro *CliRootOpts) {
|
||||
@@ -13,5 +18,11 @@ func AddRootFlags(cmd *cobra.Command, ro *CliRootOpts) {
|
||||
|
||||
pf.StringVarP(&ro.LogLevel, "log-level", "l", "info", "Set the logging level (i.e. info, debug, warn)")
|
||||
pf.StringVarP(&ro.HaulerDir, "haulerdir", "d", "", "Set the location of the hauler directory (default $HOME/.hauler)")
|
||||
<<<<<<< HEAD
|
||||
pf.BoolVar(&ro.IgnoreErrors, "ignore-errors", false, "Ignore/Bypass errors (i.e. warn on error) (defaults false)")
|
||||
=======
|
||||
pf.BoolVar(&ro.IgnoreErrors, "ignore-errors", false, "Warn and continue instead of failing on errors, including storing images that failed verification (defaults false)")
|
||||
pf.StringVar(&ro.AuditLevel, "audit-level", "", "Set the audit logging level (none, standard, verbose) (defaults standard)")
|
||||
pf.StringVarP(&ro.WorkDir, "work-dir", "w", "", "(Optional) Set the directory for output that commands would otherwise write to the current directory (default: current directory)")
|
||||
>>>>>>> 29a5c69 (fixed bug with store sync extraction into unwritable directory (#737))
|
||||
}
|
||||
|
||||
@@ -61,3 +61,26 @@ func (o *StoreRootOpts) Store(ctx context.Context) (*store.Layout, error) {
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
// resolveHaulerDir mirrors other variable detection, but duplicated to avoid an import cycle
|
||||
func resolveHaulerDir(ro *CliRootOpts) string {
|
||||
if ro != nil && ro.HaulerDir != "" {
|
||||
return ro.HaulerDir
|
||||
}
|
||||
if d := os.Getenv(consts.HaulerDir); d != "" {
|
||||
return d
|
||||
}
|
||||
home, _ := os.UserHomeDir()
|
||||
return filepath.Join(home, consts.DefaultHaulerDirName)
|
||||
}
|
||||
|
||||
// ResolveWorkDir returns the configured output dir, or "" to mean the current directory (legacy behavior).
|
||||
func ResolveWorkDir(ro *CliRootOpts) string {
|
||||
if ro != nil && ro.WorkDir != "" {
|
||||
return ro.WorkDir
|
||||
}
|
||||
return os.Getenv(consts.HaulerWorkDir)
|
||||
}
|
||||
>>>>>>> 29a5c69 (fixed bug with store sync extraction into unwritable directory (#737))
|
||||
|
||||
@@ -89,8 +89,10 @@ func (s *pusher) Push(ctx context.Context, desc ocispec.Descriptor) (ccontent.Wr
|
||||
}
|
||||
fullFileName := filepath.Join(destDir, filename)
|
||||
|
||||
// Guard against path traversal (e.g. filename containing "../")
|
||||
if !strings.HasPrefix(fullFileName, destDir+string(filepath.Separator)) {
|
||||
// Guard against path traversal (e.g. "../"). filepath.Rel handles this
|
||||
// correctly even when destDir is "/", unlike a plain prefix check.
|
||||
rel, err := filepath.Rel(destDir, fullFileName)
|
||||
if err != nil || rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {
|
||||
return nil, fmt.Errorf("path_traversal_disallowed: %q resolves outside destination dir", filename)
|
||||
}
|
||||
|
||||
|
||||
@@ -87,10 +87,26 @@ const (
|
||||
CollectionGroup = "collection.hauler.cattle.io"
|
||||
|
||||
// environment variables
|
||||
<<<<<<< HEAD
|
||||
HaulerDir = "HAULER_DIR"
|
||||
HaulerTempDir = "HAULER_TEMP_DIR"
|
||||
HaulerStoreDir = "HAULER_STORE_DIR"
|
||||
HaulerIgnoreErrors = "HAULER_IGNORE_ERRORS"
|
||||
=======
|
||||
HaulerDir = "HAULER_DIR"
|
||||
HaulerTempDir = "HAULER_TEMP_DIR"
|
||||
HaulerWorkDir = "HAULER_WORK_DIR"
|
||||
HaulerStoreDir = "HAULER_STORE_DIR"
|
||||
HaulerIgnoreErrors = "HAULER_IGNORE_ERRORS"
|
||||
HaulerRetries = "HAULER_RETRIES"
|
||||
HaulerConcurrency = "HAULER_CONCURRENCY"
|
||||
HaulerBlobConcurrency = "HAULER_BLOB_CONCURRENCY"
|
||||
HaulerLogLevel = "HAULER_LOG_LEVEL"
|
||||
HaulerAuditLevel = "HAULER_AUDIT_LEVEL"
|
||||
|
||||
CaFile = "CA_FILE"
|
||||
InsecureSkipTLSVerify = "INSECURE_SKIP_TLS_VERIFY"
|
||||
>>>>>>> 29a5c69 (fixed bug with store sync extraction into unwritable directory (#737))
|
||||
|
||||
// container files and directories
|
||||
ImageManifestFile = "manifest.json"
|
||||
|
||||
Reference in New Issue
Block a user