Bug Summary

File:build-scan/../src/libsystemd/sd-device/device-private.c
Warning:line 566, column 13
3rd function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name device-private.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/libsystemd/libsystemd_static.a.p -I src/libsystemd -I ../src/libsystemd -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility default -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/libsystemd/sd-device/device-private.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <ctype.h>
4#include <net/if.h>
5#include <sys/types.h>
6
7#include "sd-device.h"
8
9#include "alloc-util.h"
10#include "device-internal.h"
11#include "device-private.h"
12#include "device-util.h"
13#include "fd-util.h"
14#include "fileio.h"
15#include "fs-util.h"
16#include "hashmap.h"
17#include "macro.h"
18#include "mkdir.h"
19#include "parse-util.h"
20#include "path-util.h"
21#include "refcnt.h"
22#include "set.h"
23#include "string-table.h"
24#include "string-util.h"
25#include "strv.h"
26#include "strxcpyx.h"
27#include "user-util.h"
28#include "util.h"
29
30int device_add_property(sd_device *device, const char *key, const char *value) {
31 int r;
32
33 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 33, __PRETTY_FUNCTION__); } while (0)
;
34 assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("key"), "../src/libsystemd/sd-device/device-private.c"
, 34, __PRETTY_FUNCTION__); } while (0)
;
35
36 r = device_add_property_aux(device, key, value, false0);
37 if (r < 0)
38 return r;
39
40 if (key[0] != '.') {
41 r = device_add_property_aux(device, key, value, true1);
42 if (r < 0)
43 return r;
44 }
45
46 return 0;
47}
48
49static int device_add_property_internal_from_string(sd_device *device, const char *str) {
50 _cleanup_free___attribute__((cleanup(freep))) char *key = NULL((void*)0);
51 char *value;
52
53 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 53, __PRETTY_FUNCTION__); } while (0)
;
54 assert(str)do { if ((__builtin_expect(!!(!(str)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("str"), "../src/libsystemd/sd-device/device-private.c"
, 54, __PRETTY_FUNCTION__); } while (0)
;
55
56 key = strdup(str);
57 if (!key)
58 return -ENOMEM12;
59
60 value = strchr(key, '=');
61 if (!value)
62 return -EINVAL22;
63
64 *value = '\0';
65
66 if (isempty(++value))
67 value = NULL((void*)0);
68
69 return device_add_property_internal(device, key, value);
70}
71
72static int handle_db_line(sd_device *device, char key, const char *value) {
73 char *path;
74 int r;
75
76 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 76, __PRETTY_FUNCTION__); } while (0)
;
77 assert(value)do { if ((__builtin_expect(!!(!(value)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("value"), "../src/libsystemd/sd-device/device-private.c"
, 77, __PRETTY_FUNCTION__); } while (0)
;
78
79 switch (key) {
80 case 'S':
81 path = strjoina("/dev/", value)({ const char *_appendees_[] = { "/dev/", value }; char *_d_,
*_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
82 r = device_add_devlink(device, path);
83 if (r < 0)
84 return r;
85
86 break;
87 case 'L':
88 r = safe_atoi(value, &device->devlink_priority);
89 if (r < 0)
90 return r;
91
92 break;
93 case 'E':
94 r = device_add_property_internal_from_string(device, value);
95 if (r < 0)
96 return r;
97
98 break;
99 case 'G':
100 r = device_add_tag(device, value);
101 if (r < 0)
102 return r;
103
104 break;
105 case 'W':
106 r = safe_atoi(value, &device->watch_handle);
107 if (r < 0)
108 return r;
109
110 break;
111 case 'I':
112 r = device_set_usec_initialized(device, value);
113 if (r < 0)
114 return r;
115
116 break;
117 default:
118 log_debug("device db: unknown key '%c'", key)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 118, __func__
, "device db: unknown key '%c'", key) : -abs(_e); })
;
119 }
120
121 return 0;
122}
123
124void device_set_devlink_priority(sd_device *device, int priority) {
125 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 125, __PRETTY_FUNCTION__); } while (0)
;
126
127 device->devlink_priority = priority;
128}
129
130void device_set_is_initialized(sd_device *device) {
131 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 131, __PRETTY_FUNCTION__); } while (0)
;
132
133 device->is_initialized = true1;
134}
135
136int device_ensure_usec_initialized(sd_device *device, sd_device *device_old) {
137 char num[DECIMAL_STR_MAX(usec_t)(2+(sizeof(usec_t) <= 1 ? 3 : sizeof(usec_t) <= 2 ? 5 :
sizeof(usec_t) <= 4 ? 10 : sizeof(usec_t) <= 8 ? 20 : sizeof
(int[-2*(sizeof(usec_t) > 8)])))
];
138 usec_t usec_initialized;
139 int r;
140
141 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 141, __PRETTY_FUNCTION__); } while (0)
;
142
143 if (device_old && device_old->usec_initialized > 0)
144 usec_initialized = device_old->usec_initialized;
145 else
146 usec_initialized = now(CLOCK_MONOTONIC1);
147
148 r = snprintf(num, sizeof(num), USEC_FMT"%" "l" "u", usec_initialized);
149 if (r < 0)
150 return -errno(*__errno_location ());
151
152 r = device_set_usec_initialized(device, num);
153 if (r < 0)
154 return r;
155
156 return 0;
157}
158
159static int device_read_db(sd_device *device) {
160 _cleanup_free___attribute__((cleanup(freep))) char *db = NULL((void*)0);
161 char *path;
162 const char *id, *value;
163 char key;
164 size_t db_len;
165 unsigned i;
166 int r;
167
168 enum {
169 PRE_KEY,
170 KEY,
171 PRE_VALUE,
172 VALUE,
173 INVALID_LINE,
174 } state = PRE_KEY;
175
176 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 176, __PRETTY_FUNCTION__); } while (0)
;
177
178 if (device->db_loaded || device->sealed)
179 return 0;
180
181 r = device_get_id_filename(device, &id);
182 if (r < 0)
183 return r;
184
185 path = strjoina("/run/udev/data/", id)({ const char *_appendees_[] = { "/run/udev/data/", id }; char
*_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ <
__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
186
187 r = read_full_file(path, &db, &db_len);
188 if (r < 0) {
189 if (r == -ENOENT2)
190 return 0;
191 else
192 return log_debug_errno(r, "sd-device: failed to read db '%s': %m", path)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 192, __func__
, "sd-device: failed to read db '%s': %m", path) : -abs(_e); }
)
;
193 }
194
195 /* devices with a database entry are initialized */
196 device_set_is_initialized(device);
197
198 for (i = 0; i < db_len; i++) {
199 switch (state) {
200 case PRE_KEY:
201 if (!strchr(NEWLINE"\n\r", db[i])) {
202 key = db[i];
203
204 state = KEY;
205 }
206
207 break;
208 case KEY:
209 if (db[i] != ':') {
210 log_debug("sd-device: ignoring invalid db entry with key '%c'", key)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 210, __func__
, "sd-device: ignoring invalid db entry with key '%c'", key) :
-abs(_e); })
;
211
212 state = INVALID_LINE;
213 } else {
214 db[i] = '\0';
215
216 state = PRE_VALUE;
217 }
218
219 break;
220 case PRE_VALUE:
221 value = &db[i];
222
223 state = VALUE;
224
225 break;
226 case INVALID_LINE:
227 if (strchr(NEWLINE"\n\r", db[i]))
228 state = PRE_KEY;
229
230 break;
231 case VALUE:
232 if (strchr(NEWLINE"\n\r", db[i])) {
233 db[i] = '\0';
234 r = handle_db_line(device, key, value);
235 if (r < 0)
236 log_debug_errno(r, "sd-device: failed to handle db entry '%c:%s': %m", key, value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 236, __func__
, "sd-device: failed to handle db entry '%c:%s': %m", key, value
) : -abs(_e); })
;
237
238 state = PRE_KEY;
239 }
240
241 break;
242 default:
243 assert_not_reached("invalid state when parsing db")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"invalid state when parsing db"), "../src/libsystemd/sd-device/device-private.c"
, 243, __PRETTY_FUNCTION__); } while (0)
;
244 }
245 }
246
247 device->db_loaded = true1;
248
249 return 0;
250}
251
252uint64_t device_get_properties_generation(sd_device *device) {
253 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 253, __PRETTY_FUNCTION__); } while (0)
;
254
255 return device->properties_generation;
256}
257
258uint64_t device_get_tags_generation(sd_device *device) {
259 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 259, __PRETTY_FUNCTION__); } while (0)
;
260
261 return device->tags_generation;
262}
263
264uint64_t device_get_devlinks_generation(sd_device *device) {
265 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 265, __PRETTY_FUNCTION__); } while (0)
;
266
267 return device->devlinks_generation;
268}
269
270int device_get_devnode_mode(sd_device *device, mode_t *mode) {
271 int r;
272
273 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 273, __PRETTY_FUNCTION__); } while (0)
;
274 assert(mode)do { if ((__builtin_expect(!!(!(mode)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("mode"), "../src/libsystemd/sd-device/device-private.c"
, 274, __PRETTY_FUNCTION__); } while (0)
;
275
276 r = device_read_db(device);
277 if (r < 0)
278 return r;
279
280 *mode = device->devmode;
281
282 return 0;
283}
284
285int device_get_devnode_uid(sd_device *device, uid_t *uid) {
286 int r;
287
288 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 288, __PRETTY_FUNCTION__); } while (0)
;
289 assert(uid)do { if ((__builtin_expect(!!(!(uid)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("uid"), "../src/libsystemd/sd-device/device-private.c"
, 289, __PRETTY_FUNCTION__); } while (0)
;
290
291 r = device_read_db(device);
292 if (r < 0)
293 return r;
294
295 *uid = device->devuid;
296
297 return 0;
298}
299
300static int device_set_devuid(sd_device *device, const char *uid) {
301 unsigned u;
302 int r;
303
304 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 304, __PRETTY_FUNCTION__); } while (0)
;
305 assert(uid)do { if ((__builtin_expect(!!(!(uid)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("uid"), "../src/libsystemd/sd-device/device-private.c"
, 305, __PRETTY_FUNCTION__); } while (0)
;
306
307 r = safe_atou(uid, &u);
308 if (r < 0)
309 return r;
310
311 r = device_add_property_internal(device, "DEVUID", uid);
312 if (r < 0)
313 return r;
314
315 device->devuid = u;
316
317 return 0;
318}
319
320int device_get_devnode_gid(sd_device *device, gid_t *gid) {
321 int r;
322
323 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 323, __PRETTY_FUNCTION__); } while (0)
;
324 assert(gid)do { if ((__builtin_expect(!!(!(gid)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("gid"), "../src/libsystemd/sd-device/device-private.c"
, 324, __PRETTY_FUNCTION__); } while (0)
;
325
326 r = device_read_db(device);
327 if (r < 0)
328 return r;
329
330 *gid = device->devgid;
331
332 return 0;
333}
334
335static int device_set_devgid(sd_device *device, const char *gid) {
336 unsigned g;
337 int r;
338
339 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 339, __PRETTY_FUNCTION__); } while (0)
;
340 assert(gid)do { if ((__builtin_expect(!!(!(gid)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("gid"), "../src/libsystemd/sd-device/device-private.c"
, 340, __PRETTY_FUNCTION__); } while (0)
;
341
342 r = safe_atou(gid, &g);
343 if (r < 0)
344 return r;
345
346 r = device_add_property_internal(device, "DEVGID", gid);
347 if (r < 0)
348 return r;
349
350 device->devgid = g;
351
352 return 0;
353}
354
355static int device_amend(sd_device *device, const char *key, const char *value) {
356 int r;
357
358 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 358, __PRETTY_FUNCTION__); } while (0)
;
359 assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("key"), "../src/libsystemd/sd-device/device-private.c"
, 359, __PRETTY_FUNCTION__); } while (0)
;
360 assert(value)do { if ((__builtin_expect(!!(!(value)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("value"), "../src/libsystemd/sd-device/device-private.c"
, 360, __PRETTY_FUNCTION__); } while (0)
;
361
362 if (streq(key, "DEVPATH")(strcmp((key),("DEVPATH")) == 0)) {
363 char *path;
364
365 path = strjoina("/sys", value)({ const char *_appendees_[] = { "/sys", value }; char *_d_, *
_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
366
367 /* the caller must verify or trust this data (e.g., if it comes from the kernel) */
368 r = device_set_syspath(device, path, false0);
369 if (r < 0)
370 return log_debug_errno(r, "sd-device: could not set syspath to '%s': %m", path)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 370, __func__
, "sd-device: could not set syspath to '%s': %m", path) : -abs
(_e); })
;
371 } else if (streq(key, "SUBSYSTEM")(strcmp((key),("SUBSYSTEM")) == 0)) {
372 r = device_set_subsystem(device, value);
373 if (r < 0)
374 return log_debug_errno(r, "sd-device: could not set subsystem to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 374, __func__
, "sd-device: could not set subsystem to '%s': %m", value) : -
abs(_e); })
;
375 } else if (streq(key, "DEVTYPE")(strcmp((key),("DEVTYPE")) == 0)) {
376 r = device_set_devtype(device, value);
377 if (r < 0)
378 return log_debug_errno(r, "sd-device: could not set devtype to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 378, __func__
, "sd-device: could not set devtype to '%s': %m", value) : -abs
(_e); })
;
379 } else if (streq(key, "DEVNAME")(strcmp((key),("DEVNAME")) == 0)) {
380 r = device_set_devname(device, value);
381 if (r < 0)
382 return log_debug_errno(r, "sd-device: could not set devname to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 382, __func__
, "sd-device: could not set devname to '%s': %m", value) : -abs
(_e); })
;
383 } else if (streq(key, "USEC_INITIALIZED")(strcmp((key),("USEC_INITIALIZED")) == 0)) {
384 r = device_set_usec_initialized(device, value);
385 if (r < 0)
386 return log_debug_errno(r, "sd-device: could not set usec-initialized to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 386, __func__
, "sd-device: could not set usec-initialized to '%s': %m", value
) : -abs(_e); })
;
387 } else if (streq(key, "DRIVER")(strcmp((key),("DRIVER")) == 0)) {
388 r = device_set_driver(device, value);
389 if (r < 0)
390 return log_debug_errno(r, "sd-device: could not set driver to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 390, __func__
, "sd-device: could not set driver to '%s': %m", value) : -abs
(_e); })
;
391 } else if (streq(key, "IFINDEX")(strcmp((key),("IFINDEX")) == 0)) {
392 r = device_set_ifindex(device, value);
393 if (r < 0)
394 return log_debug_errno(r, "sd-device: could not set ifindex to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 394, __func__
, "sd-device: could not set ifindex to '%s': %m", value) : -abs
(_e); })
;
395 } else if (streq(key, "DEVMODE")(strcmp((key),("DEVMODE")) == 0)) {
396 r = device_set_devmode(device, value);
397 if (r < 0)
398 return log_debug_errno(r, "sd-device: could not set devmode to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 398, __func__
, "sd-device: could not set devmode to '%s': %m", value) : -abs
(_e); })
;
399 } else if (streq(key, "DEVUID")(strcmp((key),("DEVUID")) == 0)) {
400 r = device_set_devuid(device, value);
401 if (r < 0)
402 return log_debug_errno(r, "sd-device: could not set devuid to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 402, __func__
, "sd-device: could not set devuid to '%s': %m", value) : -abs
(_e); })
;
403 } else if (streq(key, "DEVGID")(strcmp((key),("DEVGID")) == 0)) {
404 r = device_set_devgid(device, value);
405 if (r < 0)
406 return log_debug_errno(r, "sd-device: could not set devgid to '%s': %m", value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 406, __func__
, "sd-device: could not set devgid to '%s': %m", value) : -abs
(_e); })
;
407 } else if (streq(key, "DEVLINKS")(strcmp((key),("DEVLINKS")) == 0)) {
408 const char *word, *state;
409 size_t l;
410
411 FOREACH_WORD(word, l, value, state)for ((state) = (value), (word) = split(&(state), &(l)
, (" \t\n\r"), (0)); (word); (word) = split(&(state), &
(l), (" \t\n\r"), (0)))
{
412 char devlink[l + 1];
413
414 strncpy(devlink, word, l);
415 devlink[l] = '\0';
416
417 r = device_add_devlink(device, devlink);
418 if (r < 0)
419 return log_debug_errno(r, "sd-device: could not add devlink '%s': %m", devlink)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 419, __func__
, "sd-device: could not add devlink '%s': %m", devlink) : -abs
(_e); })
;
420 }
421 } else if (streq(key, "TAGS")(strcmp((key),("TAGS")) == 0)) {
422 const char *word, *state;
423 size_t l;
424
425 FOREACH_WORD_SEPARATOR(word, l, value, ":", state)for ((state) = (value), (word) = split(&(state), &(l)
, (":"), (0)); (word); (word) = split(&(state), &(l),
(":"), (0)))
{
426 char tag[l + 1];
427
428 (void)strncpy(tag, word, l);
429 tag[l] = '\0';
430
431 r = device_add_tag(device, tag);
432 if (r < 0)
433 return log_debug_errno(r, "sd-device: could not add tag '%s': %m", tag)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 433, __func__
, "sd-device: could not add tag '%s': %m", tag) : -abs(_e); }
)
;
434 }
435 } else {
436 r = device_add_property_internal(device, key, value);
437 if (r < 0)
438 return log_debug_errno(r, "sd-device: could not add property '%s=%s': %m", key, value)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 438, __func__
, "sd-device: could not add property '%s=%s': %m", key, value
) : -abs(_e); })
;
439 }
440
441 return 0;
442}
443
444static const char* const device_action_table[_DEVICE_ACTION_MAX] = {
445 [DEVICE_ACTION_ADD] = "add",
446 [DEVICE_ACTION_REMOVE] = "remove",
447 [DEVICE_ACTION_CHANGE] = "change",
448 [DEVICE_ACTION_MOVE] = "move",
449 [DEVICE_ACTION_ONLINE] = "online",
450 [DEVICE_ACTION_OFFLINE] = "offline",
451 [DEVICE_ACTION_BIND] = "bind",
452 [DEVICE_ACTION_UNBIND] = "unbind",
453};
454
455DEFINE_STRING_TABLE_LOOKUP(device_action, DeviceAction)const char *device_action_to_string(DeviceAction i) { if (i <
0 || i >= (DeviceAction) __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(device_action_table), typeof
(&*(device_action_table))), sizeof(device_action_table)/sizeof
((device_action_table)[0]), ((void)0)))) return ((void*)0); return
device_action_table[i]; } DeviceAction device_action_from_string
(const char *s) { return (DeviceAction) string_table_lookup(device_action_table
, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(device_action_table), typeof(&*(device_action_table
))), sizeof(device_action_table)/sizeof((device_action_table)
[0]), ((void)0))), s); }
;
456
457static int device_append(sd_device *device, char *key, const char **_major, const char **_minor, uint64_t *_seqnum,
458 DeviceAction *_action) {
459 DeviceAction action = _DEVICE_ACTION_INVALID;
460 uint64_t seqnum = 0;
461 const char *major = NULL((void*)0), *minor = NULL((void*)0);
462 char *value;
463 int r;
464
465 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 465, __PRETTY_FUNCTION__); } while (0)
;
466 assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("key"), "../src/libsystemd/sd-device/device-private.c"
, 466, __PRETTY_FUNCTION__); } while (0)
;
467 assert(_major)do { if ((__builtin_expect(!!(!(_major)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_major"), "../src/libsystemd/sd-device/device-private.c"
, 467, __PRETTY_FUNCTION__); } while (0)
;
468 assert(_minor)do { if ((__builtin_expect(!!(!(_minor)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_minor"), "../src/libsystemd/sd-device/device-private.c"
, 468, __PRETTY_FUNCTION__); } while (0)
;
469 assert(_seqnum)do { if ((__builtin_expect(!!(!(_seqnum)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_seqnum"), "../src/libsystemd/sd-device/device-private.c"
, 469, __PRETTY_FUNCTION__); } while (0)
;
470 assert(_action)do { if ((__builtin_expect(!!(!(_action)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_action"), "../src/libsystemd/sd-device/device-private.c"
, 470, __PRETTY_FUNCTION__); } while (0)
;
471
472 value = strchr(key, '=');
473 if (!value) {
474 log_debug("sd-device: not a key-value pair: '%s'", key)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 474, __func__
, "sd-device: not a key-value pair: '%s'", key) : -abs(_e); }
)
;
475 return -EINVAL22;
476 }
477
478 *value = '\0';
479
480 value++;
481
482 if (streq(key, "MAJOR")(strcmp((key),("MAJOR")) == 0))
483 major = value;
484 else if (streq(key, "MINOR")(strcmp((key),("MINOR")) == 0))
485 minor = value;
486 else {
487 if (streq(key, "ACTION")(strcmp((key),("ACTION")) == 0)) {
488 action = device_action_from_string(value);
489 if (action == _DEVICE_ACTION_INVALID)
490 return -EINVAL22;
491 } else if (streq(key, "SEQNUM")(strcmp((key),("SEQNUM")) == 0)) {
492 r = safe_atou64(value, &seqnum);
493 if (r < 0)
494 return r;
495 else if (seqnum == 0)
496 /* kernel only sends seqnum > 0 */
497 return -EINVAL22;
498 }
499
500 r = device_amend(device, key, value);
501 if (r < 0)
502 return r;
503 }
504
505 if (major != 0)
506 *_major = major;
507
508 if (minor != 0)
509 *_minor = minor;
510
511 if (action != _DEVICE_ACTION_INVALID)
512 *_action = action;
513
514 if (seqnum > 0)
515 *_seqnum = seqnum;
516
517 return 0;
518}
519
520void device_seal(sd_device *device) {
521 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 521, __PRETTY_FUNCTION__); } while (0)
;
522
523 device->sealed = true1;
524}
525
526static int device_verify(sd_device *device, DeviceAction action, uint64_t seqnum) {
527 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 527, __PRETTY_FUNCTION__); } while (0)
;
528
529 if (!device->devpath || !device->subsystem || action == _DEVICE_ACTION_INVALID || seqnum == 0) {
530 log_debug("sd-device: device created from strv lacks devpath, subsystem, action or seqnum")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 530, __func__
, "sd-device: device created from strv lacks devpath, subsystem, action or seqnum"
) : -abs(_e); })
;
531 return -EINVAL22;
532 }
533
534 device->sealed = true1;
535
536 return 0;
537}
538
539int device_new_from_strv(sd_device **ret, char **strv) {
540 _cleanup_(sd_device_unrefp)__attribute__((cleanup(sd_device_unrefp))) sd_device *device = NULL((void*)0);
541 char **key;
542 const char *major = NULL((void*)0), *minor = NULL((void*)0);
543 DeviceAction action = _DEVICE_ACTION_INVALID;
544 uint64_t seqnum;
1
'seqnum' declared without an initial value
545 int r;
546
547 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd/sd-device/device-private.c"
, 547, __PRETTY_FUNCTION__); } while (0)
;
2
Assuming 'ret' is non-null
3
Taking false branch
4
Loop condition is false. Exiting loop
548 assert(strv)do { if ((__builtin_expect(!!(!(strv)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("strv"), "../src/libsystemd/sd-device/device-private.c"
, 548, __PRETTY_FUNCTION__); } while (0)
;
5
Assuming 'strv' is non-null
6
Taking false branch
7
Loop condition is false. Exiting loop
549
550 r = device_new_aux(&device);
551 if (r < 0)
8
Assuming 'r' is >= 0
9
Taking false branch
552 return r;
553
554 STRV_FOREACH(key, strv)for ((key) = (strv); (key) && *(key); (key)++) {
10
Loop condition is false. Execution continues on line 560
555 r = device_append(device, *key, &major, &minor, &seqnum, &action);
556 if (r < 0)
557 return r;
558 }
559
560 if (major
10.1
'major' is null
) {
11
Taking false branch
561 r = device_set_devnum(device, major, minor);
562 if (r < 0)
563 return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 563, __func__
, "sd-device: could not set devnum %s:%s: %m", major, minor) :
-abs(_e); })
;
564 }
565
566 r = device_verify(device, action, seqnum);
12
3rd function call argument is an uninitialized value
567 if (r < 0)
568 return r;
569
570 *ret = TAKE_PTR(device)({ typeof(device) _ptr_ = (device); (device) = ((void*)0); _ptr_
; })
;
571
572 return 0;
573}
574
575int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
576 _cleanup_(sd_device_unrefp)__attribute__((cleanup(sd_device_unrefp))) sd_device *device = NULL((void*)0);
577 const char *major = NULL((void*)0), *minor = NULL((void*)0);
578 DeviceAction action = _DEVICE_ACTION_INVALID;
579 uint64_t seqnum;
580 unsigned i = 0;
581 int r;
582
583 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd/sd-device/device-private.c"
, 583, __PRETTY_FUNCTION__); } while (0)
;
584 assert(nulstr)do { if ((__builtin_expect(!!(!(nulstr)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("nulstr"), "../src/libsystemd/sd-device/device-private.c"
, 584, __PRETTY_FUNCTION__); } while (0)
;
585 assert(len)do { if ((__builtin_expect(!!(!(len)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("len"), "../src/libsystemd/sd-device/device-private.c"
, 585, __PRETTY_FUNCTION__); } while (0)
;
586
587 r = device_new_aux(&device);
588 if (r < 0)
589 return r;
590
591 while (i < len) {
592 char *key;
593 const char *end;
594
595 key = (char*)&nulstr[i];
596 end = memchr(key, '\0', len - i);
597 if (!end) {
598 log_debug("sd-device: failed to parse nulstr")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 598, __func__
, "sd-device: failed to parse nulstr") : -abs(_e); })
;
599 return -EINVAL22;
600 }
601 i += end - key + 1;
602
603 r = device_append(device, key, &major, &minor, &seqnum, &action);
604 if (r < 0)
605 return r;
606 }
607
608 if (major) {
609 r = device_set_devnum(device, major, minor);
610 if (r < 0)
611 return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 611, __func__
, "sd-device: could not set devnum %s:%s: %m", major, minor) :
-abs(_e); })
;
612 }
613
614 r = device_verify(device, action, seqnum);
615 if (r < 0)
616 return r;
617
618 *ret = TAKE_PTR(device)({ typeof(device) _ptr_ = (device); (device) = ((void*)0); _ptr_
; })
;
619
620 return 0;
621}
622
623static int device_update_properties_bufs(sd_device *device) {
624 const char *val, *prop;
625 _cleanup_free___attribute__((cleanup(freep))) char **buf_strv = NULL((void*)0);
626 _cleanup_free___attribute__((cleanup(freep))) uint8_t *buf_nulstr = NULL((void*)0);
627 size_t allocated_nulstr = 0;
628 size_t nulstr_len = 0, num = 0, i = 0;
629
630 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 630, __PRETTY_FUNCTION__); } while (0)
;
631
632 if (!device->properties_buf_outdated)
633 return 0;
634
635 FOREACH_DEVICE_PROPERTY(device, prop, val)for (prop = sd_device_get_property_first(device, &(val));
prop; prop = sd_device_get_property_next(device, &(val))
)
{
636 size_t len = 0;
637
638 len = strlen(prop) + 1 + strlen(val);
639
640 buf_nulstr = GREEDY_REALLOC0(buf_nulstr, allocated_nulstr, nulstr_len + len + 2)greedy_realloc0((void**) &(buf_nulstr), &(allocated_nulstr
), (nulstr_len + len + 2), sizeof((buf_nulstr)[0]))
;
641 if (!buf_nulstr)
642 return -ENOMEM12;
643
644 strscpyl((char *)buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL((void*)0));
645 nulstr_len += len + 1;
646 ++num;
647 }
648
649 /* build buf_strv from buf_nulstr */
650 buf_strv = new0(char *, num + 1)((char **) calloc((num + 1), sizeof(char *)));
651 if (!buf_strv)
652 return -ENOMEM12;
653
654 NULSTR_FOREACH(val, (char*) buf_nulstr)for ((val) = ((char*) buf_nulstr); (val) && *(val); (
val) = strchr((val), 0)+1)
{
655 buf_strv[i] = (char *) val;
656 assert(i < num)do { if ((__builtin_expect(!!(!(i < num)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i < num"), "../src/libsystemd/sd-device/device-private.c"
, 656, __PRETTY_FUNCTION__); } while (0)
;
657 i++;
658 }
659
660 free_and_replace(device->properties_nulstr, buf_nulstr)({ free(device->properties_nulstr); (device->properties_nulstr
) = (buf_nulstr); (buf_nulstr) = ((void*)0); 0; })
;
661 device->properties_nulstr_len = nulstr_len;
662 free_and_replace(device->properties_strv, buf_strv)({ free(device->properties_strv); (device->properties_strv
) = (buf_strv); (buf_strv) = ((void*)0); 0; })
;
663
664 device->properties_buf_outdated = false0;
665
666 return 0;
667}
668
669int device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size_t *len) {
670 int r;
671
672 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 672, __PRETTY_FUNCTION__); } while (0)
;
673 assert(nulstr)do { if ((__builtin_expect(!!(!(nulstr)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("nulstr"), "../src/libsystemd/sd-device/device-private.c"
, 673, __PRETTY_FUNCTION__); } while (0)
;
674 assert(len)do { if ((__builtin_expect(!!(!(len)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("len"), "../src/libsystemd/sd-device/device-private.c"
, 674, __PRETTY_FUNCTION__); } while (0)
;
675
676 r = device_update_properties_bufs(device);
677 if (r < 0)
678 return r;
679
680 *nulstr = device->properties_nulstr;
681 *len = device->properties_nulstr_len;
682
683 return 0;
684}
685
686int device_get_properties_strv(sd_device *device, char ***strv) {
687 int r;
688
689 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 689, __PRETTY_FUNCTION__); } while (0)
;
690 assert(strv)do { if ((__builtin_expect(!!(!(strv)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("strv"), "../src/libsystemd/sd-device/device-private.c"
, 690, __PRETTY_FUNCTION__); } while (0)
;
691
692 r = device_update_properties_bufs(device);
693 if (r < 0)
694 return r;
695
696 *strv = device->properties_strv;
697
698 return 0;
699}
700
701int device_get_devlink_priority(sd_device *device, int *priority) {
702 int r;
703
704 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 704, __PRETTY_FUNCTION__); } while (0)
;
705 assert(priority)do { if ((__builtin_expect(!!(!(priority)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("priority"), "../src/libsystemd/sd-device/device-private.c"
, 705, __PRETTY_FUNCTION__); } while (0)
;
706
707 r = device_read_db(device);
708 if (r < 0)
709 return r;
710
711 *priority = device->devlink_priority;
712
713 return 0;
714}
715
716int device_get_watch_handle(sd_device *device, int *handle) {
717 int r;
718
719 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 719, __PRETTY_FUNCTION__); } while (0)
;
720 assert(handle)do { if ((__builtin_expect(!!(!(handle)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("handle"), "../src/libsystemd/sd-device/device-private.c"
, 720, __PRETTY_FUNCTION__); } while (0)
;
721
722 r = device_read_db(device);
723 if (r < 0)
724 return r;
725
726 *handle = device->watch_handle;
727
728 return 0;
729}
730
731void device_set_watch_handle(sd_device *device, int handle) {
732 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 732, __PRETTY_FUNCTION__); } while (0)
;
733
734 device->watch_handle = handle;
735}
736
737int device_rename(sd_device *device, const char *name) {
738 _cleanup_free___attribute__((cleanup(freep))) char *dirname = NULL((void*)0);
739 char *new_syspath;
740 const char *interface;
741 int r;
742
743 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 743, __PRETTY_FUNCTION__); } while (0)
;
744 assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("name"), "../src/libsystemd/sd-device/device-private.c"
, 744, __PRETTY_FUNCTION__); } while (0)
;
745
746 dirname = dirname_malloc(device->syspath);
747 if (!dirname)
748 return -ENOMEM12;
749
750 new_syspath = strjoina(dirname, "/", name)({ const char *_appendees_[] = { dirname, "/", name }; char *
_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ <
__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
751
752 /* the user must trust that the new name is correct */
753 r = device_set_syspath(device, new_syspath, false0);
754 if (r < 0)
755 return r;
756
757 r = sd_device_get_property_value(device, "INTERFACE", &interface);
758 if (r >= 0) {
759 /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
760 r = device_add_property_internal(device, "INTERFACE_OLD", interface);
761 if (r < 0)
762 return r;
763
764 r = device_add_property_internal(device, "INTERFACE", name);
765 if (r < 0)
766 return r;
767 } else if (r != -ENOENT2)
768 return r;
769
770 return 0;
771}
772
773int device_shallow_clone(sd_device *old_device, sd_device **new_device) {
774 _cleanup_(sd_device_unrefp)__attribute__((cleanup(sd_device_unrefp))) sd_device *ret = NULL((void*)0);
775 int r;
776
777 assert(old_device)do { if ((__builtin_expect(!!(!(old_device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("old_device"), "../src/libsystemd/sd-device/device-private.c"
, 777, __PRETTY_FUNCTION__); } while (0)
;
778 assert(new_device)do { if ((__builtin_expect(!!(!(new_device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("new_device"), "../src/libsystemd/sd-device/device-private.c"
, 778, __PRETTY_FUNCTION__); } while (0)
;
779
780 r = device_new_aux(&ret);
781 if (r < 0)
782 return r;
783
784 r = device_set_syspath(ret, old_device->syspath, false0);
785 if (r < 0)
786 return r;
787
788 r = device_set_subsystem(ret, old_device->subsystem);
789 if (r < 0)
790 return r;
791
792 ret->devnum = old_device->devnum;
793
794 *new_device = TAKE_PTR(ret)({ typeof(ret) _ptr_ = (ret); (ret) = ((void*)0); _ptr_; });
795
796 return 0;
797}
798
799int device_clone_with_db(sd_device *old_device, sd_device **new_device) {
800 _cleanup_(sd_device_unrefp)__attribute__((cleanup(sd_device_unrefp))) sd_device *ret = NULL((void*)0);
801 int r;
802
803 assert(old_device)do { if ((__builtin_expect(!!(!(old_device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("old_device"), "../src/libsystemd/sd-device/device-private.c"
, 803, __PRETTY_FUNCTION__); } while (0)
;
804 assert(new_device)do { if ((__builtin_expect(!!(!(new_device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("new_device"), "../src/libsystemd/sd-device/device-private.c"
, 804, __PRETTY_FUNCTION__); } while (0)
;
805
806 r = device_shallow_clone(old_device, &ret);
807 if (r < 0)
808 return r;
809
810 r = device_read_db(ret);
811 if (r < 0)
812 return r;
813
814 ret->sealed = true1;
815
816 *new_device = TAKE_PTR(ret)({ typeof(ret) _ptr_ = (ret); (ret) = ((void*)0); _ptr_; });
817
818 return 0;
819}
820
821int device_new_from_synthetic_event(sd_device **new_device, const char *syspath, const char *action) {
822 _cleanup_(sd_device_unrefp)__attribute__((cleanup(sd_device_unrefp))) sd_device *ret = NULL((void*)0);
823 int r;
824
825 assert(new_device)do { if ((__builtin_expect(!!(!(new_device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("new_device"), "../src/libsystemd/sd-device/device-private.c"
, 825, __PRETTY_FUNCTION__); } while (0)
;
826 assert(syspath)do { if ((__builtin_expect(!!(!(syspath)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("syspath"), "../src/libsystemd/sd-device/device-private.c"
, 826, __PRETTY_FUNCTION__); } while (0)
;
827 assert(action)do { if ((__builtin_expect(!!(!(action)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("action"), "../src/libsystemd/sd-device/device-private.c"
, 827, __PRETTY_FUNCTION__); } while (0)
;
828
829 r = sd_device_new_from_syspath(&ret, syspath);
830 if (r < 0)
831 return r;
832
833 r = device_read_uevent_file(ret);
834 if (r < 0)
835 return r;
836
837 r = device_add_property_internal(ret, "ACTION", action);
838 if (r < 0)
839 return r;
840
841 *new_device = TAKE_PTR(ret)({ typeof(ret) _ptr_ = (ret); (ret) = ((void*)0); _ptr_; });
842
843 return 0;
844}
845
846int device_copy_properties(sd_device *device_dst, sd_device *device_src) {
847 const char *property, *value;
848 int r;
849
850 assert(device_dst)do { if ((__builtin_expect(!!(!(device_dst)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device_dst"), "../src/libsystemd/sd-device/device-private.c"
, 850, __PRETTY_FUNCTION__); } while (0)
;
851 assert(device_src)do { if ((__builtin_expect(!!(!(device_src)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device_src"), "../src/libsystemd/sd-device/device-private.c"
, 851, __PRETTY_FUNCTION__); } while (0)
;
852
853 FOREACH_DEVICE_PROPERTY(device_src, property, value)for (property = sd_device_get_property_first(device_src, &
(value)); property; property = sd_device_get_property_next(device_src
, &(value)))
{
854 r = device_add_property(device_dst, property, value);
855 if (r < 0)
856 return r;
857 }
858
859 return 0;
860}
861
862void device_cleanup_tags(sd_device *device) {
863 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 863, __PRETTY_FUNCTION__); } while (0)
;
864
865 set_free_free(device->tags);
866 device->tags = NULL((void*)0);
867 device->property_tags_outdated = true1;
868 device->tags_generation++;
869}
870
871void device_cleanup_devlinks(sd_device *device) {
872 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 872, __PRETTY_FUNCTION__); } while (0)
;
873
874 set_free_free(device->devlinks);
875 device->devlinks = NULL((void*)0);
876 device->property_devlinks_outdated = true1;
877 device->devlinks_generation++;
878}
879
880void device_remove_tag(sd_device *device, const char *tag) {
881 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 881, __PRETTY_FUNCTION__); } while (0)
;
882 assert(tag)do { if ((__builtin_expect(!!(!(tag)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("tag"), "../src/libsystemd/sd-device/device-private.c"
, 882, __PRETTY_FUNCTION__); } while (0)
;
883
884 free(set_remove(device->tags, tag));
885 device->property_tags_outdated = true1;
886 device->tags_generation++;
887}
888
889static int device_tag(sd_device *device, const char *tag, bool_Bool add) {
890 const char *id;
891 char *path;
892 int r;
893
894 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 894, __PRETTY_FUNCTION__); } while (0)
;
895 assert(tag)do { if ((__builtin_expect(!!(!(tag)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("tag"), "../src/libsystemd/sd-device/device-private.c"
, 895, __PRETTY_FUNCTION__); } while (0)
;
896
897 r = device_get_id_filename(device, &id);
898 if (r < 0)
899 return r;
900
901 path = strjoina("/run/udev/tags/", tag, "/", id)({ const char *_appendees_[] = { "/run/udev/tags/", tag, "/",
id }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_
= 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
902
903 if (add) {
904 r = touch_file(path, true1, USEC_INFINITY((usec_t) -1), UID_INVALID((uid_t) -1), GID_INVALID((gid_t) -1), 0444);
905 if (r < 0)
906 return r;
907 } else {
908 r = unlink(path);
909 if (r < 0 && errno(*__errno_location ()) != ENOENT2)
910 return -errno(*__errno_location ());
911 }
912
913 return 0;
914}
915
916int device_tag_index(sd_device *device, sd_device *device_old, bool_Bool add) {
917 const char *tag;
918 int r = 0, k;
919
920 if (add && device_old) {
921 /* delete possible left-over tags */
922 FOREACH_DEVICE_TAG(device_old, tag)for (tag = sd_device_get_tag_first(device_old); tag; tag = sd_device_get_tag_next
(device_old))
{
923 if (!sd_device_has_tag(device, tag)) {
924 k = device_tag(device_old, tag, false0);
925 if (r >= 0 && k < 0)
926 r = k;
927 }
928 }
929 }
930
931 FOREACH_DEVICE_TAG(device, tag)for (tag = sd_device_get_tag_first(device); tag; tag = sd_device_get_tag_next
(device))
{
932 k = device_tag(device, tag, add);
933 if (r >= 0 && k < 0)
934 r = k;
935 }
936
937 return r;
938}
939
940static bool_Bool device_has_info(sd_device *device) {
941 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 941, __PRETTY_FUNCTION__); } while (0)
;
942
943 if (!set_isempty(device->devlinks))
944 return true1;
945
946 if (device->devlink_priority != 0)
947 return true1;
948
949 if (!ordered_hashmap_isempty(device->properties_db))
950 return true1;
951
952 if (!set_isempty(device->tags))
953 return true1;
954
955 if (device->watch_handle >= 0)
956 return true1;
957
958 return false0;
959}
960
961void device_set_db_persist(sd_device *device) {
962 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 962, __PRETTY_FUNCTION__); } while (0)
;
963
964 device->db_persist = true1;
965}
966
967int device_update_db(sd_device *device) {
968 const char *id;
969 char *path;
970 _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0);
971 _cleanup_free___attribute__((cleanup(freep))) char *path_tmp = NULL((void*)0);
972 bool_Bool has_info;
973 int r;
974
975 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 975, __PRETTY_FUNCTION__); } while (0)
;
976
977 has_info = device_has_info(device);
978
979 r = device_get_id_filename(device, &id);
980 if (r < 0)
981 return r;
982
983 path = strjoina("/run/udev/data/", id)({ const char *_appendees_[] = { "/run/udev/data/", id }; char
*_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ <
__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
984
985 /* do not store anything for otherwise empty devices */
986 if (!has_info && major(device->devnum)gnu_dev_major (device->devnum) == 0 && device->ifindex == 0) {
987 r = unlink(path);
988 if (r < 0 && errno(*__errno_location ()) != ENOENT2)
989 return -errno(*__errno_location ());
990
991 return 0;
992 }
993
994 /* write a database file */
995 r = mkdir_parents(path, 0755);
996 if (r < 0)
997 return r;
998
999 r = fopen_temporary(path, &f, &path_tmp);
1000 if (r < 0)
1001 return r;
1002
1003 /*
1004 * set 'sticky' bit to indicate that we should not clean the
1005 * database when we transition from initramfs to the real root
1006 */
1007 if (device->db_persist) {
1008 r = fchmod(fileno(f), 01644);
1009 if (r < 0) {
1010 r = -errno(*__errno_location ());
1011 goto fail;
1012 }
1013 } else {
1014 r = fchmod(fileno(f), 0644);
1015 if (r < 0) {
1016 r = -errno(*__errno_location ());
1017 goto fail;
1018 }
1019 }
1020
1021 if (has_info) {
1022 const char *property, *value, *tag;
1023 Iterator i;
1024
1025 if (major(device->devnum)gnu_dev_major (device->devnum) > 0) {
1026 const char *devlink;
1027
1028 FOREACH_DEVICE_DEVLINK(device, devlink)for (devlink = sd_device_get_devlink_first(device); devlink; devlink
= sd_device_get_devlink_next(device))
1029 fprintf(f, "S:%s\n", devlink + STRLEN("/dev/")(sizeof("""/dev/""") - 1));
1030
1031 if (device->devlink_priority != 0)
1032 fprintf(f, "L:%i\n", device->devlink_priority);
1033
1034 if (device->watch_handle >= 0)
1035 fprintf(f, "W:%i\n", device->watch_handle);
1036 }
1037
1038 if (device->usec_initialized > 0)
1039 fprintf(f, "I:"USEC_FMT"%" "l" "u""\n", device->usec_initialized);
1040
1041 ORDERED_HASHMAP_FOREACH_KEY(value, property, device->properties_db, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); ordered_hashmap_iterate((device->
properties_db), &(i), (void**)&(value), (const void**
) &(property)); )
1042 fprintf(f, "E:%s=%s\n", property, value);
1043
1044 FOREACH_DEVICE_TAG(device, tag)for (tag = sd_device_get_tag_first(device); tag; tag = sd_device_get_tag_next
(device))
1045 fprintf(f, "G:%s\n", tag);
1046 }
1047
1048 r = fflush_and_check(f);
1049 if (r < 0)
1050 goto fail;
1051
1052 r = rename(path_tmp, path);
1053 if (r < 0) {
1054 r = -errno(*__errno_location ());
1055 goto fail;
1056 }
1057
1058 log_debug("created %s file '%s' for '%s'", has_info ? "db" : "empty",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 1059, __func__
, "created %s file '%s' for '%s'", has_info ? "db" : "empty",
path, device->devpath) : -abs(_e); })
1059 path, device->devpath)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 1059, __func__
, "created %s file '%s' for '%s'", has_info ? "db" : "empty",
path, device->devpath) : -abs(_e); })
;
1060
1061 return 0;
1062
1063fail:
1064 (void) unlink(path);
1065 (void) unlink(path_tmp);
1066
1067 return log_error_errno(r, "failed to create %s file '%s' for '%s'", has_info ? "db" : "empty", path, device->devpath)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-device/device-private.c", 1067, __func__
, "failed to create %s file '%s' for '%s'", has_info ? "db" :
"empty", path, device->devpath) : -abs(_e); })
;
1068}
1069
1070int device_delete_db(sd_device *device) {
1071 const char *id;
1072 char *path;
1073 int r;
1074
1075 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 1075, __PRETTY_FUNCTION__); } while (0)
;
1076
1077 r = device_get_id_filename(device, &id);
1078 if (r < 0)
1079 return r;
1080
1081 path = strjoina("/run/udev/data/", id)({ const char *_appendees_[] = { "/run/udev/data/", id }; char
*_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ <
__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
1082
1083 r = unlink(path);
1084 if (r < 0 && errno(*__errno_location ()) != ENOENT2)
1085 return -errno(*__errno_location ());
1086
1087 return 0;
1088}
1089
1090int device_read_db_force(sd_device *device) {
1091 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd/sd-device/device-private.c"
, 1091, __PRETTY_FUNCTION__); } while (0)
;
1092
1093 return device_read_db_aux(device, true1);
1094}