From f264ead9fb99b9c7627611900e7a18ba13da89f0 Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Sat, 1 Nov 2025 01:42:02 -0700 Subject: [PATCH] libsframe: make flip_header version aware Future versions of the format may have alternative representation of an FDE. As the format evolves, endian flipping of the SFrame header may need to be version aware. flip_header () now takes the SFrame version as argument and also returns SFRAME_ERR in case of error. Currently the SFrame version as argument remains unused. SFrame encoder, at the momemnt, writes the SFrame data in the most recent format version by default. libsframe/ * sframe.c (flip_header): Make version aware. (sframe_decode): Adjust usage of flip_header. (sframe_encoder_write): Likewise. --- libsframe/sframe.c | 65 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/libsframe/sframe.c b/libsframe/sframe.c index a5fc3f1fa2a..260e1047b4d 100644 --- a/libsframe/sframe.c +++ b/libsframe/sframe.c @@ -181,21 +181,37 @@ need_swapping (int endian) return 0; } -/* Flip the endianness of the SFrame header. */ +/* Flip the endianness of the SFrame header starting at BUF. + VER is the version of the SFrame data in the buffer. -static void -flip_header (sframe_header *sfheader) -{ - swap_thing (sfheader->sfh_preamble.sfp_magic); - swap_thing (sfheader->sfh_preamble.sfp_version); - swap_thing (sfheader->sfh_preamble.sfp_flags); - swap_thing (sfheader->sfh_cfa_fixed_fp_offset); - swap_thing (sfheader->sfh_cfa_fixed_ra_offset); - swap_thing (sfheader->sfh_num_fdes); - swap_thing (sfheader->sfh_num_fres); - swap_thing (sfheader->sfh_fre_len); - swap_thing (sfheader->sfh_fdeoff); - swap_thing (sfheader->sfh_freoff); + Returns SFRAME_ERR if any error. If error code is returned, the flipped + header should not be used. */ + +static int +flip_header (char *buf, uint8_t ver ATTRIBUTE_UNUSED) +{ + /* SFrame header binary format has remained the same in SFRAME_VERSION_1, + SFRAME_VERSION_2. */ + sframe_header *sfh = (sframe_header *) buf; + swap_thing (sfh->sfh_preamble.sfp_magic); + swap_thing (sfh->sfh_preamble.sfp_version); + swap_thing (sfh->sfh_preamble.sfp_flags); + swap_thing (sfh->sfh_abi_arch); + swap_thing (sfh->sfh_cfa_fixed_fp_offset); + swap_thing (sfh->sfh_cfa_fixed_ra_offset); + swap_thing (sfh->sfh_auxhdr_len); + swap_thing (sfh->sfh_num_fdes); + swap_thing (sfh->sfh_num_fres); + swap_thing (sfh->sfh_fre_len); + swap_thing (sfh->sfh_fdeoff); + swap_thing (sfh->sfh_freoff); + + /* Alert for missing functionatlity. Auxiliary header, if present, needs to + flipped based on per abi/arch semantics. */ + if (sfh->sfh_auxhdr_len) + return SFRAME_ERR; + + return 0; } /* Endian flip the SFrame FDE at BUF (buffer size provided in BUF_SIZE), given @@ -1004,15 +1020,19 @@ sframe_decode (const char *sf_buf, size_t sf_size, int *errp) return sframe_ret_set_errno (errp, SFRAME_ERR_NOMEM); memcpy (tempbuf, sf_buf, sf_size); - /* Flip the header. */ - sframe_header *ihp = (sframe_header *) tempbuf; - flip_header (ihp); + /* Flip the header first. */ + if (flip_header (tempbuf, sfp->sfp_version)) + { + sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL); + goto decode_fail_free; + } /* Flip the rest of the SFrame section data buffer. */ if (flip_sframe (tempbuf, sf_size, 0)) { - free (tempbuf); - return sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL); + sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL); + goto decode_fail_free; } + frame_buf = tempbuf; /* This buffer is malloc'd when endian flipping the contents of the input buffer are needed. Keep a reference to it so it can be free'd up @@ -2036,6 +2056,10 @@ sframe_encoder_write (sframe_encoder_ctx *encoder, * sizeof (sframe_func_desc_entry); fresz = encoder->sfe_fre_nbytes; + /* Encoder writes out data in the latest SFrame format version. */ + if (sframe_encoder_get_version (encoder) != SFRAME_VERSION) + return sframe_ret_set_errno (errp, SFRAME_ERR_VERSION_INVAL); + /* The total size of buffer is the sum of header, SFrame Function Descriptor Entries section and the FRE section. */ bufsize = hdrsize + fsz + fresz; @@ -2062,7 +2086,8 @@ sframe_encoder_write (sframe_encoder_ctx *encoder, { if (flip_sframe (encoder->sfe_data, bufsize, 1)) return sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL); - flip_header ((sframe_header*)encoder->sfe_data); + if (flip_header (encoder->sfe_data, SFRAME_VERSION)) + return sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL); } *encoded_size = bufsize; -- 2.47.3