Skip to content

Commit e7bef55

Browse files
committed
pkg/podman/podman: Add DoesImageFulfillRequirements() function
Add unified image validation function that checks multiple compatibility requirements including Toolbx labels, LD_PRELOAD environment variable, and image entrypoint. Returns boolean compatibility status along with detailed warning messages for any detected issues. Signed-off-by: Dalibor Kricka <[email protected]>
1 parent d516223 commit e7bef55

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

src/pkg/podman/podman.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"fmt"
2525
"io"
2626
"strconv"
27+
"strings"
2728
"time"
2829

2930
"github.com/HarryMichal/go-version"
@@ -363,6 +364,73 @@ func IsToolboxImage(image string) (bool, error) {
363364
return true, nil
364365
}
365366

367+
func IsLDPRELOADEnvSet(image string) (bool, error) {
368+
info, err := InspectImage(image)
369+
if err != nil {
370+
return false, fmt.Errorf("failed to inspect image %s: %s", image, err)
371+
}
372+
373+
if info["Config"] == nil {
374+
return false, nil
375+
}
376+
377+
config := info["Config"].(map[string]interface{})
378+
if config["Env"] == nil {
379+
return false, nil
380+
}
381+
382+
env := config["Env"]
383+
switch envVars := env.(type) {
384+
case []interface{}:
385+
for _, envVar := range envVars {
386+
if envVarStr, ok := envVar.(string); ok {
387+
envVarStrTrimmed := strings.TrimSpace(envVarStr)
388+
if strings.HasPrefix(envVarStrTrimmed, "LD_PRELOAD=") {
389+
return true, nil
390+
}
391+
}
392+
}
393+
case []string:
394+
for _, envVar := range envVars {
395+
envVarTrimmed := strings.TrimSpace(envVar)
396+
if strings.HasPrefix(envVarTrimmed, "LD_PRELOAD=") {
397+
return true, nil
398+
}
399+
}
400+
default:
401+
return false, fmt.Errorf("unexpected type '%T' of environment variables in image %s", env, image)
402+
}
403+
404+
return false, nil
405+
}
406+
407+
func HasImageEntrypoint(image string) (bool, error) {
408+
info, err := InspectImage(image)
409+
if err != nil {
410+
return false, fmt.Errorf("failed to inspect image %s: %s", image, err)
411+
}
412+
413+
if info["Config"] == nil {
414+
return false, nil
415+
}
416+
417+
config := info["Config"].(map[string]interface{})
418+
if config["Entrypoint"] == nil {
419+
return false, nil
420+
}
421+
422+
entrypoint := config["Entrypoint"]
423+
424+
switch ep := entrypoint.(type) {
425+
case []interface{}:
426+
return len(ep) > 0, nil
427+
case []string:
428+
return len(ep) > 0, nil
429+
default:
430+
return false, fmt.Errorf("unexpected type '%T' of entrypoint of image %s", entrypoint, image)
431+
}
432+
}
433+
366434
func Logs(container string, since time.Time, stderr io.Writer) error {
367435
ctx := context.Background()
368436
err := LogsContext(ctx, container, false, since, stderr)
@@ -506,3 +574,38 @@ func SystemMigrate(ociRuntimeRequired string) error {
506574

507575
return nil
508576
}
577+
578+
func DoesImageFulfillRequirements(image string) (bool, string, error) {
579+
var warnings []string
580+
581+
isToolboxImage, err := IsToolboxImage(image)
582+
if err != nil {
583+
return false, "", fmt.Errorf("failed to verify image compatibility: %w", err)
584+
}
585+
if !isToolboxImage {
586+
warnings = append(warnings, fmt.Sprintf("Warning: Image '%s' does not contain either of the labels 'com.github.containers.toolbox=true' and 'com.github.debarshiray.toolbox=true'", image))
587+
}
588+
589+
isLDPRELOADEnvSet, err := IsLDPRELOADEnvSet(image)
590+
if err != nil {
591+
return false, "", fmt.Errorf("failed to validate LD_PRELOAD variable settings: %w", err)
592+
}
593+
if isLDPRELOADEnvSet {
594+
warnings = append(warnings, fmt.Sprintf("Warning: Image '%s' has environment variable LD_PRELOAD set, which may cause container vulnerability (Container Escape)", image))
595+
}
596+
597+
hasEntrypoint, err := HasImageEntrypoint(image)
598+
if err != nil {
599+
return false, "", fmt.Errorf("failed to check image entrypoint: %w", err)
600+
}
601+
if hasEntrypoint {
602+
warnings = append(warnings, fmt.Sprintf("Warning: Image '%s' has an entrypoint defined", image))
603+
}
604+
605+
if len(warnings) > 0 {
606+
warningMessage := strings.Join(warnings, "\n")
607+
return false, warningMessage, nil
608+
}
609+
610+
return true, "", nil
611+
}

0 commit comments

Comments
 (0)