mirror of
git://sourceware.org/git/lvm2.git
synced 2025-02-17 17:57:56 +03:00
device_id: ensure pvid buffers are ID_LEN+1
A pvid string read from system.devices could be less then ID_LEN since system.devices fields can be edited. Ensure the pvid buffer is ID_LEN+1 even if the string read from the file is shorter.
This commit is contained in:
parent
de2b11f39a
commit
631b8edefb
@ -248,4 +248,6 @@ struct device_id_list *device_id_list_find_dev(struct dm_list *devices, struct d
|
||||
int device_list_remove(struct dm_list *devices, struct device *dev);
|
||||
struct device_list *device_list_find_dev(struct dm_list *devices, struct device *dev);
|
||||
|
||||
char *strdup_pvid(char *pvid);
|
||||
|
||||
#endif
|
||||
|
@ -51,6 +51,25 @@ static const char *_searched_file_dir = DEFAULT_RUN_DIR;
|
||||
char devices_file_hostname_orig[PATH_MAX];
|
||||
char devices_file_product_uuid_orig[PATH_MAX];
|
||||
|
||||
/*
|
||||
* The input string pvid may be of any length, it's often
|
||||
* read from system.devices, which can be edited.
|
||||
* These pvid strings are often compared to pvids in the
|
||||
* form char pvid[ID_LEN+1] using memcmp with ID_LEN.
|
||||
*
|
||||
* . ignore any pvid characters over ID_LEN
|
||||
* . return a buffer is ID_LEN+1 in size, even
|
||||
* if the pvid string is shorter.
|
||||
*/
|
||||
char *strdup_pvid(char *pvid)
|
||||
{
|
||||
char *buf;
|
||||
if (!(buf = zalloc(ID_LEN + 1)))
|
||||
return NULL;
|
||||
strncpy(buf, pvid, ID_LEN);
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *devices_file_version(void)
|
||||
{
|
||||
return _devices_file_version;
|
||||
@ -1267,7 +1286,15 @@ int device_ids_read(struct cmd_context *cmd)
|
||||
if (pvid) {
|
||||
_copy_idline_str(pvid, buf, PATH_MAX);
|
||||
if (buf[0] && (buf[0] != '.')) {
|
||||
if (!(du->pvid = strdup(buf)))
|
||||
/*
|
||||
* Caution: pvids are usually stored as
|
||||
* char pvid[ID_LEN+1], and use memcmp/memcpy
|
||||
* with ID_LEN. So, strdup_pvid is used to
|
||||
* ensure the buffer for du->pvid is ID_LEN+1.
|
||||
* Then, memcmp/memcpy with ID_LEN will work,
|
||||
* and printing du->pvid with %s will work.
|
||||
*/
|
||||
if (!(du->pvid = strdup_pvid(buf)))
|
||||
line_error = 1;
|
||||
}
|
||||
}
|
||||
@ -1881,7 +1908,7 @@ id_done:
|
||||
du->idname = strdup(id->idname);
|
||||
du->devname = strdup(dev_name(dev));
|
||||
du->dev = dev;
|
||||
du->pvid = strdup(pvid);
|
||||
du->pvid = strdup_pvid(pvid);
|
||||
|
||||
dev_get_partition_number(dev, &du->part);
|
||||
|
||||
@ -2659,7 +2686,7 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
|
||||
dev_name(dev), dev->pvid);
|
||||
log_warn("Device %s has PVID %s (devices file %s)",
|
||||
dev_name(dev), dev->pvid, du->pvid ?: "none");
|
||||
if (!(tmpdup = strdup(dev->pvid)))
|
||||
if (!(tmpdup = strdup_pvid(dev->pvid)))
|
||||
continue;
|
||||
free(du->pvid);
|
||||
du->pvid = tmpdup;
|
||||
@ -3210,7 +3237,7 @@ void device_ids_check_serial(struct cmd_context *cmd, struct dm_list *scan_devs,
|
||||
|
||||
log_debug("Device %s with serial number %s has PVID %s (devices file %s)",
|
||||
dev_name(dev), du->idname, dev->pvid, du->pvid ?: "none");
|
||||
if (!(tmpdup = strdup(dev->pvid)))
|
||||
if (!(tmpdup = strdup_pvid(dev->pvid)))
|
||||
continue;
|
||||
free(du->pvid);
|
||||
du->pvid = tmpdup;
|
||||
@ -3395,7 +3422,7 @@ void device_ids_search(struct cmd_context *cmd, struct dm_list *new_devs,
|
||||
memcpy(dil->pvid, du->pvid, ID_LEN);
|
||||
dm_list_add(&search_pvids, &dil->list);
|
||||
search_pvids_count++;
|
||||
search_pvids_hash = calc_crc(search_pvids_hash, (const uint8_t *)du->pvid, strlen(du->pvid));
|
||||
search_pvids_hash = calc_crc(search_pvids_hash, (const uint8_t *)du->pvid, ID_LEN);
|
||||
}
|
||||
|
||||
/* No unmatched PVIDs to search for, and no system id to update. */
|
||||
|
@ -190,7 +190,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
if (du) {
|
||||
memcpy(pvid, &pv->id.uuid, ID_LEN);
|
||||
free(du->pvid);
|
||||
if (!(du->pvid = strdup(pvid)))
|
||||
if (!(du->pvid = strdup_pvid(pvid)))
|
||||
log_error("Failed to set pvid for devices file.");
|
||||
if (!device_ids_write(cmd))
|
||||
log_warn("Failed to update devices file.");
|
||||
|
Loading…
x
Reference in New Issue
Block a user