Skip to content

Commit

Permalink
Improve handling of nonexistent symlinks for extractions + programkind (
Browse files Browse the repository at this point in the history
#709)

* Improve handling of nonexistent symlinks for extractions + programkind

Signed-off-by: egibs <20933572+egibs@users.noreply.github.com>

* Appease the linter

Signed-off-by: egibs <20933572+egibs@users.noreply.github.com>

---------

Signed-off-by: egibs <20933572+egibs@users.noreply.github.com>
  • Loading branch information
egibs authored Dec 16, 2024
1 parent 4cb8edf commit 191c6f3
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
34 changes: 31 additions & 3 deletions pkg/action/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,21 @@ func extractTar(ctx context.Context, d string, f string) error {
return fmt.Errorf("failed to close file: %w", err)
}
case tar.TypeSymlink:
if err := os.Symlink(header.Linkname, target); err != nil {
// Skip symlinks for targets that do not exist
_, err = os.Readlink(target)
if os.IsNotExist(err) {
continue
}
// Ensure that symlinks are not relative path traversals
// #nosec G305 // L208 handles the check
linkReal, err := filepath.EvalSymlinks(filepath.Join(d, header.Linkname))
if err != nil {
return fmt.Errorf("failed to evaluate symlink: %w", err)
}
if !strings.HasPrefix(linkReal, filepath.Clean(d)+string(os.PathSeparator)) {
return fmt.Errorf("symlink points outside temporary directory: %s", linkReal)
}
if err := os.Symlink(linkReal, target); err != nil {
return fmt.Errorf("failed to create symlink: %w", err)
}
}
Expand Down Expand Up @@ -428,7 +442,7 @@ func extractDeb(ctx context.Context, d, f string) error {

for {
header, err := df.Data.Next()
if err == io.EOF {
if errors.Is(err, io.EOF) {
break
}
if err != nil {
Expand Down Expand Up @@ -469,7 +483,21 @@ func extractDeb(ctx context.Context, d, f string) error {
return fmt.Errorf("failed to close file: %w", err)
}
case tar.TypeSymlink:
if err := os.Symlink(header.Linkname, target); err != nil {
// Skip symlinks for targets that do not exist
_, err = os.Readlink(target)
if os.IsNotExist(err) {
continue
}
// Ensure that symlinks are not relative path traversals
// #nosec G305 // L208 handles the check
linkReal, err := filepath.EvalSymlinks(filepath.Join(d, header.Linkname))
if err != nil {
return fmt.Errorf("failed to evaluate symlink: %w", err)
}
if !strings.HasPrefix(linkReal, filepath.Clean(d)+string(os.PathSeparator)) {
return fmt.Errorf("symlink points outside temporary directory: %s", linkReal)
}
if err := os.Symlink(linkReal, target); err != nil {
return fmt.Errorf("failed to create symlink: %w", err)
}
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/programkind/programkind.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ func makeFileType(path string, ext string, mime string) *FileType {

// File detects what kind of program this file might be.
func File(path string) (*FileType, error) {
// Follow symlinks and return cleanly if the target does not exist
_, err := filepath.EvalSymlinks(path)
if os.IsNotExist(err) {
return nil, nil
}

st, err := os.Stat(path)
if err != nil {
return nil, fmt.Errorf("stat: %w", err)
Expand Down

0 comments on commit 191c6f3

Please sign in to comment.