summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2022-08-03 19:53:11 +0000
committerLaurent Bercot <ska@appnovation.com>2022-08-03 19:53:11 +0000
commit6e21f54b5519af90847d87158ecc75adb5892e1c (patch)
tree69c7d5ba2a75f5a2ef2578406fa3f9a1a4550c35
parent8ad0f7f39526ee0d8f52f44f5434dfd518f8897a (diff)
downloadmdevd-6e21f54b5519af90847d87158ecc75adb5892e1c.tar.xz
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 <ska@appnovation.com>
-rw-r--r--package/targets.mak2
-rw-r--r--src/mdevd/mdevd-coldplug.c6
-rw-r--r--src/mdevd/mdevd-internal.h3
-rw-r--r--src/mdevd/mdevd.c2
-rw-r--r--src/mdevd/mdevd_uevent_read.c8
5 files changed, 13 insertions, 8 deletions
diff --git a/package/targets.mak b/package/targets.mak
index 79e56ea..1a21f42 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -2,5 +2,7 @@ BIN_TARGETS := \
mdevd \
mdevd-coldplug
+INTERNAL_LIBS := libmdevd.a.xyzzy
+
LIBEXEC_TARGETS :=
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 <stdint.h>
#include <limits.h>
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)