@@ -124,6 +124,9 @@ static Broadcast_Info *fetch_broadcast_info(const Memory *mem, const Network *ns
124124
125125#elif !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION ) && (defined(__linux__ ) || defined(__FreeBSD__ ) || defined(__DragonFly__ ))
126126
127+ non_null ()
128+ static bool ip4_is_local (const IP4 * ip4 );
129+
127130non_null ()
128131static Broadcast_Info * fetch_broadcast_info (const Memory * mem , const Network * ns )
129132{
@@ -167,7 +170,8 @@ static Broadcast_Info *fetch_broadcast_info(const Memory *mem, const Network *ns
167170 const int n = ifc .ifc_len / sizeof (struct ifreq );
168171
169172 for (int i = 0 ; i < n ; ++ i ) {
170- /* there are interfaces with are incapable of broadcast */
173+ /* there are interfaces with are incapable of broadcast
174+ * on Linux, `lo` has no broadcast address, but this function returns `>=0` */
171175 if (ioctl (net_socket_to_native (sock ), SIOCGIFBRDADDR , & i_faces [i ]) < 0 ) {
172176 continue ;
173177 }
@@ -177,18 +181,35 @@ static Broadcast_Info *fetch_broadcast_info(const Memory *mem, const Network *ns
177181 continue ;
178182 }
179183
180- const struct sockaddr_in * sock4 = (const struct sockaddr_in * )(void * )& i_faces [i ].ifr_broadaddr ;
184+ const struct sockaddr_in * broadaddr4 = (const struct sockaddr_in * )(void * )& i_faces [i ].ifr_broadaddr ;
181185
182186 if (broadcast -> count >= MAX_INTERFACES ) {
183187 break ;
184188 }
185189
186190 IP * ip = & broadcast -> ips [broadcast -> count ];
187191 ip -> family = net_family_ipv4 ();
188- ip -> ip .v4 .uint32 = sock4 -> sin_addr .s_addr ;
192+ ip -> ip .v4 .uint32 = broadaddr4 -> sin_addr .s_addr ;
189193
194+ // if no broadcast address
190195 if (ip -> ip .v4 .uint32 == 0 ) {
191- continue ;
196+ if (ioctl (net_socket_to_native (sock ), SIOCGIFADDR , & i_faces [i ]) < 0 ) {
197+ continue ;
198+ }
199+
200+ const struct sockaddr_in * addr4 = (const struct sockaddr_in * )(void * )& i_faces [i ].ifr_addr ;
201+
202+
203+ IP4 ip4_staging ;
204+ ip4_staging .uint32 = addr4 -> sin_addr .s_addr ;
205+
206+ if (ip4_is_local (& ip4_staging )) {
207+ // this is 127.x.x.x
208+ ip -> ip .v4 .uint32 = ip4_staging .uint32 ;
209+ } else {
210+ // give up.
211+ continue ;
212+ }
192213 }
193214
194215 ++ broadcast -> count ;
0 commit comments