| 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 | }; |