Skip to content

Commit 2a456e9

Browse files
wuguanghao3mwilck
authored andcommitted
udev: prevent interruption by thread cancellation
Using mutexes only guarantees no concurrency during normal runtime. However, if a thread is cancelled mid-execution, a libudev API call might be interrupted halfway (partially executed), leaving memory values in an inconsistent or abnormal state. Furthermore, this change aligns with the requirement that libudev interfaces are not thread-safe and must not be called from multiple threads. Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
1 parent 9aa02a9 commit 2a456e9

1 file changed

Lines changed: 67 additions & 57 deletions

File tree

libmpathutil/mt-udev-wrap.h

Lines changed: 67 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,89 +2,99 @@
22
#define MT_LIBUDEV_WRAP_HPP
33
#include "mt-libudev.h"
44

5-
#define udev_ref(udev) mt_udev_ref(udev)
6-
#define udev_unref(udev) mt_udev_unref(udev)
7-
#define udev_new() mt_udev_new()
5+
#define MT_NO_CANCEL(call) \
6+
({ \
7+
int __oldstate; \
8+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &__oldstate); \
9+
__typeof__(call) __ret = (call); \
10+
pthread_setcancelstate(__oldstate, NULL); \
11+
pthread_testcancel(); \
12+
__ret; \
13+
})
814

9-
#define udev_list_entry_get_next(list_entry) mt_udev_list_entry_get_next(list_entry)
10-
#define udev_list_entry_get_by_name(list_entry, name) mt_udev_list_entry_get_by_name(list_entry, name)
11-
#define udev_list_entry_get_name(list_entry) mt_udev_list_entry_get_name(list_entry)
12-
#define udev_list_entry_get_value(list_entry) mt_udev_list_entry_get_value(list_entry)
15+
#define udev_ref(udev) MT_NO_CANCEL(mt_udev_ref(udev))
16+
#define udev_unref(udev) MT_NO_CANCEL(mt_udev_unref(udev))
17+
#define udev_new() MT_NO_CANCEL(mt_udev_new())
18+
19+
#define udev_list_entry_get_next(list_entry) MT_NO_CANCEL(mt_udev_list_entry_get_next(list_entry))
20+
#define udev_list_entry_get_by_name(list_entry, name) MT_NO_CANCEL(mt_udev_list_entry_get_by_name(list_entry, name))
21+
#define udev_list_entry_get_name(list_entry) MT_NO_CANCEL(mt_udev_list_entry_get_name(list_entry))
22+
#define udev_list_entry_get_value(list_entry) MT_NO_CANCEL(mt_udev_list_entry_get_value(list_entry))
1323

1424
#define udev_list_entry_foreach(list_entry, first_entry) \
1525
for (list_entry = first_entry; \
1626
list_entry; \
1727
list_entry = udev_list_entry_get_next(list_entry))
1828

19-
#define udev_device_new_from_syspath(udev, syspath) mt_udev_device_new_from_syspath(udev, syspath)
20-
#define udev_device_new_from_devnum(udev, type, devnum) mt_udev_device_new_from_devnum(udev, type, devnum)
29+
#define udev_device_new_from_syspath(udev, syspath) MT_NO_CANCEL(mt_udev_device_new_from_syspath(udev, syspath))
30+
#define udev_device_new_from_devnum(udev, type, devnum) MT_NO_CANCEL(mt_udev_device_new_from_devnum(udev, type, devnum))
2131
#define udev_device_new_from_subsystem_sysname(udev, subsystem, sysname) \
22-
mt_udev_device_new_from_subsystem_sysname(udev, subsystem, sysname)
23-
#define udev_device_new_from_device_id(udev, id) mt_udev_device_new_from_device_id(udev, id)
24-
#define udev_device_new_from_environment(udev) mt_udev_device_new_from_environment(udev)
32+
MT_NO_CANCEL(mt_udev_device_new_from_subsystem_sysname(udev, subsystem, sysname))
33+
#define udev_device_new_from_device_id(udev, id) MT_NO_CANCEL(mt_udev_device_new_from_device_id(udev, id))
34+
#define udev_device_new_from_environment(udev) MT_NO_CANCEL(mt_udev_device_new_from_environment(udev))
2535

26-
#define udev_device_ref(udev_device) mt_udev_device_ref(udev_device)
27-
#define udev_device_unref(udev_device) mt_udev_device_unref(udev_device)
28-
#define udev_device_get_udev(udev_device) mt_udev_device_get_udev(udev_device)
29-
#define udev_device_get_parent(udev_device) mt_udev_device_get_parent(udev_device)
36+
#define udev_device_ref(udev_device) MT_NO_CANCEL(mt_udev_device_ref(udev_device))
37+
#define udev_device_unref(udev_device) MT_NO_CANCEL(mt_udev_device_unref(udev_device))
38+
#define udev_device_get_udev(udev_device) MT_NO_CANCEL(mt_udev_device_get_udev(udev_device))
39+
#define udev_device_get_parent(udev_device) MT_NO_CANCEL(mt_udev_device_get_parent(udev_device))
3040
#define udev_device_get_parent_with_subsystem_devtype(udev_device, subsystem, devtype) \
31-
mt_udev_device_get_parent_with_subsystem_devtype(udev_device, subsystem, devtype)
32-
#define udev_device_get_devpath(udev_device) mt_udev_device_get_devpath(udev_device)
33-
#define udev_device_get_subsystem(udev_device) mt_udev_device_get_subsystem(udev_device)
34-
#define udev_device_get_devtype(udev_device) mt_udev_device_get_devtype(udev_device)
35-
#define udev_device_get_syspath(udev_device) mt_udev_device_get_syspath(udev_device)
36-
#define udev_device_get_sysname(udev_device) mt_udev_device_get_sysname(udev_device)
37-
#define udev_device_get_is_initialized(udev_device) mt_udev_device_get_is_initialized(udev_device)
38-
#define udev_device_get_property_value(udev_device, key) mt_udev_device_get_property_value(udev_device, key)
39-
#define udev_device_get_devnum(udev_device) mt_udev_device_get_devnum(udev_device)
40-
#define udev_device_get_seqnum(udev_device) mt_udev_device_get_seqnum(udev_device)
41-
#define udev_device_get_driver(udev_device) mt_udev_device_get_driver(udev_device)
42-
#define udev_device_get_devnode(udev_device) mt_udev_device_get_devnode(udev_device)
41+
MT_NO_CANCEL(mt_udev_device_get_parent_with_subsystem_devtype(udev_device, subsystem, devtype))
42+
#define udev_device_get_devpath(udev_device) MT_NO_CANCEL(mt_udev_device_get_devpath(udev_device))
43+
#define udev_device_get_subsystem(udev_device) MT_NO_CANCEL(mt_udev_device_get_subsystem(udev_device))
44+
#define udev_device_get_devtype(udev_device) MT_NO_CANCEL(mt_udev_device_get_devtype(udev_device))
45+
#define udev_device_get_syspath(udev_device) MT_NO_CANCEL(mt_udev_device_get_syspath(udev_device))
46+
#define udev_device_get_sysname(udev_device) MT_NO_CANCEL(mt_udev_device_get_sysname(udev_device))
47+
#define udev_device_get_is_initialized(udev_device) MT_NO_CANCEL(mt_udev_device_get_is_initialized(udev_device))
48+
#define udev_device_get_property_value(udev_device, key) MT_NO_CANCEL(mt_udev_device_get_property_value(udev_device, key))
49+
#define udev_device_get_devnum(udev_device) MT_NO_CANCEL(mt_udev_device_get_devnum(udev_device))
50+
#define udev_device_get_seqnum(udev_device) MT_NO_CANCEL(mt_udev_device_get_seqnum(udev_device))
51+
#define udev_device_get_driver(udev_device) MT_NO_CANCEL(mt_udev_device_get_driver(udev_device))
52+
#define udev_device_get_devnode(udev_device) MT_NO_CANCEL(mt_udev_device_get_devnode(udev_device))
4353
#define udev_device_get_sysattr_value(udev_device, sysattr) \
44-
mt_udev_device_get_sysattr_value(udev_device, sysattr)
54+
MT_NO_CANCEL(mt_udev_device_get_sysattr_value(udev_device, sysattr))
4555
#define udev_device_set_sysattr_value(udev_device, sysattr, value) \
46-
mt_udev_device_set_sysattr_value(udev_device, sysattr, value)
56+
MT_NO_CANCEL(mt_udev_device_set_sysattr_value(udev_device, sysattr, value))
4757

48-
#define udev_device_get_devlinks_list_entry(udev_device) mt_udev_device_get_devlinks_list_entry(udev_device)
49-
#define udev_device_get_properties_list_entry(udev_device) mt_udev_device_get_properties_list_entry(udev_device)
50-
#define udev_device_get_tags_list_entry(udev_device) mt_udev_device_get_tags_list_entry(udev_device)
51-
#define udev_device_get_current_tags_list_entry(udev_device) mt_udev_device_get_current_tags_list_entry(udev_device)
52-
#define udev_device_get_sysattr_list_entry(udev_device) mt_udev_device_get_sysattr_list_entry(udev_device)
58+
#define udev_device_get_devlinks_list_entry(udev_device) MT_NO_CANCEL(mt_udev_device_get_devlinks_list_entry(udev_device))
59+
#define udev_device_get_properties_list_entry(udev_device) MT_NO_CANCEL(mt_udev_device_get_properties_list_entry(udev_device))
60+
#define udev_device_get_tags_list_entry(udev_device) MT_NO_CANCEL(mt_udev_device_get_tags_list_entry(udev_device))
61+
#define udev_device_get_current_tags_list_entry(udev_device) MT_NO_CANCEL(mt_udev_device_get_current_tags_list_entry(udev_device))
62+
#define udev_device_get_sysattr_list_entry(udev_device) MT_NO_CANCEL(mt_udev_device_get_sysattr_list_entry(udev_device))
5363

54-
#define udev_monitor_new_from_netlink(udev, name) mt_udev_monitor_new_from_netlink(udev, name)
55-
#define udev_monitor_ref(udev_monitor) mt_udev_monitor_ref(udev_monitor)
56-
#define udev_monitor_unref(udev_monitor) mt_udev_monitor_unref(udev_monitor)
57-
#define udev_monitor_enable_receiving(udev_monitor) mt_udev_monitor_enable_receiving(udev_monitor)
58-
#define udev_monitor_get_fd(udev_monitor) mt_udev_monitor_get_fd(udev_monitor)
59-
#define udev_monitor_receive_device(udev_monitor) mt_udev_monitor_receive_device(udev_monitor)
64+
#define udev_monitor_new_from_netlink(udev, name) MT_NO_CANCEL(mt_udev_monitor_new_from_netlink(udev, name))
65+
#define udev_monitor_ref(udev_monitor) MT_NO_CANCEL(mt_udev_monitor_ref(udev_monitor))
66+
#define udev_monitor_unref(udev_monitor) MT_NO_CANCEL(mt_udev_monitor_unref(udev_monitor))
67+
#define udev_monitor_enable_receiving(udev_monitor) MT_NO_CANCEL(mt_udev_monitor_enable_receiving(udev_monitor))
68+
#define udev_monitor_get_fd(udev_monitor) MT_NO_CANCEL(mt_udev_monitor_get_fd(udev_monitor))
69+
#define udev_monitor_receive_device(udev_monitor) MT_NO_CANCEL(mt_udev_monitor_receive_device(udev_monitor))
6070
#define udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, subsystem, devtype) \
61-
mt_udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, subsystem, devtype)
71+
MT_NO_CANCEL(mt_udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, subsystem, devtype))
6272
#define udev_monitor_set_receive_buffer_size(udev_monitor, size) \
63-
mt_udev_monitor_set_receive_buffer_size(udev_monitor, size)
73+
MT_NO_CANCEL(mt_udev_monitor_set_receive_buffer_size(udev_monitor, size))
6474

65-
#define udev_enumerate_new(udev) mt_udev_enumerate_new(udev)
66-
#define udev_enumerate_unref(udev_enumerate) mt_udev_enumerate_unref(udev_enumerate)
75+
#define udev_enumerate_new(udev) MT_NO_CANCEL(mt_udev_enumerate_new(udev))
76+
#define udev_enumerate_unref(udev_enumerate) MT_NO_CANCEL(mt_udev_enumerate_unref(udev_enumerate))
6777
#define udev_enumerate_add_match_subsystem(udev_enumerate, subsystem) \
68-
mt_udev_enumerate_add_match_subsystem(udev_enumerate, subsystem)
78+
MT_NO_CANCEL(mt_udev_enumerate_add_match_subsystem(udev_enumerate, subsystem))
6979
#define udev_enumerate_add_nomatch_subsystem(udev_enumerate, subsystem) \
70-
mt_udev_enumerate_add_nomatch_subsystem(udev_enumerate, subsystem)
80+
MT_NO_CANCEL(mt_udev_enumerate_add_nomatch_subsystem(udev_enumerate, subsystem))
7181
#define udev_enumerate_add_match_sysattr(udev_enumerate, sysattr, value) \
72-
mt_udev_enumerate_add_match_sysattr(udev_enumerate, sysattr, value)
82+
MT_NO_CANCEL(mt_udev_enumerate_add_match_sysattr(udev_enumerate, sysattr, value))
7383
#define udev_enumerate_add_nomatch_sysattr(udev_enumerate, sysattr, value) \
74-
mt_udev_enumerate_add_nomatch_sysattr(udev_enumerate, sysattr, value)
84+
MT_NO_CANCEL(mt_udev_enumerate_add_nomatch_sysattr(udev_enumerate, sysattr, value))
7585
#define udev_enumerate_add_match_property(udev_enumerate, property, value) \
76-
mt_udev_enumerate_add_match_property(udev_enumerate, property, value)
77-
#define udev_enumerate_add_match_tag(udev_enumerate, tag) mt_udev_enumerate_add_match_tag(udev_enumerate, tag)
86+
MT_NO_CANCEL(mt_udev_enumerate_add_match_property(udev_enumerate, property, value))
87+
#define udev_enumerate_add_match_tag(udev_enumerate, tag) MT_NO_CANCEL(mt_udev_enumerate_add_match_tag(udev_enumerate, tag))
7888
#define udev_enumerate_add_match_parent(udev_enumerate, parent) \
79-
mt_udev_enumerate_add_match_parent(udev_enumerate, parent)
89+
MT_NO_CANCEL(mt_udev_enumerate_add_match_parent(udev_enumerate, parent))
8090
#define udev_enumerate_add_match_is_initialized(udev_enumerate) \
81-
mt_udev_enumerate_add_match_is_initialized(udev_enumerate)
91+
MT_NO_CANCEL(mt_udev_enumerate_add_match_is_initialized(udev_enumerate))
8292
#define udev_enumerate_add_syspath(udev_enumerate, syspath) \
83-
mt_udev_enumerate_add_syspath(udev_enumerate, syspath)
93+
MT_NO_CANCEL(mt_udev_enumerate_add_syspath(udev_enumerate, syspath))
8494

85-
#define udev_enumerate_scan_devices(udev_enumerate) mt_udev_enumerate_scan_devices(udev_enumerate)
95+
#define udev_enumerate_scan_devices(udev_enumerate) MT_NO_CANCEL(mt_udev_enumerate_scan_devices(udev_enumerate))
8696
#define udev_enumerate_scan_device(udev_enumerate, syspath) \
87-
mt_udev_enumerate_scan_device(udev_enumerate, syspath)
88-
#define udev_enumerate_get_list_entry(udev_enumerate) mt_udev_enumerate_get_list_entry(udev_enumerate)
97+
MT_NO_CANCEL(mt_udev_enumerate_scan_device(udev_enumerate, syspath))
98+
#define udev_enumerate_get_list_entry(udev_enumerate) MT_NO_CANCEL(mt_udev_enumerate_get_list_entry(udev_enumerate))
8999

90100
#endif

0 commit comments

Comments
 (0)