From 6e21f54b5519af90847d87158ecc75adb5892e1c Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 3 Aug 2022 19:53:11 +0000 Subject: Fix mdevd-coldlplug -O loop bug mdevd-coldplug -O reads its data from mdevd, a user process, so the check that we only read kernel data is invalid. Add an option to mdevd_uevent_read() to activate the check or not. Signed-off-by: Laurent Bercot --- src/mdevd/mdevd-coldplug.c | 6 ++++-- src/mdevd/mdevd-internal.h | 3 ++- src/mdevd/mdevd.c | 2 +- src/mdevd/mdevd_uevent_read.c | 8 ++++---- 4 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/mdevd/mdevd-coldplug.c b/src/mdevd/mdevd-coldplug.c index 2be7be0..e692fd4 100644 --- a/src/mdevd/mdevd-coldplug.c +++ b/src/mdevd/mdevd-coldplug.c @@ -145,9 +145,11 @@ int main (int argc, char const *const *argv, char const *const *envp) if (nlgroup && subsystem[0] && mdev[0]) { struct uevent_s event ; - for (;;) if (mdevd_uevent_read(nlfd, &event, verbosity)) + for (;;) if (mdevd_uevent_read(nlfd, &event, 0, verbosity)) { - char *x = mdevd_uevent_getvar(&event, "SUBSYSTEM") ; + char *x = mdevd_uevent_getvar(&event, "ACTION") ; + if (strcmp(x, "add")) continue ; + x = mdevd_uevent_getvar(&event, "SUBSYSTEM") ; if (strcmp(x, subsystem)) continue ; x = mdevd_uevent_getvar(&event, "MDEV") ; if (!strcmp(x, mdev)) break ; diff --git a/src/mdevd/mdevd-internal.h b/src/mdevd/mdevd-internal.h index cc98a6d..cff7cdf 100644 --- a/src/mdevd/mdevd-internal.h +++ b/src/mdevd/mdevd-internal.h @@ -6,6 +6,7 @@ #define UEVENT_MAX_VARS 63 #define UEVENT_MAX_SIZE 8192 +#include #include struct uevent_s @@ -18,7 +19,7 @@ struct uevent_s #define UEVENT_ZERO { .len = 0, .varn = 0 } extern int mdevd_netlink_init (unsigned int, unsigned int) ; -extern int mdevd_uevent_read (int, struct uevent_s *, unsigned int) ; +extern int mdevd_uevent_read (int, struct uevent_s *, uint32_t, unsigned int) ; extern char *mdevd_uevent_getvar (struct uevent_s *, char const *) ; #endif diff --git a/src/mdevd/mdevd.c b/src/mdevd/mdevd.c index 2bc6e08..1ac2bc6 100644 --- a/src/mdevd/mdevd.c +++ b/src/mdevd/mdevd.c @@ -862,7 +862,7 @@ static inline int handle_signals (struct uevent_s *event, scriptelem const *scri static inline int handle_event (int fd, struct uevent_s *event, scriptelem const *script, unsigned short scriptlen, char const *storage, struct envmatch_s const *envmatch, udata *ud) { - if (!mdevd_uevent_read(fd, event, verbosity) || event->varn <= 1) return 0 ; + if (!mdevd_uevent_read(fd, event, 1, verbosity) || event->varn <= 1) return 0 ; return on_event(event, script, scriptlen, storage, envmatch, ud) ; } diff --git a/src/mdevd/mdevd_uevent_read.c b/src/mdevd/mdevd_uevent_read.c index 2cb4245..ed33843 100644 --- a/src/mdevd/mdevd_uevent_read.c +++ b/src/mdevd/mdevd_uevent_read.c @@ -24,7 +24,7 @@ static inline ssize_t fd_recvmsg (int fd, struct msghdr *hdr) return r ; } -static inline size_t netlink_read (int fd, char *s, unsigned int verbosity) +static inline size_t netlink_read (int fd, char *s, uint32_t options, unsigned int verbosity) { struct sockaddr_nl nl; struct iovec v = { .iov_base = s, .iov_len = UEVENT_MAX_SIZE } ; @@ -44,7 +44,7 @@ static inline size_t netlink_read (int fd, char *s, unsigned int verbosity) if (!r) return 0 ; if (msg.msg_flags & MSG_TRUNC) strerr_diefu1x(111, "buffer too small for netlink message") ; - if (nl.nl_pid) + if (options & 1 && nl.nl_pid) { if (verbosity >= 3) { @@ -67,10 +67,10 @@ static inline size_t netlink_read (int fd, char *s, unsigned int verbosity) return r ; } -int mdevd_uevent_read (int fd, struct uevent_s *event, unsigned int verbosity) +int mdevd_uevent_read (int fd, struct uevent_s *event, uint32_t options, unsigned int verbosity) { unsigned short len = 0 ; - event->len = netlink_read(fd, event->buf, verbosity) ; + event->len = netlink_read(fd, event->buf, options, verbosity) ; if (!event->len) return 0 ; event->varn = 0 ; while (len < event->len) -- cgit v1.2.3