@@ -104,6 +104,46 @@ static int dns_check_nameserver(FAR void *arg, FAR struct sockaddr *addr,
104104 return OK ;
105105}
106106
107+ #ifdef CONFIG_NETDB_RESOLVCONF
108+ static int dns_is_valid_nameserver (FAR const struct sockaddr * addr )
109+ {
110+ #ifdef CONFIG_NET_IPv4
111+ if (addr -> sa_family == AF_INET )
112+ {
113+ FAR const struct sockaddr_in * in4 =
114+ (FAR const struct sockaddr_in * )addr ;
115+
116+ if (net_ipv4addr_cmp (in4 -> sin_addr .s_addr , INADDR_ANY ) ||
117+ net_ipv4addr_cmp (in4 -> sin_addr .s_addr , INADDR_BROADCAST ) ||
118+ IN_MULTICAST (NTOHL (in4 -> sin_addr .s_addr )))
119+ {
120+ return - EINVAL ;
121+ }
122+
123+ return OK ;
124+ }
125+ #endif
126+
127+ #ifdef CONFIG_NET_IPv6
128+ if (addr -> sa_family == AF_INET6 )
129+ {
130+ FAR const struct sockaddr_in6 * in6 =
131+ (FAR const struct sockaddr_in6 * )addr ;
132+
133+ if (IN6_IS_ADDR_UNSPECIFIED (& in6 -> sin6_addr ) ||
134+ IN6_IS_ADDR_MULTICAST (& in6 -> sin6_addr ))
135+ {
136+ return - EINVAL ;
137+ }
138+
139+ return OK ;
140+ }
141+ #endif
142+
143+ return - ENOSYS ;
144+ }
145+ #endif
146+
107147/****************************************************************************
108148 * Public Functions
109149 ****************************************************************************/
@@ -119,7 +159,7 @@ static int dns_check_nameserver(FAR void *arg, FAR struct sockaddr *addr,
119159#ifdef CONFIG_NETDB_RESOLVCONF
120160int dns_add_nameserver (FAR const struct sockaddr * addr , socklen_t addrlen )
121161{
122- FAR FILE * stream ;
162+ FAR FILE * stream = NULL ;
123163 char addrstr [DNS_MAX_ADDRSTR ];
124164 union dns_addr_u dns_addr ;
125165 FAR uint16_t * pport ;
@@ -131,32 +171,30 @@ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen)
131171#endif
132172 int ret ;
133173
134- stream = fopen (CONFIG_NETDB_RESOLVCONF_PATH , "a+" );
135- if (stream == NULL )
174+ if (addr == NULL )
136175 {
137- ret = - get_errno ();
138- nerr ("ERROR: Failed to open %s: %d\n" ,
139- CONFIG_NETDB_RESOLVCONF_PATH , ret );
140- DEBUGASSERT (ret < 0 );
141- return ret ;
176+ return - EINVAL ;
142177 }
143178
144- dns_lock ();
145-
146179#ifdef CONFIG_NET_IPv4
147180 /* Check for an IPv4 address */
148181
149182 if (addr -> sa_family == AF_INET )
150183 {
151184 if (addrlen < sizeof (struct sockaddr_in ))
152185 {
153- ret = - EINVAL ;
154- goto errout ;
186+ return - EINVAL ;
155187 }
156188 else
157189 {
158190 FAR struct sockaddr_in * in4 = (FAR struct sockaddr_in * )addr ;
159191
192+ ret = dns_is_valid_nameserver (addr );
193+ if (ret < 0 )
194+ {
195+ return ret ;
196+ }
197+
160198 copylen = sizeof (struct sockaddr_in );
161199 pport = & dns_addr .ipv4 .sin_port ;
162200 if (inet_ntop (AF_INET , & in4 -> sin_addr , addrstr ,
@@ -165,7 +203,7 @@ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen)
165203 ret = - get_errno ();
166204 nerr ("ERROR: inet_ntop failed: %d\n" , ret );
167205 DEBUGASSERT (ret < 0 );
168- goto errout ;
206+ return ret ;
169207 }
170208 }
171209 }
@@ -179,13 +217,18 @@ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen)
179217 {
180218 if (addrlen < sizeof (struct sockaddr_in6 ))
181219 {
182- ret = - EINVAL ;
183- goto errout ;
220+ return - EINVAL ;
184221 }
185222 else
186223 {
187224 FAR struct sockaddr_in6 * in6 = (FAR struct sockaddr_in6 * )addr ;
188225
226+ ret = dns_is_valid_nameserver (addr );
227+ if (ret < 0 )
228+ {
229+ return ret ;
230+ }
231+
189232 copylen = sizeof (struct sockaddr_in6 );
190233 pport = & dns_addr .ipv6 .sin6_port ;
191234 if (inet_ntop (AF_INET6 , & in6 -> sin6_addr , addrstr ,
@@ -194,18 +237,29 @@ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen)
194237 ret = - get_errno ();
195238 nerr ("ERROR: inet_ntop failed: %d\n" , ret );
196239 DEBUGASSERT (ret < 0 );
197- goto errout ;
240+ return ret ;
198241 }
199242 }
200243 }
201244 else
202245#endif
203246 {
204247 nerr ("ERROR: Unsupported family: %d\n" , addr -> sa_family );
205- ret = - ENOSYS ;
206- goto errout ;
248+ return - ENOSYS ;
249+ }
250+
251+ stream = fopen (CONFIG_NETDB_RESOLVCONF_PATH , "a+" );
252+ if (stream == NULL )
253+ {
254+ ret = - get_errno ();
255+ nerr ("ERROR: Failed to open %s: %d\n" ,
256+ CONFIG_NETDB_RESOLVCONF_PATH , ret );
257+ DEBUGASSERT (ret < 0 );
258+ return ret ;
207259 }
208260
261+ dns_lock ();
262+
209263 memcpy (& dns_addr .addr , addr , copylen );
210264
211265 /* A port number of zero means to use the default DNS server port number */
@@ -227,9 +281,7 @@ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen)
227281 ret = OK ;
228282 }
229283
230- dns_unlock ();
231- fclose (stream );
232- return ret ;
284+ goto errout ;
233285 }
234286
235287#if CONFIG_NETDB_DNSSERVER_NAMESERVERS > 1
@@ -246,6 +298,14 @@ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen)
246298
247299 fclose (stream );
248300 stream = fopen (CONFIG_NETDB_RESOLVCONF_PATH , "w" );
301+ if (stream == NULL )
302+ {
303+ ret = - get_errno ();
304+ nerr ("ERROR: Failed to open %s: %d\n" ,
305+ CONFIG_NETDB_RESOLVCONF_PATH , ret );
306+ DEBUGASSERT (ret < 0 );
307+ goto errout ;
308+ }
249309
250310 /* Write the new record to the head of the resolv.conf file. */
251311
0 commit comments