kubelet: use new securejoin API

Using securejoin.SecureJoin() ensures that paths are bound within a
given root, but it doesn't protect from changes happening between the
construction of the path and its use. securejoin 0.3 introduces a new
Linux-specific API which avoids this by making rooted open operations
explicit; this migrates kubelet's log retrieval to use that.

Signed-off-by: Stephen Kitt <skitt@redhat.com>
This commit is contained in:
Stephen Kitt
2024-10-03 16:02:44 +02:00
parent 7918e9f0cb
commit 16817e8f4f
21 changed files with 1820 additions and 132 deletions

View File

@@ -21,8 +21,13 @@ package kubelet
import (
"context"
"fmt"
"io"
"os"
"os/exec"
"strings"
securejoin "github.com/cyphar/filepath-securejoin"
unix "golang.org/x/sys/unix"
)
// getLoggingCmd returns the journalctl cmd and arguments for the given nodeLogQuery and boot. Note that
@@ -72,3 +77,32 @@ func checkForNativeLogger(ctx context.Context, service string) bool {
// hence we search for it in the list of services known to journalctl
return strings.Contains(string(output), service+".service")
}
// heuristicsCopyFileLog returns the contents of the given logFile
func heuristicsCopyFileLog(ctx context.Context, w io.Writer, logDir, logFileName string) error {
f, err := securejoin.OpenInRoot(logDir, logFileName)
if err != nil {
return err
}
// Ignoring errors when closing a file opened read-only doesn't cause data loss
defer func() { _ = f.Close() }()
fInfo, err := f.Stat()
if err != nil {
return err
}
// This is to account for the heuristics where logs for service foo
// could be in /var/log/foo/
if fInfo.IsDir() {
return os.ErrNotExist
}
rf, err := securejoin.Reopen(f, unix.O_RDONLY)
if err != nil {
return err
}
defer func() { _ = rf.Close() }()
if _, err := io.Copy(w, newReaderCtx(ctx, rf)); err != nil {
return err
}
return nil
}