@@ -73,13 +73,13 @@ struct rfc2734_header {
7373
7474#define fwnet_get_hdr_lf (h ) (((h)->w0 & 0xc0000000) >> 30)
7575#define fwnet_get_hdr_ether_type (h ) (((h)->w0 & 0x0000ffff))
76- #define fwnet_get_hdr_dg_size (h ) (((h)->w0 & 0x0fff0000) >> 16)
76+ #define fwnet_get_hdr_dg_size (h ) (((( h)->w0 & 0x0fff0000) >> 16) + 1 )
7777#define fwnet_get_hdr_fg_off (h ) (((h)->w0 & 0x00000fff))
7878#define fwnet_get_hdr_dgl (h ) (((h)->w1 & 0xffff0000) >> 16)
7979
80- #define fwnet_set_hdr_lf (lf ) ((lf) << 30)
80+ #define fwnet_set_hdr_lf (lf ) ((lf) << 30)
8181#define fwnet_set_hdr_ether_type (et ) (et)
82- #define fwnet_set_hdr_dg_size (dgs ) ((dgs) << 16)
82+ #define fwnet_set_hdr_dg_size (dgs ) ((( dgs) - 1 ) << 16)
8383#define fwnet_set_hdr_fg_off (fgo ) (fgo)
8484
8585#define fwnet_set_hdr_dgl (dgl ) ((dgl) << 16)
@@ -578,6 +578,9 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
578578 int retval ;
579579 u16 ether_type ;
580580
581+ if (len <= RFC2374_UNFRAG_HDR_SIZE )
582+ return 0 ;
583+
581584 hdr .w0 = be32_to_cpu (buf [0 ]);
582585 lf = fwnet_get_hdr_lf (& hdr );
583586 if (lf == RFC2374_HDR_UNFRAG ) {
@@ -602,7 +605,12 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
602605 return fwnet_finish_incoming_packet (net , skb , source_node_id ,
603606 is_broadcast , ether_type );
604607 }
608+
605609 /* A datagram fragment has been received, now the fun begins. */
610+
611+ if (len <= RFC2374_FRAG_HDR_SIZE )
612+ return 0 ;
613+
606614 hdr .w1 = ntohl (buf [1 ]);
607615 buf += 2 ;
608616 len -= RFC2374_FRAG_HDR_SIZE ;
@@ -614,7 +622,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
614622 fg_off = fwnet_get_hdr_fg_off (& hdr );
615623 }
616624 datagram_label = fwnet_get_hdr_dgl (& hdr );
617- dg_size = fwnet_get_hdr_dg_size (& hdr ); /* ??? + 1 */
625+ dg_size = fwnet_get_hdr_dg_size (& hdr );
626+
627+ if (fg_off + len > dg_size )
628+ return 0 ;
618629
619630 spin_lock_irqsave (& dev -> lock , flags );
620631
@@ -722,6 +733,22 @@ static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r,
722733 fw_send_response (card , r , rcode );
723734}
724735
736+ static int gasp_source_id (__be32 * p )
737+ {
738+ return be32_to_cpu (p [0 ]) >> 16 ;
739+ }
740+
741+ static u32 gasp_specifier_id (__be32 * p )
742+ {
743+ return (be32_to_cpu (p [0 ]) & 0xffff ) << 8 |
744+ (be32_to_cpu (p [1 ]) & 0xff000000 ) >> 24 ;
745+ }
746+
747+ static u32 gasp_version (__be32 * p )
748+ {
749+ return be32_to_cpu (p [1 ]) & 0xffffff ;
750+ }
751+
725752static void fwnet_receive_broadcast (struct fw_iso_context * context ,
726753 u32 cycle , size_t header_length , void * header , void * data )
727754{
@@ -731,9 +758,6 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context,
731758 __be32 * buf_ptr ;
732759 int retval ;
733760 u32 length ;
734- u16 source_node_id ;
735- u32 specifier_id ;
736- u32 ver ;
737761 unsigned long offset ;
738762 unsigned long flags ;
739763
@@ -750,22 +774,17 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context,
750774
751775 spin_unlock_irqrestore (& dev -> lock , flags );
752776
753- specifier_id = (be32_to_cpu (buf_ptr [0 ]) & 0xffff ) << 8
754- | (be32_to_cpu (buf_ptr [1 ]) & 0xff000000 ) >> 24 ;
755- ver = be32_to_cpu (buf_ptr [1 ]) & 0xffffff ;
756- source_node_id = be32_to_cpu (buf_ptr [0 ]) >> 16 ;
757-
758- if (specifier_id == IANA_SPECIFIER_ID &&
759- (ver == RFC2734_SW_VERSION
777+ if (length > IEEE1394_GASP_HDR_SIZE &&
778+ gasp_specifier_id (buf_ptr ) == IANA_SPECIFIER_ID &&
779+ (gasp_version (buf_ptr ) == RFC2734_SW_VERSION
760780#if IS_ENABLED (CONFIG_IPV6 )
761- || ver == RFC3146_SW_VERSION
781+ || gasp_version ( buf_ptr ) == RFC3146_SW_VERSION
762782#endif
763- )) {
764- buf_ptr += 2 ;
765- length -= IEEE1394_GASP_HDR_SIZE ;
766- fwnet_incoming_packet ( dev , buf_ptr , length , source_node_id ,
783+ ))
784+ fwnet_incoming_packet ( dev , buf_ptr + 2 ,
785+ length - IEEE1394_GASP_HDR_SIZE ,
786+ gasp_source_id ( buf_ptr ) ,
767787 context -> card -> generation , true);
768- }
769788
770789 packet .payload_length = dev -> rcv_buffer_size ;
771790 packet .interrupt = 1 ;
0 commit comments