From 0228b3d53766aded8f0a9b87252852f28eceac54 Mon Sep 17 00:00:00 2001 From: Rebecca Mahany-Horton Date: Thu, 11 Apr 2024 16:07:08 -0400 Subject: [PATCH 1/6] Ensure file permissions are set appropriately when untarring archives during autoupdate (#1680) --- ee/tuf/library_manager.go | 90 ++++++++++++++++++++- ee/tuf/library_manager_test.go | 144 +++++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 37 +-------- 4 files changed, 233 insertions(+), 40 deletions(-) diff --git a/ee/tuf/library_manager.go b/ee/tuf/library_manager.go index 186792468..62cb27393 100644 --- a/ee/tuf/library_manager.go +++ b/ee/tuf/library_manager.go @@ -1,10 +1,13 @@ package tuf import ( + "archive/tar" "bytes" + "compress/gzip" "context" "fmt" "io" + "io/fs" "log/slog" "net/http" "os" @@ -16,7 +19,6 @@ import ( "time" "github.com/Masterminds/semver" - "github.com/kolide/kit/fsutil" "github.com/kolide/launcher/pkg/backoff" "github.com/kolide/launcher/pkg/traces" "github.com/theupdateframework/go-tuf/data" @@ -207,9 +209,8 @@ func (ulm *updateLibraryManager) moveVerifiedUpdate(binary autoupdatableBinary, } }() - // Untar the archive. Note that `UntarBundle` calls `filepath.Dir(destination)`, so the inclusion of `binary` - // here doesn't matter as it's immediately stripped off. - if err := fsutil.UntarBundle(filepath.Join(stagedVersionedDirectory, string(binary)), stagedUpdate); err != nil { + // Untar the archive. + if err := untar(stagedVersionedDirectory, stagedUpdate); err != nil { return fmt.Errorf("could not untar update to %s: %w", stagedVersionedDirectory, err) } @@ -249,6 +250,87 @@ func (ulm *updateLibraryManager) moveVerifiedUpdate(binary autoupdatableBinary, return nil } +// untar extracts the archive `source` to the given `destinationDir`. It sanitizes +// extract paths and file permissions. +func untar(destinationDir string, source string) error { + f, err := os.Open(source) + if err != nil { + return fmt.Errorf("opening source: %w", err) + } + defer f.Close() + + gzr, err := gzip.NewReader(f) + if err != nil { + return fmt.Errorf("creating gzip reader from %s: %w", source, err) + } + defer gzr.Close() + + tr := tar.NewReader(gzr) + for { + header, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + return fmt.Errorf("reading tar file: %w", err) + } + + if err := sanitizeExtractPath(destinationDir, header.Name); err != nil { + return fmt.Errorf("checking filename: %w", err) + } + + destPath := filepath.Join(destinationDir, header.Name) + info := header.FileInfo() + if info.IsDir() { + if err = os.MkdirAll(destPath, sanitizePermissions(info)); err != nil { + return fmt.Errorf("creating directory %s for tar file: %w", destPath, err) + } + continue + } + + if err := writeBundleFile(destPath, sanitizePermissions(info), tr); err != nil { + return fmt.Errorf("writing file: %w", err) + } + } + return nil +} + +// sanitizeExtractPath checks that the supplied extraction path is not +// vulnerable to zip slip attacks. See https://snyk.io/research/zip-slip-vulnerability +func sanitizeExtractPath(filePath string, destination string) error { + destpath := filepath.Join(destination, filePath) + if !strings.HasPrefix(destpath, filepath.Clean(destination)+string(os.PathSeparator)) { + return fmt.Errorf("illegal file path %s", filePath) + } + return nil +} + +// Allow owner read/write/execute, and only read/execute for all others. +const allowedPermissionBits fs.FileMode = fs.ModeType | 0755 + +// sanitizePermissions ensures that only the file owner has write permissions. +func sanitizePermissions(fileInfo fs.FileInfo) fs.FileMode { + return fileInfo.Mode() & allowedPermissionBits +} + +// writeBundleFile reads from the given reader to create a file at the given path, with the desired permissions. +func writeBundleFile(destPath string, perm fs.FileMode, srcReader io.Reader) error { + file, err := os.OpenFile(destPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, perm) + if err != nil { + return fmt.Errorf("opening %s: %w", destPath, err) + } + if _, err := io.Copy(file, srcReader); err != nil { + if closeErr := file.Close(); closeErr != nil { + return fmt.Errorf("copying to %s: %v; close error: %w", destPath, err, closeErr) + } + return fmt.Errorf("copying to %s: %w", destPath, err) + } + if err := file.Close(); err != nil { + return fmt.Errorf("closing %s: %w", destPath, err) + } + return nil +} + // removeUpdate removes a given version from the given binary's update library. func (ulm *updateLibraryManager) removeUpdate(binary autoupdatableBinary, binaryVersion string) { directoryToRemove := filepath.Join(updatesDirectory(binary, ulm.baseDir), binaryVersion) diff --git a/ee/tuf/library_manager_test.go b/ee/tuf/library_manager_test.go index 7143b7319..1a26c04ea 100644 --- a/ee/tuf/library_manager_test.go +++ b/ee/tuf/library_manager_test.go @@ -3,6 +3,7 @@ package tuf import ( "context" "fmt" + "io/fs" "net/http" "net/http/httptest" "os" @@ -12,6 +13,7 @@ import ( "sync" "testing" + "github.com/kolide/kit/ulid" tufci "github.com/kolide/launcher/ee/tuf/ci" "github.com/kolide/launcher/pkg/log/multislogger" "github.com/stretchr/testify/require" @@ -291,6 +293,148 @@ func TestAddToLibrary_verifyStagedUpdate_handlesInvalidFiles(t *testing.T) { } } +func Test_sanitizeExtractPath(t *testing.T) { + t.Parallel() + + var tests = []struct { + filepath string + destination string + expectError bool + }{ + { + filepath: "file", + destination: "/tmp", + expectError: false, + }, + { + filepath: "subdir/../subdir/file", + destination: "/tmp", + expectError: false, + }, + + { + filepath: "../../../file", + destination: "/tmp", + expectError: true, + }, + { + filepath: "./././file", + destination: "/tmp", + expectError: false, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.filepath, func(t *testing.T) { + t.Parallel() + + if tt.expectError { + require.Error(t, sanitizeExtractPath(tt.filepath, tt.destination), tt.filepath) + } else { + require.NoError(t, sanitizeExtractPath(tt.filepath, tt.destination), tt.filepath) + } + }) + } +} + +func Test_sanitizePermissions(t *testing.T) { + t.Parallel() + + testCases := []struct { + testCaseName string + givenFilePermissions fs.FileMode + }{ + { + testCaseName: "directory, valid permissions", + givenFilePermissions: fs.ModeDir | 0755, + }, + { + testCaseName: "directory, invalid permissions (group has write)", + givenFilePermissions: fs.ModeDir | 0775, + }, + { + testCaseName: "directory, invalid permissions (public has write)", + givenFilePermissions: fs.ModeDir | 0757, + }, + { + testCaseName: "directory, invalid permissions (everyone has write)", + givenFilePermissions: fs.ModeDir | 0777, + }, + { + testCaseName: "executable file, valid permissions", + givenFilePermissions: 0755, + }, + { + testCaseName: "executable file, invalid permissions (group has write)", + givenFilePermissions: 0775, + }, + { + testCaseName: "executable file, invalid permissions (public has write)", + givenFilePermissions: 0757, + }, + { + testCaseName: "executable file, invalid permissions (everyone has write)", + givenFilePermissions: 0777, + }, + { + testCaseName: "non-executable file, valid permissions", + givenFilePermissions: 0644, + }, + { + testCaseName: "non-executable file, invalid permissions (group has write)", + givenFilePermissions: 0664, + }, + { + testCaseName: "non-executable file, invalid permissions (public has write)", + givenFilePermissions: 0646, + }, + { + testCaseName: "non-executable file, invalid permissions (everyone has write)", + givenFilePermissions: 0666, + }, + } + + for _, tt := range testCases { + tt := tt + t.Run(tt.testCaseName, func(t *testing.T) { + t.Parallel() + + // Create a temp file to extract a FileInfo from it with tt.givenFilePermissions + tmpDir := t.TempDir() + pathUnderTest := filepath.Join(tmpDir, ulid.New()) + if tt.givenFilePermissions.IsDir() { + require.NoError(t, os.MkdirAll(pathUnderTest, tt.givenFilePermissions)) + } else { + f, err := os.OpenFile(pathUnderTest, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, tt.givenFilePermissions) + require.NoError(t, err) + require.NoError(t, f.Close()) + } + fileInfo, err := os.Stat(pathUnderTest) + require.NoError(t, err) + + sanitizedPermissions := sanitizePermissions(fileInfo) + + // Confirm no group write + require.True(t, sanitizedPermissions&0020 == 0) + + // Confirm no public write + require.True(t, sanitizedPermissions&0002 == 0) + + // Confirm type is set correctly + require.Equal(t, tt.givenFilePermissions.Type(), sanitizedPermissions.Type()) + + // Confirm owner permissions are unmodified + var ownerBits fs.FileMode = 0700 + if runtime.GOOS == "windows" { + // Windows doesn't have executable bit + ownerBits = 0600 + } + require.Equal(t, tt.givenFilePermissions&ownerBits, sanitizedPermissions&ownerBits) + }) + } +} + func TestTidyLibrary(t *testing.T) { t.Parallel() diff --git a/go.mod b/go.mod index 93b09d149..09311c981 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/gorilla/websocket v1.4.2 github.com/groob/plist v0.0.0-20190114192801-a99fbe489d03 github.com/knightsc/system_policy v1.1.1-0.20211029142728-5f4c0d5419cc - github.com/kolide/kit v0.0.0-20221107170827-fb85e3d59eab + github.com/kolide/kit v0.0.0-20240411131714-94dd1939cf50 github.com/kolide/krypto v0.1.1-0.20231229162826-db516b7e0121 github.com/mat/besticon v3.9.0+incompatible github.com/mattn/go-sqlite3 v1.14.19 diff --git a/go.sum b/go.sum index e41710438..9ad9e19e1 100644 --- a/go.sum +++ b/go.sum @@ -52,7 +52,6 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-ini/ini v1.61.0 h1:+IytwU4FcXqB+i5Vqiu/Ybf/Jdin9Pwzdxs5lmuT10o= github.com/go-ini/ini v1.61.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-kit/kit v0.7.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -66,8 +65,6 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.7.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -83,7 +80,6 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -129,7 +125,6 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -154,7 +149,6 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmoiron/sqlx v0.0.0-20180406164412-2aeb6a910c2b/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -165,8 +159,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/knightsc/system_policy v1.1.1-0.20211029142728-5f4c0d5419cc h1:g2S0GQD5Q2jXmPdTJS8L8JfA1GquHnFeK3PDcl26E/k= github.com/knightsc/system_policy v1.1.1-0.20211029142728-5f4c0d5419cc/go.mod h1:5e34JEkxWsOeAd9jvcxkz01tAY/JAGFuabGnNBJ6TT4= -github.com/kolide/kit v0.0.0-20221107170827-fb85e3d59eab h1:KVR7cs+oPyy85i+8t1ZaNSy1bymCy5FuWyt51pdrXu4= -github.com/kolide/kit v0.0.0-20221107170827-fb85e3d59eab/go.mod h1:OYYulo9tUqRadRLwB0+LE914sa1ui2yL7OrcU3Q/1XY= +github.com/kolide/kit v0.0.0-20240411131714-94dd1939cf50 h1:N7RaYBPTK5o4y2z1z8kl/G3iAeP73QCfAUH4y39GRCc= +github.com/kolide/kit v0.0.0-20240411131714-94dd1939cf50/go.mod h1:pFbEKXFww1uqu4RRO7qCnUmQ2EIwKYRzUqpJbODNlfc= github.com/kolide/krypto v0.1.1-0.20231229162826-db516b7e0121 h1:f7APX9VNsCkD/tdlAjbU4A22FyfTOCF6QadlvnzZElg= github.com/kolide/krypto v0.1.1-0.20231229162826-db516b7e0121/go.mod h1:/0sxd3OIxciTlMTeZI/9WTaUHsx/K/+3f+NbD5dywTY= github.com/kolide/systray v1.10.4 h1:eBhnVfhW0fGal1KBkBZC9fzRs4yrxUymgiXuQh5MBSg= @@ -183,7 +177,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -193,7 +186,6 @@ github.com/mat/besticon v3.9.0+incompatible h1:SLaWKCE7ptsjWbQee8Sbx8F/WK4bw8b55 github.com/mat/besticon v3.9.0+incompatible/go.mod h1:mA1auQYHt6CW5e7L9HJLmqVQC8SzNk2gVwouO0AbiEU= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -206,14 +198,12 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/ulid v0.3.0/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= -github.com/opencensus-integrations/ocsql v0.1.1/go.mod h1:ozPYpNVBHZsX33jfoQPO5TlI5lqh0/3R36kirEqJKAM= github.com/osquery/osquery-go v0.0.0-20210622151333-99b4efa62ec5/go.mod h1:JKR5QhjsYdnIPY7hakgas5sxf8qlA/9wQnLqaMfWdcg= github.com/osquery/osquery-go v0.0.0-20231006172600-d6f325f636a9 h1:+7IDjPDpcEwVqphCBCi/VWMF6sSSrqzJ3lq09K9cnAU= github.com/osquery/osquery-go v0.0.0-20231006172600-d6f325f636a9/go.mod h1:mLJRc1Go8uP32LRALGvWj2lVJ+hDYyIfxDzVa+C5Yo8= @@ -287,7 +277,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -322,7 +311,6 @@ github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= @@ -352,13 +340,10 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -384,22 +369,17 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -412,9 +392,6 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -433,8 +410,6 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -444,11 +419,7 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -465,7 +436,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191025023517-2077df36852e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -478,9 +448,7 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0= @@ -490,7 +458,6 @@ google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a h1:a2MQQVoTo96JC9PMGtGBymLp7+/RzpFc2yX/9WfFg1c= google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= From 227fef9810818d35a600cab74e2dbc0367cb7b36 Mon Sep 17 00:00:00 2001 From: Micah-Kolide <109157253+Micah-Kolide@users.noreply.github.com> Date: Fri, 19 Apr 2024 06:48:05 -0700 Subject: [PATCH 2/6] Fix command exec's `WithUid` (RunAsUser) when running as self (#1682) --- ee/tables/tablehelpers/run_as_user_posix.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ee/tables/tablehelpers/run_as_user_posix.go b/ee/tables/tablehelpers/run_as_user_posix.go index 923c1f7f1..cf4d72318 100644 --- a/ee/tables/tablehelpers/run_as_user_posix.go +++ b/ee/tables/tablehelpers/run_as_user_posix.go @@ -24,7 +24,10 @@ func WithUid(uid string) ExecOps { return fmt.Errorf("looking up user with uid %s: %w", uid, err) } - if currentUser.Uid != "0" && currentUser.Uid != runningUser.Uid { + // If the current user is the user to run as, then early return to avoid needing NoSetGroups. + if currentUser.Uid == runningUser.Uid { + return nil + } else if currentUser.Uid != "0" { return fmt.Errorf("current user %s is not root and can't start process for other user %s", currentUser.Uid, uid) } From 6db5135f9ffdf06df939b6665652b298aad4733d Mon Sep 17 00:00:00 2001 From: Micah-Kolide <109157253+Micah-Kolide@users.noreply.github.com> Date: Mon, 22 Apr 2024 10:25:06 -0700 Subject: [PATCH 3/6] Remove arg from flatpak command exec (#1684) --- pkg/osquery/table/platform_tables_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/osquery/table/platform_tables_linux.go b/pkg/osquery/table/platform_tables_linux.go index d1785e87f..2b3089aa4 100644 --- a/pkg/osquery/table/platform_tables_linux.go +++ b/pkg/osquery/table/platform_tables_linux.go @@ -62,7 +62,7 @@ func platformSpecificTables(slogger *slog.Logger, currentOsquerydBinaryPath stri dataflattentable.NewExecAndParseTable(slogger, "kolide_apt_upgradeable", apt.Parser, allowedcmd.Apt, []string{"list", "--upgradeable"}, dataflattentable.WithIncludeStderr()), dataflattentable.NewExecAndParseTable(slogger, "kolide_dnf_upgradeable", dnf.Parser, allowedcmd.Dnf, []string{"check-update"}, dataflattentable.WithIncludeStderr()), dataflattentable.NewExecAndParseTable(slogger, "kolide_dpkg_version_info", dpkg.Parser, allowedcmd.Dpkg, []string{"-p"}, dataflattentable.WithIncludeStderr()), - dataflattentable.NewExecAndParseTable(slogger, "kolide_flatpak_upgradeable", flatpak_upgradeable.Parser, allowedcmd.Flatpak, []string{"remote-ls", "--all", "--updates"}, dataflattentable.WithIncludeStderr()), + dataflattentable.NewExecAndParseTable(slogger, "kolide_flatpak_upgradeable", flatpak_upgradeable.Parser, allowedcmd.Flatpak, []string{"remote-ls", "--updates"}, dataflattentable.WithIncludeStderr()), dataflattentable.NewExecAndParseTable(slogger, "kolide_pacman_group", pacman_group.Parser, allowedcmd.Pacman, []string{"-Qg"}, dataflattentable.WithIncludeStderr()), dataflattentable.NewExecAndParseTable(slogger, "kolide_pacman_version_info", pacman_info.Parser, allowedcmd.Pacman, []string{"-Qi"}, dataflattentable.WithIncludeStderr()), dataflattentable.NewExecAndParseTable(slogger, "kolide_pacman_upgradeable", pacman_upgradeable.Parser, allowedcmd.Pacman, []string{"-Qu"}, dataflattentable.WithIncludeStderr()), From 34e8847d235e7317c2a1adb8cc4e51f996c86632 Mon Sep 17 00:00:00 2001 From: James Pickett Date: Tue, 23 Apr 2024 07:07:28 -0700 Subject: [PATCH 4/6] fix codeql allocation-size-overflow alert (#1686) --- ee/agent/storage/sqlite/keyvalue_store_sqlite.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ee/agent/storage/sqlite/keyvalue_store_sqlite.go b/ee/agent/storage/sqlite/keyvalue_store_sqlite.go index 22d91c14a..c63056047 100644 --- a/ee/agent/storage/sqlite/keyvalue_store_sqlite.go +++ b/ee/agent/storage/sqlite/keyvalue_store_sqlite.go @@ -6,6 +6,7 @@ import ( "embed" "errors" "fmt" + "math" "os" "path" "path/filepath" @@ -254,6 +255,13 @@ VALUES %s ON CONFLICT (name) DO UPDATE SET value=excluded.value;` valueStr := strings.TrimRight(strings.Repeat("(?, ?),", len(kvPairs)), ",") + // make sure we don't go over max int size + // this is driven codeql code scanning + // https://codeql.github.com/codeql-query-help/go/go-allocation-size-overflow/ + if len(kvPairs) > math.MaxInt/2 { + return nil, errors.New("too many key-value pairs") + } + // Build value args; save key names at the same time to determine which keys to prune later valueArgs := make([]any, 2*len(kvPairs)) keyNames := make([]any, len(kvPairs)) From 05b5f74b61248a351a392e37b886ebae504b47cf Mon Sep 17 00:00:00 2001 From: seph Date: Wed, 24 Apr 2024 18:09:45 -0400 Subject: [PATCH 5/6] Fix panic in 1.6.4 (#1689) --- pkg/service/publish_results.go | 18 ++++++++--- pkg/service/publish_results_test.go | 49 +++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 pkg/service/publish_results_test.go diff --git a/pkg/service/publish_results.go b/pkg/service/publish_results.go index 240fb8ee5..8bf56ccf3 100644 --- a/pkg/service/publish_results.go +++ b/pkg/service/publish_results.go @@ -184,10 +184,6 @@ func (s *grpcServer) PublishResults(ctx context.Context, req *pb.ResultCollectio func (mw logmw) PublishResults(ctx context.Context, nodeKey string, results []distributed.Result) (message, errcode string, reauth bool, err error) { defer func(begin time.Time) { resJSON, _ := json.Marshal(results) - resTruncated := string(resJSON[:200]) - if len(resJSON) > 200 { - resTruncated += "..." - } uuid, _ := uuid.FromContext(ctx) @@ -202,7 +198,7 @@ func (mw logmw) PublishResults(ctx context.Context, nodeKey string, results []di mw.knapsack.Slogger().Log(ctx, levelForError(err), message, // nolint:sloglint // it's fine to not have a constant or literal here "method", "PublishResults", "uuid", uuid, - "results_truncated", resTruncated, + "results_truncated", trivialTruncate(string(resJSON), 200), "result_count", len(results), "result_size", len(resJSON), "errcode", errcode, @@ -220,3 +216,15 @@ func (mw uuidmw) PublishResults(ctx context.Context, nodeKey string, results []d ctx = uuid.NewContext(ctx, uuid.NewForRequest()) return mw.next.PublishResults(ctx, nodeKey, results) } + +// trivialTruncate performs a trivial truncate operation on strings. Because it's string based, it may not handle +// multibyte characters correctly. Note that this actually returns a string length of maxLen +3, but that's okay +// because it's only used to keep logs from being too huge. +func trivialTruncate(str string, maxLen int) string { + if len(str) <= maxLen { + return str + } + + return str[:maxLen] + "..." + +} diff --git a/pkg/service/publish_results_test.go b/pkg/service/publish_results_test.go new file mode 100644 index 000000000..31bd71094 --- /dev/null +++ b/pkg/service/publish_results_test.go @@ -0,0 +1,49 @@ +package service + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_TrivialTruncate(t *testing.T) { + t.Parallel() + + const maxLen = 5 + var tests = []struct { + in string + expected string + }{ + { + in: "", + expected: "", + }, + { + in: "1", + expected: "1", + }, + { + in: "short", + expected: "short", + }, + { + in: "and this is a long string", + expected: "and t...", + }, + { + in: "我喜歡吃辣的食物", + expected: "我\xe5\x96...", + }, + } + + for _, tt := range tests { + tt := tt + t.Run("", func(t *testing.T) { + t.Parallel() + }) + + actual := trivialTruncate(tt.in, maxLen) + require.Equal(t, tt.expected, actual) + } + +} From 20342a0827f758d435d3af0b0b64b15b44b33716 Mon Sep 17 00:00:00 2001 From: seph Date: Wed, 24 Apr 2024 18:17:09 -0400 Subject: [PATCH 6/6] Bump go version in docker (#1688) --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0f9ee41ba..a3680318f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ # Note that multistage builds can leverage the tag applied (at build # time) to this container -FROM --platform=linux/amd64 golang:1.20 AS golauncherbuild +FROM --platform=linux/amd64 golang:1.21 AS golauncherbuild LABEL maintainer="engineering@kolide.co" # fake data or not?