@@ -141,30 +141,41 @@ static uint8_t g_bitbucket[UNCOMP_MAXHDR];
141141 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
142142 *
143143 * Input Parameters:
144+ * iob - Pointer to the iob struct
144145 * fptr - Pointer to the beginning of the frame under construction
145146 * bptr - Output goes here. Normally this is a known offset into d_buf,
146147 * may be redirected to g_bitbucket on the case of FRAGN frames.
147- * proto - True: Copy the protocol header following the IPv6 header too.
148148 *
149149 * Returned Value:
150- * None
150+ * On success returns 0 and a negative error otherwise
151151 *
152152 ****************************************************************************/
153153
154- static void sixlowpan_uncompress_ipv6hdr (FAR uint8_t * fptr ,
155- FAR uint8_t * bptr )
154+ static int sixlowpan_uncompress_ipv6hdr (FAR struct iob_s * iob ,
155+ FAR uint8_t * fptr ,
156+ FAR uint8_t * bptr )
156157{
157158 FAR struct ipv6_hdr_s * ipv6 = (FAR struct ipv6_hdr_s * )bptr ;
159+ FAR uint8_t * endofframe = fptr + iob -> io_len ;
158160
159161 /* Put uncompressed IPv6 header in d_buf. */
160162
161163 g_frame_hdrlen += SIXLOWPAN_IPV6_HDR_LEN ;
164+
165+ if (fptr + g_frame_hdrlen + IPv6_HDRLEN > endofframe )
166+ {
167+ nerr ("ERROR: Frame too short for IPv6 header\n" );
168+ return - EINVAL ;
169+ }
170+
162171 memcpy (ipv6 , fptr + g_frame_hdrlen , IPv6_HDRLEN );
163172
164173 /* Update g_uncomp_hdrlen and g_frame_hdrlen. */
165174
166175 g_frame_hdrlen += IPv6_HDRLEN ;
167176 g_uncomp_hdrlen += IPv6_HDRLEN ;
177+
178+ return OK ;
168179}
169180
170181/****************************************************************************
@@ -174,20 +185,22 @@ static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr,
174185 * Copy the protocol header following the IPv4 header
175186 *
176187 * Input Parameters:
188+ * iob - Pointer to the iob struct
177189 * fptr - Pointer to the beginning of the frame under construction
178190 * bptr - Output goes here. Normally this is a known offset into d_buf,
179191 * may be redirected to g_bitbucket on the case of FRAGN frames.
180- * proto - True: Copy the protocol header following the IPv6 header too.
181192 *
182193 * Returned Value:
183- * The size of the protocol header that was copied.
194+ * The size of the protocol header that was copied or a negative error .
184195 *
185196 ****************************************************************************/
186197
187- static uint16_t sixlowpan_uncompress_ipv6proto (FAR uint8_t * fptr ,
188- FAR uint8_t * bptr )
198+ static int sixlowpan_uncompress_ipv6proto (FAR struct iob_s * iob ,
199+ FAR uint8_t * fptr ,
200+ FAR uint8_t * bptr )
189201{
190202 FAR struct ipv6_hdr_s * ipv6 = (FAR struct ipv6_hdr_s * )bptr ;
203+ FAR uint8_t * endofframe = fptr + iob -> io_len ;
191204 uint16_t protosize = 0 ;
192205
193206 /* Copy the following protocol header. */
@@ -200,6 +213,14 @@ static uint16_t sixlowpan_uncompress_ipv6proto(FAR uint8_t *fptr,
200213 FAR struct tcp_hdr_s * tcp =
201214 (FAR struct tcp_hdr_s * )(fptr + g_frame_hdrlen );
202215
216+ /* Check if the frame is too short */
217+
218+ if (fptr + g_frame_hdrlen + sizeof (struct tcp_hdr_s ) > endofframe )
219+ {
220+ nerr ("ERROR: Frame too short for TCP header\n" );
221+ return - EINVAL ;
222+ }
223+
203224 /* The TCP header length is encoded in the top 4 bits of the
204225 * tcpoffset field (in units of 32-bit words).
205226 */
@@ -226,14 +247,23 @@ static uint16_t sixlowpan_uncompress_ipv6proto(FAR uint8_t *fptr,
226247 return 0 ;
227248 }
228249
250+ /* Check if the TCP header exceeds the frame size */
251+
252+ if (fptr + g_frame_hdrlen + protosize > endofframe )
253+ {
254+ nerr ("ERROR: TCP header size from tcpoffset exceeds frame bounds\n" );
255+ return - EINVAL ;
256+ }
257+
229258 /* Copy the protocol header. */
230259
231260 memcpy ((FAR uint8_t * )ipv6 + g_uncomp_hdrlen , fptr + g_frame_hdrlen ,
232261 protosize );
233262
234263 g_frame_hdrlen += protosize ;
235264 g_uncomp_hdrlen += protosize ;
236- return protosize ;
265+
266+ return (int )protosize ;
237267}
238268
239269/****************************************************************************
@@ -485,7 +515,13 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
485515
486516 /* Uncompress the IPv6 header */
487517
488- sixlowpan_uncompress_ipv6hdr (fptr , bptr );
518+ ret = sixlowpan_uncompress_ipv6hdr (iob , fptr , bptr );
519+ if (ret < 0 )
520+ {
521+ nerr ("ERROR: Failed to uncompress IPv6 header: %d\n" ,
522+ ret );
523+ goto errout_with_reass ;
524+ }
489525
490526 /* A protocol header will follow the IPv6 header only on a non-
491527 * fragmented packet or on the first fragment of a fragmented
@@ -494,7 +530,15 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
494530
495531 if (!isfrag || isfrag1 )
496532 {
497- protosize = sixlowpan_uncompress_ipv6proto (fptr , bptr );
533+ ret = sixlowpan_uncompress_ipv6proto (iob , fptr , bptr );
534+ if (ret < 0 )
535+ {
536+ nerr ("ERROR: Failed to uncompress IPv6 proto header: %d\n" ,
537+ ret );
538+ goto errout_with_reass ;
539+ }
540+
541+ protosize = (uint8_t ) ret ;
498542 }
499543 }
500544 else
0 commit comments