When the first item in the entrypoint array is a symbolic link (to /bin/busybox, for example), the entrypoint validation resolves this link relative to the build machine, rather than relative to the target rootfs. So, for example, the architecture validation would check /bin/busybox for compatibility, rather than /tmp/corteca-<id>/rootfs/bin/busybox, which would cause the validation to fail unless the build and target machines are the same architecture.
A full resolution is tricky, since we can't rely on standard lib functions (filepath.EvalSymlinks() exhibits the same behaviour). A partial fix is implemented below, but it currently only handles a single level of indirection:
func ValidateRootFS(rootfsPath string, targetArch string, appSettings configuration.AppSettings) error {
entrypointPath := filepath.Join(rootfsPath, appSettings.Entrypoint[0])
// TODO: handle more than a single symlink degree
entrypointInfo, err := os.Lstat(entrypointPath)
if err != nil {
return err
}
if entrypointInfo.Mode()&os.ModeSymlink != 0 {
// construct a rootfs-based path to the symlink target
symPath, err := os.Readlink(entrypointPath)
if err != nil {
return err
}
entrypointPath = filepath.Join(rootfsPath, symPath)
}
if err := validateEntrypoint(entrypointPath, targetArch); err != nil {
return err
}
if err := validateMounts(rootfsPath, appSettings.Runtime.Mounts); err != nil {
return fmt.Errorf("runtime configuration error: %w", err)
}
return nil
}
This issue can be worked around by specifying the actual symlink targets in the entrypoint array. For example, if we wanted the container entry point to be a shell script, instead of specifying the entrypoint as ["/bin/sh", "/path/to/start.sh"], we could specify it as follows:
entrypoint:
- /bin/busybox
- sh
- /path/to/start.sh
When the first item in the entrypoint array is a symbolic link (to
/bin/busybox, for example), the entrypoint validation resolves this link relative to the build machine, rather than relative to the target rootfs. So, for example, the architecture validation would check/bin/busyboxfor compatibility, rather than/tmp/corteca-<id>/rootfs/bin/busybox, which would cause the validation to fail unless the build and target machines are the same architecture.A full resolution is tricky, since we can't rely on standard lib functions (
filepath.EvalSymlinks()exhibits the same behaviour). A partial fix is implemented below, but it currently only handles a single level of indirection:This issue can be worked around by specifying the actual symlink targets in the entrypoint array. For example, if we wanted the container entry point to be a shell script, instead of specifying the entrypoint as
["/bin/sh", "/path/to/start.sh"], we could specify it as follows: