File: | build-scan/../src/udev/udev-builtin-blkid.c |
Warning: | line 178, column 16 Potential leak of memory pointed to by 'root_id' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: GPL-2.0+ */ | |||
2 | /* | |||
3 | * probe disks for filesystems and partitions | |||
4 | * | |||
5 | * Copyright © 2011 Karel Zak <kzak@redhat.com> | |||
6 | * | |||
7 | */ | |||
8 | ||||
9 | #include <blkid.h> | |||
10 | #include <errno(*__errno_location ()).h> | |||
11 | #include <fcntl.h> | |||
12 | #include <getopt.h> | |||
13 | #include <stdio.h> | |||
14 | #include <stdlib.h> | |||
15 | #include <string.h> | |||
16 | #include <sys/stat.h> | |||
17 | ||||
18 | #include "sd-id128.h" | |||
19 | ||||
20 | #include "alloc-util.h" | |||
21 | #include "blkid-util.h" | |||
22 | #include "efivars.h" | |||
23 | #include "fd-util.h" | |||
24 | #include "gpt.h" | |||
25 | #include "parse-util.h" | |||
26 | #include "string-util.h" | |||
27 | #include "udev.h" | |||
28 | ||||
29 | static void print_property(struct udev_device *dev, bool_Bool test, const char *name, const char *value) { | |||
30 | char s[256]; | |||
31 | ||||
32 | s[0] = '\0'; | |||
33 | ||||
34 | if (streq(name, "TYPE")(strcmp((name),("TYPE")) == 0)) { | |||
35 | udev_builtin_add_property(dev, test, "ID_FS_TYPE", value); | |||
36 | ||||
37 | } else if (streq(name, "USAGE")(strcmp((name),("USAGE")) == 0)) { | |||
38 | udev_builtin_add_property(dev, test, "ID_FS_USAGE", value); | |||
39 | ||||
40 | } else if (streq(name, "VERSION")(strcmp((name),("VERSION")) == 0)) { | |||
41 | udev_builtin_add_property(dev, test, "ID_FS_VERSION", value); | |||
42 | ||||
43 | } else if (streq(name, "UUID")(strcmp((name),("UUID")) == 0)) { | |||
44 | blkid_safe_string(value, s, sizeof(s)); | |||
45 | udev_builtin_add_property(dev, test, "ID_FS_UUID", s); | |||
46 | blkid_encode_string(value, s, sizeof(s)); | |||
47 | udev_builtin_add_property(dev, test, "ID_FS_UUID_ENC", s); | |||
48 | ||||
49 | } else if (streq(name, "UUID_SUB")(strcmp((name),("UUID_SUB")) == 0)) { | |||
50 | blkid_safe_string(value, s, sizeof(s)); | |||
51 | udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB", s); | |||
52 | blkid_encode_string(value, s, sizeof(s)); | |||
53 | udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB_ENC", s); | |||
54 | ||||
55 | } else if (streq(name, "LABEL")(strcmp((name),("LABEL")) == 0)) { | |||
56 | blkid_safe_string(value, s, sizeof(s)); | |||
57 | udev_builtin_add_property(dev, test, "ID_FS_LABEL", s); | |||
58 | blkid_encode_string(value, s, sizeof(s)); | |||
59 | udev_builtin_add_property(dev, test, "ID_FS_LABEL_ENC", s); | |||
60 | ||||
61 | } else if (streq(name, "PTTYPE")(strcmp((name),("PTTYPE")) == 0)) { | |||
62 | udev_builtin_add_property(dev, test, "ID_PART_TABLE_TYPE", value); | |||
63 | ||||
64 | } else if (streq(name, "PTUUID")(strcmp((name),("PTUUID")) == 0)) { | |||
65 | udev_builtin_add_property(dev, test, "ID_PART_TABLE_UUID", value); | |||
66 | ||||
67 | } else if (streq(name, "PART_ENTRY_NAME")(strcmp((name),("PART_ENTRY_NAME")) == 0)) { | |||
68 | blkid_encode_string(value, s, sizeof(s)); | |||
69 | udev_builtin_add_property(dev, test, "ID_PART_ENTRY_NAME", s); | |||
70 | ||||
71 | } else if (streq(name, "PART_ENTRY_TYPE")(strcmp((name),("PART_ENTRY_TYPE")) == 0)) { | |||
72 | blkid_encode_string(value, s, sizeof(s)); | |||
73 | udev_builtin_add_property(dev, test, "ID_PART_ENTRY_TYPE", s); | |||
74 | ||||
75 | } else if (startswith(name, "PART_ENTRY_")) { | |||
76 | strscpyl(s, sizeof(s), "ID_", name, NULL((void*)0)); | |||
77 | udev_builtin_add_property(dev, test, s, value); | |||
78 | ||||
79 | } else if (streq(name, "SYSTEM_ID")(strcmp((name),("SYSTEM_ID")) == 0)) { | |||
80 | blkid_encode_string(value, s, sizeof(s)); | |||
81 | udev_builtin_add_property(dev, test, "ID_FS_SYSTEM_ID", s); | |||
82 | ||||
83 | } else if (streq(name, "PUBLISHER_ID")(strcmp((name),("PUBLISHER_ID")) == 0)) { | |||
84 | blkid_encode_string(value, s, sizeof(s)); | |||
85 | udev_builtin_add_property(dev, test, "ID_FS_PUBLISHER_ID", s); | |||
86 | ||||
87 | } else if (streq(name, "APPLICATION_ID")(strcmp((name),("APPLICATION_ID")) == 0)) { | |||
88 | blkid_encode_string(value, s, sizeof(s)); | |||
89 | udev_builtin_add_property(dev, test, "ID_FS_APPLICATION_ID", s); | |||
90 | ||||
91 | } else if (streq(name, "BOOT_SYSTEM_ID")(strcmp((name),("BOOT_SYSTEM_ID")) == 0)) { | |||
92 | blkid_encode_string(value, s, sizeof(s)); | |||
93 | udev_builtin_add_property(dev, test, "ID_FS_BOOT_SYSTEM_ID", s); | |||
94 | } | |||
95 | } | |||
96 | ||||
97 | static int find_gpt_root(struct udev_device *dev, blkid_probe pr, bool_Bool test) { | |||
98 | ||||
99 | #if defined(GPT_ROOT_NATIVE((const sd_id128_t) { .bytes = { 0x4f, 0x68, 0xbc, 0xe3, 0xe8 , 0xcd, 0x4d, 0xb1, 0x96, 0xe7, 0xfb, 0xca, 0xf9, 0x84, 0xb7, 0x09 }})) && ENABLE_EFI1 | |||
100 | ||||
101 | _cleanup_free___attribute__((cleanup(freep))) char *root_id = NULL((void*)0); | |||
102 | bool_Bool found_esp = false0; | |||
103 | blkid_partlist pl; | |||
104 | int i, nvals, r; | |||
105 | ||||
106 | assert(pr)do { if ((__builtin_expect(!!(!(pr)),0))) log_assert_failed_realm (LOG_REALM_UDEV, ("pr"), "../src/udev/udev-builtin-blkid.c", 106 , __PRETTY_FUNCTION__); } while (0); | |||
107 | ||||
108 | /* Iterate through the partitions on this disk, and see if the | |||
109 | * EFI ESP we booted from is on it. If so, find the first root | |||
110 | * disk, and add a property indicating its partition UUID. */ | |||
111 | ||||
112 | errno(*__errno_location ()) = 0; | |||
113 | pl = blkid_probe_get_partitions(pr); | |||
114 | if (!pl) | |||
115 | return -errno(*__errno_location ()) ?: -ENOMEM12; | |||
116 | ||||
117 | nvals = blkid_partlist_numof_partitions(pl); | |||
118 | for (i = 0; i < nvals; i++) { | |||
119 | blkid_partition pp; | |||
120 | const char *stype, *sid; | |||
121 | sd_id128_t type; | |||
122 | ||||
123 | pp = blkid_partlist_get_partition(pl, i); | |||
124 | if (!pp) | |||
125 | continue; | |||
126 | ||||
127 | sid = blkid_partition_get_uuid(pp); | |||
128 | if (!sid) | |||
129 | continue; | |||
130 | ||||
131 | stype = blkid_partition_get_type_string(pp); | |||
132 | if (!stype) | |||
133 | continue; | |||
134 | ||||
135 | if (sd_id128_from_string(stype, &type) < 0) | |||
136 | continue; | |||
137 | ||||
138 | if (sd_id128_equal(type, GPT_ESP((const sd_id128_t) { .bytes = { 0xc1, 0x2a, 0x73, 0x28, 0xf8 , 0x1f, 0x11, 0xd2, 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b }}))) { | |||
139 | sd_id128_t id, esp; | |||
140 | ||||
141 | /* We found an ESP, let's see if it matches | |||
142 | * the ESP we booted from. */ | |||
143 | ||||
144 | if (sd_id128_from_string(sid, &id) < 0) | |||
145 | continue; | |||
146 | ||||
147 | r = efi_loader_get_device_part_uuid(&esp); | |||
148 | if (r < 0) | |||
149 | return r; | |||
150 | ||||
151 | if (sd_id128_equal(id, esp)) | |||
152 | found_esp = true1; | |||
153 | ||||
154 | } else if (sd_id128_equal(type, GPT_ROOT_NATIVE((const sd_id128_t) { .bytes = { 0x4f, 0x68, 0xbc, 0xe3, 0xe8 , 0xcd, 0x4d, 0xb1, 0x96, 0xe7, 0xfb, 0xca, 0xf9, 0x84, 0xb7, 0x09 }}))) { | |||
155 | unsigned long long flags; | |||
156 | ||||
157 | flags = blkid_partition_get_flags(pp); | |||
158 | if (flags & GPT_FLAG_NO_AUTO(1ULL << 63)) | |||
159 | continue; | |||
160 | ||||
161 | /* We found a suitable root partition, let's | |||
162 | * remember the first one. */ | |||
163 | ||||
164 | if (!root_id
| |||
165 | root_id = strdup(sid); | |||
166 | if (!root_id) | |||
167 | return -ENOMEM12; | |||
168 | } | |||
169 | } | |||
170 | } | |||
171 | ||||
172 | /* We found the ESP on this disk, and also found a root | |||
173 | * partition, nice! Let's export its UUID */ | |||
174 | if (found_esp
| |||
175 | udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT_UUID", root_id); | |||
176 | #endif | |||
177 | ||||
178 | return 0; | |||
| ||||
179 | } | |||
180 | ||||
181 | static int probe_superblocks(blkid_probe pr) { | |||
182 | struct stat st; | |||
183 | int rc; | |||
184 | ||||
185 | if (fstat(blkid_probe_get_fd(pr), &st)) | |||
186 | return -errno(*__errno_location ()); | |||
187 | ||||
188 | blkid_probe_enable_partitions(pr, 1); | |||
189 | ||||
190 | if (!S_ISCHR(st.st_mode)((((st.st_mode)) & 0170000) == (0020000)) && | |||
191 | blkid_probe_get_size(pr) <= 1024 * 1440 && | |||
192 | blkid_probe_is_wholedisk(pr)) { | |||
193 | /* | |||
194 | * check if the small disk is partitioned, if yes then | |||
195 | * don't probe for filesystems. | |||
196 | */ | |||
197 | blkid_probe_enable_superblocks(pr, 0); | |||
198 | ||||
199 | rc = blkid_do_fullprobe(pr); | |||
200 | if (rc < 0) | |||
201 | return rc; /* -1 = error, 1 = nothing, 0 = success */ | |||
202 | ||||
203 | if (blkid_probe_lookup_value(pr, "PTTYPE", NULL((void*)0), NULL((void*)0)) == 0) | |||
204 | return 0; /* partition table detected */ | |||
205 | } | |||
206 | ||||
207 | blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS(1 << 2)); | |||
208 | blkid_probe_enable_superblocks(pr, 1); | |||
209 | ||||
210 | return blkid_do_safeprobe(pr); | |||
211 | } | |||
212 | ||||
213 | static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool_Bool test) { | |||
214 | const char *root_partition; | |||
215 | int64_t offset = 0; | |||
216 | bool_Bool noraid = false0; | |||
217 | _cleanup_close___attribute__((cleanup(closep))) int fd = -1; | |||
218 | _cleanup_(blkid_free_probep)__attribute__((cleanup(blkid_free_probep))) blkid_probe pr = NULL((void*)0); | |||
219 | const char *data; | |||
220 | const char *name; | |||
221 | int nvals; | |||
222 | int i; | |||
223 | int err = 0; | |||
224 | bool_Bool is_gpt = false0; | |||
225 | ||||
226 | static const struct option options[] = { | |||
227 | { "offset", required_argument1, NULL((void*)0), 'o' }, | |||
228 | { "noraid", no_argument0, NULL((void*)0), 'R' }, | |||
229 | {} | |||
230 | }; | |||
231 | ||||
232 | for (;;) { | |||
| ||||
233 | int option; | |||
234 | ||||
235 | option = getopt_long(argc, argv, "o:R", options, NULL((void*)0)); | |||
236 | if (option == -1) | |||
237 | break; | |||
238 | ||||
239 | switch (option) { | |||
240 | case 'o': | |||
241 | err = safe_atoi64(optarg, &offset); | |||
242 | if (err < 0) | |||
243 | goto out; | |||
244 | if (offset < 0) { | |||
245 | err = -ERANGE34; | |||
246 | goto out; | |||
247 | } | |||
248 | break; | |||
249 | case 'R': | |||
250 | noraid = true1; | |||
251 | break; | |||
252 | } | |||
253 | } | |||
254 | ||||
255 | pr = blkid_new_probe(); | |||
256 | if (!pr) | |||
257 | return EXIT_FAILURE1; | |||
258 | ||||
259 | blkid_probe_set_superblocks_flags(pr, | |||
260 | BLKID_SUBLKS_LABEL(1 << 1) | BLKID_SUBLKS_UUID(1 << 3) | | |||
261 | BLKID_SUBLKS_TYPE(1 << 5) | BLKID_SUBLKS_SECTYPE(1 << 6) | | |||
262 | BLKID_SUBLKS_USAGE(1 << 7) | BLKID_SUBLKS_VERSION(1 << 8)); | |||
263 | ||||
264 | if (noraid
| |||
265 | blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN1, BLKID_USAGE_RAID(1 << 2)); | |||
266 | ||||
267 | fd = open(udev_device_get_devnode(dev), O_RDONLY00|O_CLOEXEC02000000); | |||
268 | if (fd < 0) { | |||
269 | err = log_debug_errno(errno, "Failure opening block device %s: %m", udev_device_get_devnode(dev))({ int _level = ((7)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= ( (_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/udev/udev-builtin-blkid.c", 269, __func__, "Failure opening block device %s: %m", udev_device_get_devnode (dev)) : -abs(_e); }); | |||
270 | goto out; | |||
271 | } | |||
272 | ||||
273 | err = blkid_probe_set_device(pr, fd, offset, 0); | |||
274 | if (err < 0) | |||
275 | goto out; | |||
276 | ||||
277 | log_debug("probe %s %sraid offset=%"PRIi64,({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/udev-builtin-blkid.c", 279, __func__, "probe %s %sraid offset=%" "l" "i", udev_device_get_devnode(dev), noraid ? "no" : "", offset ) : -abs(_e); }) | |||
278 | udev_device_get_devnode(dev),({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/udev-builtin-blkid.c", 279, __func__, "probe %s %sraid offset=%" "l" "i", udev_device_get_devnode(dev), noraid ? "no" : "", offset ) : -abs(_e); }) | |||
279 | noraid ? "no" : "", offset)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/udev-builtin-blkid.c", 279, __func__, "probe %s %sraid offset=%" "l" "i", udev_device_get_devnode(dev), noraid ? "no" : "", offset ) : -abs(_e); }); | |||
280 | ||||
281 | err = probe_superblocks(pr); | |||
282 | if (err < 0) | |||
283 | goto out; | |||
284 | ||||
285 | /* If we are a partition then our parent passed on the root | |||
286 | * partition UUID to us */ | |||
287 | root_partition = udev_device_get_property_value(dev, "ID_PART_GPT_AUTO_ROOT_UUID"); | |||
288 | ||||
289 | nvals = blkid_probe_numof_values(pr); | |||
290 | for (i = 0; i < nvals; i++) { | |||
291 | if (blkid_probe_get_value(pr, i, &name, &data, NULL((void*)0))) | |||
292 | continue; | |||
293 | ||||
294 | print_property(dev, test, name, data); | |||
295 | ||||
296 | /* Is this a disk with GPT partition table? */ | |||
297 | if (streq(name, "PTTYPE")(strcmp((name),("PTTYPE")) == 0) && streq(data, "gpt")(strcmp((data),("gpt")) == 0)) | |||
298 | is_gpt = true1; | |||
299 | ||||
300 | /* Is this a partition that matches the root partition | |||
301 | * property we inherited from our parent? */ | |||
302 | if (root_partition && streq(name, "PART_ENTRY_UUID")(strcmp((name),("PART_ENTRY_UUID")) == 0) && streq(data, root_partition)(strcmp((data),(root_partition)) == 0)) | |||
303 | udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT", "1"); | |||
304 | } | |||
305 | ||||
306 | if (is_gpt
| |||
307 | find_gpt_root(dev, pr, test); | |||
308 | ||||
309 | out: | |||
310 | if (err < 0) | |||
311 | return EXIT_FAILURE1; | |||
312 | ||||
313 | return EXIT_SUCCESS0; | |||
314 | } | |||
315 | ||||
316 | const struct udev_builtin udev_builtin_blkid = { | |||
317 | .name = "blkid", | |||
318 | .cmd = builtin_blkid, | |||
319 | .help = "Filesystem and partition probing", | |||
320 | .run_once = true1, | |||
321 | }; |