From 7a07a16ecb4d9598f383e29b9c98748babe7be8e Mon Sep 17 00:00:00 2001 From: Clayton Craft Date: Fri, 1 Aug 2025 23:23:07 -0700 Subject: [PATCH] misc/getfiles: fix infinite recursion loop when given a symlink This fixes an infinite recursion loop in getFile caused by: 1) `os.Stat(file)` resolves a symlink so that `fileInfo.isDir()` returns True 2) `filepath.Walk()` starts iterating on the root directory (in this case the symlink) 3) `filepath.Walk()` uses `os.Lstat` internally, which does NOT dereference the symlink 4) in the walk func, `f.isDir()` returns False, and the walk func calls `getFile()` on it 5) goto 1 fixes #47 Part-of: https://gitlab.postmarketos.org/postmarketOS/postmarketos-mkinitfs/-/merge_requests/65 --- internal/misc/getfiles.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/internal/misc/getfiles.go b/internal/misc/getfiles.go index 3c0eea1..552ff97 100644 --- a/internal/misc/getfiles.go +++ b/internal/misc/getfiles.go @@ -3,6 +3,7 @@ package misc import ( "debug/elf" "fmt" + "io/fs" "os" "path/filepath" @@ -39,6 +40,24 @@ func getFile(file string, required bool) (files []string, err error) { return RemoveDuplicates(files), nil } + // If the file is a symlink we need to do this to prevent an infinite recursion + // loop: + // Symlinks need special handling to prevent infinite recursion: + // 1) add the symlink to the list of files + // 2) set file to dereferenced target + // 4) continue this function to either walk it if the target is a dir or add the + // target to the list of files + if s, err := os.Lstat(file); err != nil { + return files, err + } else if s.Mode()&fs.ModeSymlink != 0 { + files = append(files, file) + if target, err := filepath.EvalSymlinks(file); err != nil { + return files, err + } else { + file = target + } + } + fileInfo, err := os.Stat(file) if err != nil { // Check if there is a Zstd-compressed version of the file