Merge pull request #14598 from Luap99/service-systemd-fd

systemd socket activation: check listener to prevent panic
This commit is contained in:
Ed Santiago 2022-06-15 09:52:38 -06:00 committed by GitHub
commit 08f35dab5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 9 deletions

View File

@ -46,6 +46,10 @@ func restService(flags *pflag.FlagSet, cfg *entities.PodmanConfig, opts entities
return fmt.Errorf("wrong number of file descriptors for socket activation protocol (%d != 1)", len(listeners))
}
listener = listeners[0]
// note that activation.Listeners() returns nil when it cannot listen on the fd (i.e. udp connection)
if listener == nil {
return fmt.Errorf("unexpected fd received from systemd: cannot listen on it")
}
libpodRuntime.SetRemoteURI(listeners[0].Addr().String())
} else {
uri, err := url.Parse(opts.URI)

View File

@ -169,7 +169,7 @@ func (e EventJournalD) Read(ctx context.Context, options ReadOptions) error {
return nil
}
func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) { //nolint
func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) {
newEvent := Event{}
eventType, err := StringToType(entry.Fields["PODMAN_TYPE"])
if err != nil {

View File

@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"io/fs"
"net"
"os"
"os/exec"
"path/filepath"
@ -21,6 +22,7 @@ var _ = Describe("Systemd activate", func() {
var tempDir string
var err error
var podmanTest *PodmanTestIntegration
var activate string
BeforeEach(func() {
tempDir, err = testUtils.CreateTempDirInTempDir()
@ -31,17 +33,10 @@ var _ = Describe("Systemd activate", func() {
podmanTest = PodmanTestCreate(tempDir)
podmanTest.Setup()
})
AfterEach(func() {
podmanTest.Cleanup()
processTestResult(CurrentGinkgoTestDescription())
})
It("stop podman.service", func() {
SkipIfRemote("Testing stopped service requires both podman and podman-remote binaries")
activate, err := exec.LookPath("systemd-socket-activate")
activate, err = exec.LookPath("systemd-socket-activate")
if err != nil {
activate = "/usr/bin/systemd-socket-activate"
}
@ -54,7 +49,14 @@ var _ = Describe("Systemd activate", func() {
case err != nil:
Skip(err.Error())
}
})
AfterEach(func() {
podmanTest.Cleanup()
processTestResult(CurrentGinkgoTestDescription())
})
It("stop podman.service", func() {
// systemd-socket-activate does not support DNS lookups
host := "127.0.0.1"
port, err := podmanUtils.GetRandomPort()
@ -103,4 +105,37 @@ var _ = Describe("Systemd activate", func() {
Expect(abiSession).To(Exit(0))
Expect(abiSession.OutputToString()).To(Equal("true"))
})
It("invalid systemd file descriptor", func() {
host := "127.0.0.1"
port, err := podmanUtils.GetRandomPort()
Expect(err).ToNot(HaveOccurred())
addr := fmt.Sprintf("%s:%d", host, port)
// start systemd activation with datagram socket
activateSession := testUtils.StartSystemExec(activate, []string{
"--datagram", "--listen", addr,
podmanTest.PodmanBinary,
"--root=" + filepath.Join(tempDir, "server_root"),
"system", "service",
"--time=0",
})
Expect(activateSession.Exited).ShouldNot(Receive(), "Failed to start podman service")
// we have to wait for systemd-socket-activate to become ready
time.Sleep(1 * time.Second)
// now dial the socket to start podman
conn, err := net.Dial("udp", addr)
Expect(err).ToNot(HaveOccurred())
defer conn.Close()
_, err = conn.Write([]byte("test"))
Expect(err).ToNot(HaveOccurred())
// wait for podman to exit
activateSession.Wait(10)
Expect(activateSession).To(Exit(125))
Expect(activateSession.ErrorToString()).To(ContainSubstring("Error: unexpected fd received from systemd: cannot listen on it"))
})
})