libudev-zero: import upstream patches
authorDaniel Golle <[email protected]>
Sat, 12 Jul 2025 02:01:08 +0000 (03:01 +0100)
committerTianling Shen <[email protected]>
Sat, 12 Jul 2025 05:18:49 +0000 (13:18 +0800)
udev_device.c: fix TOCTOU race condition (illiliti/libudev-zero#57)

illiliti/libudev-zero@a2cc51bb142c16eac5598237d2edb46f095607be

Avoidable OOM on small systems (illiliti/libudev-zero#62)

illiliti/libudev-zero@5eca08d71d51074bfe7b14fcf7d89318f4f6ff47

Fixes incorrect detection of touchpads (illiliti/libudev-zero#66)

illiliti/libudev-zero@bbeb7ad51c1edb7ab3cf63f30a21e9bb383b7994

Signed-off-by: Daniel Golle <[email protected]>
libs/libudev-zero/Makefile
libs/libudev-zero/patches/0001-udev_device.c-fix-TOCTOU-race-condition-57.patch [new file with mode: 0644]
libs/libudev-zero/patches/0002-Avoidable-OOM-on-small-systems-62.patch [new file with mode: 0644]
libs/libudev-zero/patches/0003-Fixes-incorrect-detection-of-touchpads-66.patch [new file with mode: 0644]

index 0d18307bc38e62c616de6d1865487dd041166dda..e8a5cb19ac22898ad4288fb510cf8cfe98099414 100644 (file)
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libudev-zero
 PKG_VERSION:=1.0.3
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/illiliti/libudev-zero/tar.gz/$(PKG_VERSION)?
diff --git a/libs/libudev-zero/patches/0001-udev_device.c-fix-TOCTOU-race-condition-57.patch b/libs/libudev-zero/patches/0001-udev_device.c-fix-TOCTOU-race-condition-57.patch
new file mode 100644 (file)
index 0000000..4d3528d
--- /dev/null
@@ -0,0 +1,59 @@
+From a2cc51bb142c16eac5598237d2edb46f095607be Mon Sep 17 00:00:00 2001
+From: Mingjie Shen <[email protected]>
+Date: Tue, 5 Dec 2023 03:41:24 -0500
+Subject: [PATCH] udev_device.c: fix TOCTOU race condition (#57)
+
+Separately checking the state of a file before operating on it may allow
+an attacker to modify the file between the two operations.
+
+Reference: CWE-367.
+---
+ udev_device.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+--- a/udev_device.c
++++ b/udev_device.c
+@@ -267,16 +267,17 @@ const char *udev_device_get_sysattr_valu
+     snprintf(path, sizeof(path), "%s/%s", udev_device_get_syspath(udev_device), sysattr);
+-    if (lstat(path, &st) != 0 || !S_ISREG(st.st_mode)) {
+-        return NULL;
+-    }
+-
+     file = fopen(path, "r");
+     if (!file) {
+         return NULL;
+     }
++    if (fstat(fileno(file), &st) != 0 || !S_ISREG(st.st_mode)) {
++        fclose(file);
++        return NULL;
++    }
++
+     // TODO dynamic allocation of data
+     len = fread(data, 1, sizeof(data) - 1, file);
+@@ -309,16 +310,17 @@ int udev_device_set_sysattr_value(struct
+     snprintf(path, sizeof(path), "%s/%s", udev_device_get_syspath(udev_device), sysattr);
+-    if (lstat(path, &st) != 0 || !S_ISREG(st.st_mode)) {
+-        return -1;
+-    }
+-
+     file = fopen(path, "w");
+     if (!file) {
+         return -1;
+     }
++    if (fstat(fileno(file), &st) != 0 || !S_ISREG(st.st_mode)) {
++        fclose(file);
++        return -1;
++    }
++
+     len = strlen(value);
+     if (fwrite(value, 1, len, file) != len) {
diff --git a/libs/libudev-zero/patches/0002-Avoidable-OOM-on-small-systems-62.patch b/libs/libudev-zero/patches/0002-Avoidable-OOM-on-small-systems-62.patch
new file mode 100644 (file)
index 0000000..904f41f
--- /dev/null
@@ -0,0 +1,163 @@
+From 5eca08d71d51074bfe7b14fcf7d89318f4f6ff47 Mon Sep 17 00:00:00 2001
+From: liamHowatt <[email protected]>
+Date: Tue, 5 Dec 2023 04:15:26 -0500
+Subject: [PATCH] Avoidable OOM on small systems (#62)
+
+* bandaid fix OOM
+
+* refactor fix OOM
+
+* Makefile: remove no longer needed -pthread option
+
+* libudev.pc.in: remove threads requirement
+
+---------
+
+Co-authored-by: illiliti <[email protected]>
+---
+ Makefile         |  2 +-
+ libudev.pc.in    |  1 -
+ udev_enumerate.c | 65 +++++++++++-------------------------------------
+ 3 files changed, 15 insertions(+), 53 deletions(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -5,7 +5,7 @@ PREFIX = /usr/local
+ LIBDIR = ${PREFIX}/lib
+ INCLUDEDIR = ${PREFIX}/include
+ PKGCONFIGDIR = ${LIBDIR}/pkgconfig
+-XCFLAGS = ${CPPFLAGS} ${CFLAGS} -std=c99 -fPIC -pthread -D_XOPEN_SOURCE=700 \
++XCFLAGS = ${CPPFLAGS} ${CFLAGS} -std=c99 -fPIC -D_XOPEN_SOURCE=700 \
+                 -Wall -Wextra -Wpedantic -Wmissing-prototypes -Wstrict-prototypes \
+                 -Wno-unused-parameter
+ XLDFLAGS = ${LDFLAGS} -shared -Wl,-soname,libudev.so.1
+--- a/libudev.pc.in
++++ b/libudev.pc.in
+@@ -9,5 +9,4 @@ Description: Daemonless replacement for
+ Version: @VERSION@
+ URL: https://github.com/illiliti/libudev-zero
+ Libs: -L${libdir} -ludev
+-Libs.private: -pthread
+ Cflags: -I${includedir}
+--- a/udev_enumerate.c
++++ b/udev_enumerate.c
+@@ -21,7 +21,6 @@
+ #include <string.h>
+ #include <limits.h>
+ #include <fnmatch.h>
+-#include <pthread.h>
+ #include "udev.h"
+ #include "udev_list.h"
+@@ -38,13 +37,6 @@ struct udev_enumerate {
+     int refcount;
+ };
+-struct udev_enumerate_thread {
+-    struct udev_enumerate *udev_enumerate;
+-    pthread_mutex_t *mutex;
+-    char path[PATH_MAX];
+-    pthread_t thread;
+-};
+-
+ int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
+ {
+     return udev_enumerate ? !!udev_list_entry_add(&udev_enumerate->subsystem_match, subsystem, NULL, 0) - 1 : -1;
+@@ -231,31 +223,27 @@ static int filter_sysattr(struct udev_en
+     return 1;
+ }
+-static void *add_device(void *ptr)
++static void add_device(struct udev_enumerate *udev_enumerate, const char *path)
+ {
+-    struct udev_enumerate_thread *thread = ptr;
+     struct udev_device *udev_device;
+-    udev_device = udev_device_new_from_syspath(thread->udev_enumerate->udev, thread->path);
++    udev_device = udev_device_new_from_syspath(udev_enumerate->udev, path);
+     if (!udev_device) {
+-        return NULL;
++        return;
+     }
+-    if (!filter_subsystem(thread->udev_enumerate, udev_device) ||
+-        !filter_sysname(thread->udev_enumerate, udev_device) ||
+-        !filter_property(thread->udev_enumerate, udev_device) ||
+-        !filter_sysattr(thread->udev_enumerate, udev_device)) {
++    if (!filter_subsystem(udev_enumerate, udev_device) ||
++        !filter_sysname(udev_enumerate, udev_device) ||
++        !filter_property(udev_enumerate, udev_device) ||
++        !filter_sysattr(udev_enumerate, udev_device)) {
+         udev_device_unref(udev_device);
+-        return NULL;
++        return;
+     }
+-    pthread_mutex_lock(thread->mutex);
+-    udev_list_entry_add(&thread->udev_enumerate->devices, udev_device_get_syspath(udev_device), NULL, 0);
+-    pthread_mutex_unlock(thread->mutex);
++    udev_list_entry_add(&udev_enumerate->devices, udev_device_get_syspath(udev_device), NULL, 0);
+     udev_device_unref(udev_device);
+-    return NULL;
+ }
+ static int filter_dot(const struct dirent *de)
+@@ -265,9 +253,7 @@ static int filter_dot(const struct diren
+ static int scan_devices(struct udev_enumerate *udev_enumerate, const char *path)
+ {
+-    struct udev_enumerate_thread *thread;
+-    pthread_mutex_t mutex;
+-    int i, cnt, ret = 1;
++    int i, cnt;
+     struct dirent **de;
+     cnt = scandir(path, &de, filter_dot, NULL);
+@@ -276,41 +262,18 @@ static int scan_devices(struct udev_enum
+         return 0;
+     }
+-    thread = calloc(cnt, sizeof(*thread));
+-
+-    if (!thread) {
+-        ret = 0;
+-        goto free_de;
+-    }
+-
+-    pthread_mutex_init(&mutex, NULL);
+-
+-    for (i = 0; i < cnt; i++) {
+-        thread[i].mutex = &mutex;
+-        thread[i].udev_enumerate = udev_enumerate;
+-
+-        snprintf(thread[i].path, sizeof(thread[i].path), "%s/%s", path, de[i]->d_name);
+-
+-        if (pthread_create(&thread[i].thread, NULL, add_device, &thread[i]) != 0) {
+-            ret = 0;
+-            break;
+-        }
+-    }
+-
+     for (i = 0; i < cnt; i++) {
+-        pthread_join(thread[i].thread, NULL);
++        char device_path[PATH_MAX];
++        snprintf(device_path, sizeof(device_path), "%s/%s", path, de[i]->d_name);
++        add_device(udev_enumerate, device_path);
+     }
+-    free(thread);
+-    pthread_mutex_destroy(&mutex);
+-
+-free_de:
+     for (i = 0; i < cnt; i++) {
+         free(de[i]);
+     }
+     free(de);
+-    return ret;
++    return 1;
+ }
+ int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate)
diff --git a/libs/libudev-zero/patches/0003-Fixes-incorrect-detection-of-touchpads-66.patch b/libs/libudev-zero/patches/0003-Fixes-incorrect-detection-of-touchpads-66.patch
new file mode 100644 (file)
index 0000000..1884192
--- /dev/null
@@ -0,0 +1,41 @@
+From bbeb7ad51c1edb7ab3cf63f30a21e9bb383b7994 Mon Sep 17 00:00:00 2001
+From: Matt <[email protected]>
+Date: Tue, 13 Feb 2024 11:20:52 +0000
+Subject: [PATCH] Fixes incorrect detection of touchpads (#66)
+
+Some touchpad drivers (such as applespi) claim to have both EV_ABS and EV_REL
+capabilities. These touchpads are then reported as mice by libudev-zero.
+---
+ udev_device.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/udev_device.c
++++ b/udev_device.c
+@@ -458,13 +458,7 @@ static void set_properties_from_evdev(st
+         udev_list_entry_add(&udev_device->properties, "ID_INPUT_SWITCH", "1", 0);
+     }
+-    if (test_bit(ev_bits, EV_REL)) {
+-        if (test_bit(rel_bits, REL_Y) && test_bit(rel_bits, REL_X) &&
+-            test_bit(key_bits, BTN_MOUSE)) {
+-            udev_list_entry_add(&udev_device->properties, "ID_INPUT_MOUSE", "1", 0);
+-        }
+-    }
+-    else if (test_bit(ev_bits, EV_ABS)) {
++    if (test_bit(ev_bits, EV_ABS)) {
+         if (test_bit(key_bits, BTN_SELECT) || test_bit(key_bits, BTN_TR) ||
+             test_bit(key_bits, BTN_START) || test_bit(key_bits, BTN_TL)) {
+             if (test_bit(key_bits, BTN_TOUCH)) {
+@@ -494,6 +488,12 @@ static void set_properties_from_evdev(st
+             }
+         }
+     }
++    else if (test_bit(ev_bits, EV_REL)) {
++        if (test_bit(rel_bits, REL_Y) && test_bit(rel_bits, REL_X) &&
++            test_bit(key_bits, BTN_MOUSE)) {
++            udev_list_entry_add(&udev_device->properties, "ID_INPUT_MOUSE", "1", 0);
++        }
++    }
+     if (!test_bit(ev_bits, EV_KEY)) {
+         return;