summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanosch Frank <frankja@linux.ibm.com>2020-06-18 12:36:48 -0400
committerDmitry V. Levin <ldv@altlinux.org>2020-07-24 08:00:00 +0000
commit0ed6f3258d6809e44fc44b3ddfa6d2e996f423e2 (patch)
tree4ea10c341244ad46f59e07eb45026d662d42e6cf
parent03d9f49c3187a9be7b337f2cd863fa3a10ad7e7b (diff)
downloadstrace-0ed6f3258d6809e44fc44b3ddfa6d2e996f423e2.tar.gz
s390x: sthyi: Fix section size requirement and error
Some old z/VM instances report only 40 bytes for the partition section, as they don't report the last three struct members. Let's lower the size check of that section to 40 to accommodate them. Also we expect a section to be at least x bytes, so we should make that clear in the error message. Signed-off-by: Janosch Frank <frankja@linux.ibm.com> Reviewed-by: Eugene Syromyatnikov <evgsyr@gmail.com>
-rw-r--r--s390.c28
-rw-r--r--tests/s390_sthyi.c30
2 files changed, 30 insertions, 28 deletions
diff --git a/s390.c b/s390.c
index 54ece4b98..a02d1884a 100644
--- a/s390.c
+++ b/s390.c
@@ -592,7 +592,7 @@ static void
print_sthyi_partition(struct tcb *tcp, struct sthyi_partition *hdr,
uint16_t size, bool *mt)
{
- size_t last_decoded = offsetofend(typeof(*hdr), infplgif);
+ size_t last_decoded = offsetofend(typeof(*hdr), infpabif);
int cnt_val, wcap_val, acap_val, id_val, lpar_val;
*mt = false;
@@ -662,18 +662,20 @@ print_sthyi_partition(struct tcb *tcp, struct sthyi_partition *hdr,
if (acap_val || hdr->infpabif)
PRINT_FIELD_WEIGHT(", ", *hdr, infpabif);
- if (!IS_ARRAY_ZERO(hdr->infplgnm)) {
- PRINT_FIELD_EBCDIC(", ", *hdr, infplgnm);
-
- PRINT_FIELD_WEIGHT(", ", *hdr, infplgcp);
- PRINT_FIELD_WEIGHT(", ", *hdr, infplgif);
- } else {
- if (lpar_val)
- PRINT_FIELD_HEX_ARRAY(", ", *hdr, infplgnm);
- if (hdr->infplgcp)
- PRINT_FIELD_X(", ", *hdr, infplgcp);
- if (hdr->infplgif)
- PRINT_FIELD_X(", ", *hdr, infplgif);
+ if (size >= offsetofend(struct sthyi_partition, infplgif)) {
+ if (!IS_ARRAY_ZERO(hdr->infplgnm)) {
+ PRINT_FIELD_EBCDIC(", ", *hdr, infplgnm);
+
+ PRINT_FIELD_WEIGHT(", ", *hdr, infplgcp);
+ PRINT_FIELD_WEIGHT(", ", *hdr, infplgif);
+ } else {
+ if (lpar_val)
+ PRINT_FIELD_HEX_ARRAY(", ", *hdr, infplgnm);
+ if (hdr->infplgcp)
+ PRINT_FIELD_X(", ", *hdr, infplgcp);
+ if (hdr->infplgif)
+ PRINT_FIELD_X(", ", *hdr, infplgif);
+ }
}
if (size >= offsetofend(struct sthyi_partition, infpplnm)) {
diff --git a/tests/s390_sthyi.c b/tests/s390_sthyi.c
index 96c54d967..48c3dda79 100644
--- a/tests/s390_sthyi.c
+++ b/tests/s390_sthyi.c
@@ -509,7 +509,7 @@ print_sthyi(unsigned char *buf)
hdr_size = *(uint16_t *) (buf + 10);
if (hdr_size < 44)
error_msg_and_fail("sthyi: header section is too small "
- "(got %hu, 44 expected)", hdr_size);
+ "(got %hu, >=44 expected)", hdr_size);
/* INFHFLG1 */
print_0x8("{/* header */ {infhflg1", buf, 0, true);
@@ -598,7 +598,7 @@ print_sthyi(unsigned char *buf)
hdr_size = *(uint16_t *) (buf + 14);
if (hdr_size < 60)
error_msg_and_fail("sthyi: machine section is too small "
- "(got %hu, 60 expected)", hdr_size);
+ "(got %hu, >=60 expected)", hdr_size);
cur = buf + offs;
@@ -670,9 +670,9 @@ partition_hdr:
goto hv_hdr;
hdr_size = *(uint16_t *) (buf + 18);
- if (hdr_size < 56)
+ if (hdr_size < 40)
error_msg_and_fail("sthyi: partition section is too small "
- "(got %hu, 56 expected)", hdr_size);
+ "(got %hu, >=40 expected)", hdr_size);
cur = buf + offs;
@@ -741,18 +741,18 @@ partition_hdr:
print_weight(", infpwbif", cur, 32, pwcap_valid);
print_weight(", infpabif", cur, 36, pacap_valid);
- if (print_ebcdic(", infplgnm", cur, 40, 8, false, false)) {
-
- print_weight(", infplgcp", cur, 48, false);
- print_weight(", infplgif", cur, 52, false);
- } else {
- if (lpar_valid) {
- printf(", infplgnm=");
- print_quoted_hex((char *) (cur + 40), 8);
+ if (hdr_size >= 56) {
+ if (print_ebcdic(", infplgnm", cur, 40, 8, false, false)) {
+ print_weight(", infplgcp", cur, 48, false);
+ print_weight(", infplgif", cur, 52, false);
+ } else {
+ if (lpar_valid) {
+ printf(", infplgnm=");
+ print_quoted_hex((char *) (cur + 40), 8);
+ }
+ print_x32(", infplgcp", cur, 48, false);
+ print_x32(", infplgif", cur, 52, false);
}
-
- print_x32(", infplgcp", cur, 48, false);
- print_x32(", infplgif", cur, 52, false);
}
if (hdr_size >= 64) {