4040#include "bpf.h"
4141#include "logerr.h"
4242
43- const char * bpf_name = "Berkley Packet Filter" ;
43+ const char * bpf_name = "Berkeley Packet Filter" ;
4444
4545struct bpf *
4646bpf_open (const struct interface * ifp ,
@@ -138,7 +138,8 @@ bpf_read(struct bpf *bpf, void *data, size_t len)
138138{
139139 ssize_t bytes ;
140140 struct bpf_hdr packet ;
141- const char * payload ;
141+ size_t hdr_max ;
142+ const uint8_t * payload ;
142143
143144 bpf -> bpf_flags &= ~BPF_EOF ;
144145 for (;;) {
@@ -159,11 +160,22 @@ bpf_read(struct bpf *bpf, void *data, size_t len)
159160 bpf -> bpf_pos = 0 ;
160161 }
161162 bytes = -1 ;
162- payload = (const char * )bpf -> bpf_buffer + bpf -> bpf_pos ;
163+ if (bpf -> bpf_pos + sizeof (packet ) > bpf -> bpf_len ) {
164+ errno = EINVAL ;
165+ goto err ;
166+ }
167+ payload = (const uint8_t * )bpf -> bpf_buffer + bpf -> bpf_pos ;
163168 memcpy (& packet , payload , sizeof (packet ));
164- if (bpf -> bpf_pos + packet .bh_caplen + packet .bh_hdrlen >
165- bpf -> bpf_len )
166- goto next ; /* Packet beyond buffer, drop. */
169+ hdr_max = SIZE_MAX - packet .bh_caplen ;
170+ if (packet .bh_hdrlen > hdr_max ) {
171+ errno = EOVERFLOW ;
172+ goto err ;
173+ }
174+ if (packet .bh_hdrlen + packet .bh_caplen >
175+ bpf -> bpf_len - bpf -> bpf_pos ) {
176+ errno = EBADMSG ;
177+ goto err ;
178+ }
167179 payload += packet .bh_hdrlen ;
168180 if (packet .bh_caplen > len )
169181 bytes = (ssize_t )len ;
@@ -174,7 +186,6 @@ bpf_read(struct bpf *bpf, void *data, size_t len)
174186 else
175187 bpf -> bpf_flags &= ~BPF_BCAST ;
176188 memcpy (data , payload , (size_t )bytes );
177- next :
178189 bpf -> bpf_pos += BPF_WORDALIGN (
179190 packet .bh_hdrlen + packet .bh_caplen );
180191 if (bpf -> bpf_pos >= bpf -> bpf_len ) {
@@ -186,6 +197,11 @@ bpf_read(struct bpf *bpf, void *data, size_t len)
186197 }
187198
188199 /* NOTREACHED */
200+
201+ err :
202+ bpf -> bpf_len = bpf -> bpf_pos = 0 ;
203+ bpf -> bpf_flags |= BPF_EOF ;
204+ return -1 ;
189205}
190206
191207int
0 commit comments