On Sun, Mar 15, 2020 at 10:05:19PM +0100, mwilck@xxxxxxxx wrote: > From: Martin Wilck <mwilck@xxxxxxxx> > > This limits the PERSISTENT RESERVE OUT data size to max. 8192 bytes. > Reviewed-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx> > Signed-off-by: Martin Wilck <mwilck@xxxxxxxx> > --- > libmpathpersist/mpath_pr_ioctl.c | 31 +++++++++++++++++++++++++++++-- > 1 file changed, 29 insertions(+), 2 deletions(-) > > diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c > index 1a28cba7..c78e8000 100644 > --- a/libmpathpersist/mpath_pr_ioctl.c > +++ b/libmpathpersist/mpath_pr_ioctl.c > @@ -1,5 +1,6 @@ > #include <stdio.h> > #include <stdlib.h> > +#include <stddef.h> > > #include <sys/types.h> > #include <sys/stat.h> > @@ -138,38 +139,64 @@ retry : > return status; > } > > +/* > + * Helper macro to avoid overflow of prout_param_descriptor in > + * format_transportids(). Data must not be written past > + * MPATH_MAX_PARAM_LEN bytes from struct prout_param_descriptor. > + */ > +#define check_overflow(ofs, n, start, label) \ > + do { \ > + if ((ofs) + (n) + \ > + offsetof(struct prout_param_descriptor, private_buffer) \ > + > MPATH_MAX_PARAM_LEN) \ > + { \ > + (ofs) = (start); \ > + goto label; \ > + } \ > + } while(0) > + > uint32_t format_transportids(struct prout_param_descriptor *paramp) > { > unsigned int i = 0, len; > uint32_t buff_offset = 4; > - memset(paramp->private_buffer, 0, MPATH_MAX_PARAM_LEN); > + memset(paramp->private_buffer, 0, sizeof(paramp->private_buffer)); > for (i=0; i < paramp->num_transportid; i++ ) > { > + uint32_t start_offset = buff_offset; > + > + check_overflow(buff_offset, 1, start_offset, end_loop); > paramp->private_buffer[buff_offset] = (uint8_t)((paramp->trnptid_list[i]->format_code & 0xff)| > (paramp->trnptid_list[i]->protocol_id & 0xff)); > buff_offset += 1; > switch(paramp->trnptid_list[i]->protocol_id) > { > case MPATH_PROTOCOL_ID_FC: > + check_overflow(buff_offset, 7 + 8 + 8, > + start_offset, end_loop); > buff_offset += 7; > memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->n_port_name, 8); > buff_offset +=8 ; > buff_offset +=8 ; > break; > case MPATH_PROTOCOL_ID_SAS: > + check_overflow(buff_offset, 3 + 12, > + start_offset, end_loop); > buff_offset += 3; > memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->sas_address, 8); > buff_offset += 12; > break; > case MPATH_PROTOCOL_ID_ISCSI: > - buff_offset += 1; > len = (paramp->trnptid_list[i]->iscsi_name[1] & 0xff)+2; > + check_overflow(buff_offset, 1 + len, > + start_offset, end_loop); > + buff_offset += 1; > memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->iscsi_name,len); > buff_offset += len ; > break; > } > > } > +end_loop: > buff_offset -= 4; > paramp->private_buffer[0] = (unsigned char)((buff_offset >> 24) & 0xff); > paramp->private_buffer[1] = (unsigned char)((buff_offset >> 16) & 0xff); > -- > 2.25.1 -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel