mirror of https://github.com/OISF/suricata
systemd: reimplement sd_notify logic using UNIX socket
One of the lessons of the XZ backdoor story was that just linking to libsystemd to call sd_notify is discouraged by the systemd project: Lennart Poettering: "PSA: In context of the xzpocalypse we now added an example reimplementation of sd_notify() to our man page: https://www.freedesktop.org/software/systemd/man/devel/sd_notify.html#Notes It's pretty comprehensive (i.e. uses it for reload notification too), but still relatively short. In the past, I have been telling anyone who wanted to listen that if all you want is sd_notify() then don't bother linking to libsystemd, since the protocol is stable and should be considered the API, not our C wrapper around it. After all, the protocol is so trivial" From: https://mastodon.social/@pid_eins/112202687764571433 This commit takes the example code and uses it to reimplement the notify logic. The code is enabled if Linux is detected in configure. Since the code won't do anything if the NOTIFY_SOCKET env var isn't set, this should also work fine on systems w/o systemd. Ticket: #6913.pull/10790/head
parent
6d40517502
commit
34f53f85bc
@ -0,0 +1,91 @@
|
||||
/* SPDX-License-Identifier: MIT-0 */
|
||||
|
||||
/* Implement the systemd notify protocol without external dependencies.
|
||||
* Supports both readiness notification on startup and on reloading,
|
||||
* according to the protocol defined at:
|
||||
* https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html
|
||||
* This protocol is guaranteed to be stable as per:
|
||||
* https://systemd.io/PORTABILITY_AND_STABILITY/ */
|
||||
|
||||
/* this file is copied from:
|
||||
* https://github.com/systemd/systemd/blob/main/man/notify-selfcontained-example.c
|
||||
* written by Luca Boccassi */
|
||||
|
||||
#include "suricata-common.h"
|
||||
|
||||
#if (defined SYSTEMD_NOTIFY) && (defined HAVE_SYS_UN_H) && (defined HAVE_SYS_STAT_H) && \
|
||||
(defined HAVE_SYS_TYPES_H)
|
||||
#include <sys/un.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "util-systemd.h"
|
||||
|
||||
#define _cleanup_(f) __attribute__((cleanup(f)))
|
||||
|
||||
static void closep(int *fd)
|
||||
{
|
||||
if (!fd || *fd < 0)
|
||||
return;
|
||||
|
||||
close(*fd);
|
||||
*fd = -1;
|
||||
}
|
||||
|
||||
static int Notify(const char *message)
|
||||
{
|
||||
union sockaddr_union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_un sun;
|
||||
} socket_addr = {
|
||||
.sun.sun_family = AF_UNIX,
|
||||
};
|
||||
size_t path_length, message_length;
|
||||
_cleanup_(closep) int fd = -1;
|
||||
const char *socket_path;
|
||||
|
||||
socket_path = getenv("NOTIFY_SOCKET");
|
||||
if (!socket_path)
|
||||
return 0; /* Not running under systemd? Nothing to do */
|
||||
|
||||
if (!message)
|
||||
return -EINVAL;
|
||||
|
||||
message_length = strlen(message);
|
||||
if (message_length == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Only AF_UNIX is supported, with path or abstract sockets */
|
||||
if (socket_path[0] != '/' && socket_path[0] != '@')
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
path_length = strlen(socket_path);
|
||||
/* Ensure there is room for NUL byte */
|
||||
if (path_length >= sizeof(socket_addr.sun.sun_path))
|
||||
return -E2BIG;
|
||||
|
||||
memcpy(socket_addr.sun.sun_path, socket_path, path_length);
|
||||
|
||||
/* Support for abstract socket */
|
||||
if (socket_addr.sun.sun_path[0] == '@')
|
||||
socket_addr.sun.sun_path[0] = 0;
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (connect(fd, &socket_addr.sa, offsetof(struct sockaddr_un, sun_path) + path_length) != 0)
|
||||
return -errno;
|
||||
|
||||
ssize_t written = write(fd, message, message_length);
|
||||
if (written != (ssize_t)message_length)
|
||||
return written < 0 ? -errno : -EPROTO;
|
||||
|
||||
return 1; /* Notified! */
|
||||
}
|
||||
|
||||
int SystemDNotifyReady(void)
|
||||
{
|
||||
return Notify("READY=1");
|
||||
}
|
||||
#endif
|
@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: MIT-0 */
|
||||
|
||||
/* Implement the systemd notify protocol without external dependencies.
|
||||
* Supports both readiness notification on startup and on reloading,
|
||||
* according to the protocol defined at:
|
||||
* https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html
|
||||
* This protocol is guaranteed to be stable as per:
|
||||
* https://systemd.io/PORTABILITY_AND_STABILITY/ */
|
||||
|
||||
#ifndef SURICATA_UTIL_SYSTEMD_H
|
||||
#define SURICATA_UTIL_SYSTEMD_H
|
||||
|
||||
int SystemDNotifyReady(void);
|
||||
|
||||
#endif /* SURICATA_UTIL_SYSTEMD_H */
|
Loading…
Reference in New Issue