Skip to content

Commit 0333219

Browse files
egibsstevebeattie
andauthored
fix: harden UPX exec calls and limit file name length (#1342)
Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> Co-authored-by: Steve Beattie <steve+github@nxnw.org>
1 parent a2a0de7 commit 0333219

2 files changed

Lines changed: 29 additions & 9 deletions

File tree

pkg/archive/upx.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,24 @@ func ExtractUPX(ctx context.Context, d, f string) error {
3131
return fmt.Errorf("failed to stat file: %w", err)
3232
}
3333

34-
gf, err := os.Open(f)
35-
if err != nil {
36-
return fmt.Errorf("failed to open file: %w", err)
34+
base := filepath.Base(f)
35+
if strings.HasPrefix(base, "-") {
36+
return fmt.Errorf("file name begins with '-': %q", base)
37+
}
38+
if len(base) > 255 {
39+
return fmt.Errorf("file name exceeds 255 characters")
3740
}
38-
defer gf.Close()
3941

4042
target := filepath.Join(d, filepath.Base(f))
4143
if !IsValidPath(target, d) {
4244
return fmt.Errorf("invalid file path: %s", target)
4345
}
4446

47+
absTarget, err := filepath.Abs(target)
48+
if err != nil {
49+
return fmt.Errorf("failed to get absolute path: %w", err)
50+
}
51+
4552
tf, err := os.ReadFile(f)
4653
if err != nil {
4754
return fmt.Errorf("failed to read file: %w", err)
@@ -52,18 +59,18 @@ func ExtractUPX(ctx context.Context, d, f string) error {
5259
return fmt.Errorf("failed to write file: %w", err)
5360
}
5461

55-
cmd := exec.CommandContext(ctx, "upx", "-d", "-k", target)
62+
cmd := exec.CommandContext(ctx, "upx", "-d", "-k", "--", absTarget)
5663
output, err := cmd.CombinedOutput()
5764
if err != nil {
58-
os.Remove(target)
65+
os.Remove(absTarget)
5966
return fmt.Errorf("failed to decompress upx file: %w, output: %s", err, output)
6067
}
6168

6269
if !strings.Contains(string(output), "Decompressed") && !strings.Contains(string(output), "Unpacked") {
63-
os.Remove(target)
70+
os.Remove(absTarget)
6471
return fmt.Errorf("upx decompression might have failed: %s", output)
6572
}
6673

67-
logger.Debug("successfully decompressed upx file", "output", string(output), "target", target)
74+
logger.Debug("successfully decompressed upx file", "output", string(output), "target", absTarget)
6875
return nil
6976
}

pkg/programkind/programkind.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,20 @@ func IsValidUPX(ctx context.Context, fc []byte, path string) (bool, error) {
249249
return false, err
250250
}
251251

252-
cmd := exec.CommandContext(ctx, "upx", "-l", "-f", path)
252+
base := filepath.Base(path)
253+
if strings.HasPrefix(path, "-") || strings.HasPrefix(base, "-") {
254+
return false, fmt.Errorf("path and/or file begins with '-': %q", path)
255+
}
256+
if len(base) > 255 {
257+
return false, fmt.Errorf("file name exceeds 255 characters")
258+
}
259+
260+
absPath, err := filepath.Abs(path)
261+
if err != nil {
262+
return false, err
263+
}
264+
265+
cmd := exec.CommandContext(ctx, "upx", "-l", "-f", "--", absPath)
253266
output, err := cmd.CombinedOutput()
254267

255268
if err != nil && (bytes.Contains(output, []byte("NotPackedException")) ||

0 commit comments

Comments
 (0)