block: partition: aix: bound LV name formatting
PATCH 1/1 block: partition: aix: bound LV name formatting
In reply to a message not in the archiveFrom: Zhiling Zou <[email protected]>
AIX logical volume names are stored on disk as fixed-size fields. The partition parser reads them into struct lvname, but later formats the fields with %s. If an on-disk name is not NUL-terminated, the string formatting code can keep reading past the end of the 64-byte name field.
Limit the formatted string length to the size of the on-disk name field when printing AIX logical volume names.
--- block/partitions/aix.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
block/partitions/aix.c +4 -2
@@ -261,7 +261,8 @@ int aix_partition(struct parsed_partitions *state)put_partition (state, lv_ix +1 , (i +1 - lp_ix) * pp_blocks_size + psn_part1, lvip[lv_ix].pps_per_lv * pp_blocks_size); -seq_buf_printf (&state->pp_buf," <%s>\n" , +seq_buf_printf (&state->pp_buf," <%.*s>\n" , + (int )sizeof (n[lv_ix].name), n[lv_ix].name); lvip[lv_ix].lv_is_contiguous =1 ; ret =1 ;
@@ -273,7 +274,8 @@ int aix_partition(struct parsed_partitions *state)if (lvip[i].pps_found && !lvip[i].lv_is_contiguous) {char tmp[sizeof (n[i].name) +1 ];// null char -snprintf (tmp,sizeof (tmp),"%s" , n[i].name); +snprintf (tmp,sizeof (tmp),"%.*s" , + (int )sizeof (n[i].name), n[i].name);pr_warn ("partition %s (%u pp's found) is " "not contiguous\n" , tmp, lvip[i].pps_found);
Signature · 1 line
2.43.0
Hello Ren Wei,
Quoted 36 lines · Ren Wei
From: Zhiling Zou <[email protected]>
AIX logical volume names are stored on disk as fixed-size fields. The partition parser reads them into struct lvname, but later formats the fields with %s. If an on-disk name is not NUL-terminated, the string formatting code can keep reading past the end of the 64-byte name field.
Limit the formatted string length to the size of the on-disk name field when printing AIX logical volume names.
Fixes 6ceea22bbbc8 ("partitions: add aix lvm partition support files")Reported-by Yuan Tan <[email protected]>Reported-by Xin Liu <[email protected]>Assisted-by Codex:gpt-5.4Signed-off-by Zhiling Zou <[email protected]>Signed-off-by Ren Wei <[email protected]>--- block/partitions/aix.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)block/partitions/aix.c +2
-1@@ -261,7 +261,8 @@ int aix_partition(struct parsed_partitions *state)put_partition (state, lv_ix +1 , (i +1 - lp_ix) * pp_blocks_size + psn_part1, lvip[lv_ix].pps_per_lv * pp_blocks_size); -seq_buf_printf (&state->pp_buf," <%s>\n" , +seq_buf_printf (&state->pp_buf," <%.*s>\n" , + (int )sizeof (n[lv_ix].name), n[lv_ix].name); lvip[lv_ix].lv_is_contiguous =1 ; ret =1 ;
block/partitions/aix.c int aix_partition(struct parsed_partitions *state) · line 278
Quoted 6 lines
block/partitions/aix.c +2
-1@@ -273,7 +274,8 @@ int aix_partition(struct parsed_partitions *state)if (lvip[i].pps_found && !lvip[i].lv_is_contiguous) {char tmp[sizeof (n[i].name) +1 ];// null char -snprintf (tmp,sizeof (tmp),"%s" , n[i].name); +snprintf (tmp,sizeof (tmp),"%.*s" , + (int )sizeof (n[i].name), n[i].name);
Is this change necessary ? snprintf always adds a NULL terminator and truncates the input if needed, isn't it ?
Quoted 5 lines
block/partitions/aix.c +0
-0pr_warn ("partition %s (%u pp's found) is " "not contiguous\n" , tmp, lvip[i].pps_found);Signature · 1 line
2.43.0
Best Regards
Philippe De Muyter
Quoted 43 lines · Philippe De Muyter
Hello Ren Wei,
Quoted 39 lines · Ren Wei
From: Zhiling Zou <[email protected]>
AIX logical volume names are stored on disk as fixed-size fields. The partition parser reads them into struct lvname, but later formats the fields with %s. If an on-disk name is not NUL-terminated, the string formatting code can keep reading past the end of the 64-byte name field.
Limit the formatted string length to the size of the on-disk name field when printing AIX logical volume names.
Fixes 6ceea22bbbc8 ("partitions: add aix lvm partition support files")Reported-by Yuan Tan <[email protected]>Reported-by Xin Liu <[email protected]>Assisted-by Codex:gpt-5.4Signed-off-by Zhiling Zou <[email protected]>Signed-off-by Ren Wei <[email protected]>--- block/partitions/aix.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)block/partitions/aix.c +2
-1@@ -261,7 +261,8 @@ int aix_partition(struct parsed_partitions *state)put_partition (state, lv_ix +1 , (i +1 - lp_ix) * pp_blocks_size + psn_part1, lvip[lv_ix].pps_per_lv * pp_blocks_size); -seq_buf_printf (&state->pp_buf," <%s>\n" , +seq_buf_printf (&state->pp_buf," <%.*s>\n" , + (int )sizeof (n[lv_ix].name), n[lv_ix].name); lvip[lv_ix].lv_is_contiguous =1 ; ret =1 ;@@ -273,7 +274,8 @@ int aix_partition(struct parsed_partitions *state)if (lvip[i].pps_found && !lvip[i].lv_is_contiguous) {char tmp[sizeof (n[i].name) +1 ];// null char
Quoted 7 lines
block/partitions/aix.c int aix_partition(struct parsed_partitions *state) · line 278
Quoted 3 lines
block/partitions/aix.c +2
-1-snprintf (tmp,sizeof (tmp),"%s" , n[i].name); +snprintf (tmp,sizeof (tmp),"%.*s" , + (int )sizeof (n[i].name), n[i].name);Is this change necessary ? snprintf always adds a NULL terminator and truncates the input if needed, isn't it ?
Yes, snprintf() guarantees that the destination buffer is NUL-terminated and truncates the output.
However, with %s and no precision, snprintf() still treats n[i].name as a NUL-terminated source string. If the on-disk fixed-size name field is not NUL-terminated, snprintf() can keep reading past the end of n[i].name while looking for the terminator, before truncating the output into tmp.
So the issue is not an overflow of tmp, but an out-of-bounds read from the fixed-width source field. The precision is needed to bound that source read to sizeof(n[i].name).
Quoted 9 lines
Quoted 5 lines
block/partitions/aix.c +0
-1pr_warn ("partition %s (%u pp's found) is " "not contiguous\n" , tmp, lvip[i].pps_found); --2.43.0
Best Regards
Philippe De Muyter
Hello tt roxy,
Quoted 27 lines · tt roxy
Quoted 9 lines · Philippe De Muyter
Hello Ren Wei,
Quoted 5 lines · Ren Wei
From: Zhiling Zou <[email protected]>
block/partitions/aix.c +0
-0@@ -273,7 +274,8 @@ int aix_partition(struct parsed_partitions *state)if (lvip[i].pps_found && !lvip[i].lv_is_contiguous) {char tmp[sizeof (n[i].name) +1 ];// null char Quoted 7 lines
block/partitions/aix.c int aix_partition(struct parsed_partitions *state) · line 278
Quoted 3 lines
block/partitions/aix.c +2
-1-snprintf (tmp,sizeof (tmp),"%s" , n[i].name); +snprintf (tmp,sizeof (tmp),"%.*s" , + (int )sizeof (n[i].name), n[i].name);Is this change necessary ? snprintf always adds a NULL terminator and truncates the input if needed, isn't it ?
Yes,
snprintf()guarantees that the destination buffer is NUL-terminated and truncates the output.However, with %s and no precision,
snprintf()still treats n[i].name as a NUL-terminated source string. If the on-disk fixed-size name field is not NUL-terminated,snprintf()can keep reading past the end of n[i].name while looking for the terminator, before truncating the output into tmp.
Quoted 8 lines
So the issue is not an overflow of tmp, but an out-of-bounds read from the fixed-width source field. The precision is needed to bound that source read to
sizeof(n[i].name).Quoted 4 lines
Quoted 4 lines
block/partitions/aix.c +0
-1pr_warn ("partition %s (%u pp's found) is " "not contiguous\n" , tmp, lvip[i].pps_found); --
Actually the 'tmp' buffer is not needed. Printing directky n[i].name with '%.*s' in pr_warn would be enough to fix the problem IMHO.
Philippe