diff options
| author | F. Aragon <paco@voltanet.io> | 2018-07-03 20:07:25 +0200 | 
|---|---|---|
| committer | F. Aragon <paco@voltanet.io> | 2018-07-04 00:01:22 +0200 | 
| commit | 4149ef7c0f0876a2b9fdfe34afc1ecd9036b2382 (patch) | |
| tree | 22341ea9b9bcd5bb71483cf5559f7906233690d5 /ldpd/neighbor.c | |
| parent | 7f04893904881c2822a3736d004358a0dad9f959 (diff) | |
ldpd: buffer underflow, thread safety (PVS-Studio)
This commit fixes two issues:
- memcpy() using containers of different sizes when using addr2sa(), mixing
  'struct sockaddr_storage' and 'union sockunion'.
- addr2sa() function not being thread safe (using a local static variable as
  container.
Signed-off-by: F. Aragon <paco@voltanet.io>
Diffstat (limited to 'ldpd/neighbor.c')
| -rw-r--r-- | ldpd/neighbor.c | 22 | 
1 files changed, 10 insertions, 12 deletions
diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c index 1c3f650dff..78a6131ca4 100644 --- a/ldpd/neighbor.c +++ b/ldpd/neighbor.c @@ -584,8 +584,8 @@ nbr_connect_cb(struct thread *thread)  int  nbr_establish_connection(struct nbr *nbr)  { -	struct sockaddr_storage	 local_sa; -	struct sockaddr_storage	 remote_sa; +	union sockunion		 local_su; +	union sockunion		 remote_su;  	struct adj		*adj;  	struct nbr_params	*nbrp;  #ifdef __OpenBSD__ @@ -619,16 +619,14 @@ nbr_establish_connection(struct nbr *nbr)  #endif  	} -	memcpy(&local_sa, addr2sa(nbr->af, &nbr->laddr, 0), sizeof(local_sa)); -	memcpy(&remote_sa, addr2sa(nbr->af, &nbr->raddr, LDP_PORT), -	    sizeof(local_sa)); +	addr2sa(nbr->af, &nbr->laddr, 0, &local_su); +	addr2sa(nbr->af, &nbr->raddr, LDP_PORT, &remote_su);  	if (nbr->af == AF_INET6 && nbr->raddr_scope) -		addscope((struct sockaddr_in6 *)&remote_sa, nbr->raddr_scope); +		addscope(&remote_su.sin6, nbr->raddr_scope); -	if (bind(nbr->fd, (struct sockaddr *)&local_sa, -	    sockaddr_len((struct sockaddr *)&local_sa)) == -1) { +	if (bind(nbr->fd, &local_su.sa, sockaddr_len(&local_su.sa)) == -1) {  		log_warn("%s: error while binding socket to %s", __func__, -		    log_sockaddr((struct sockaddr *)&local_sa)); +			 log_sockaddr(&local_su.sa));  		close(nbr->fd);  		return (-1);  	} @@ -646,15 +644,15 @@ nbr_establish_connection(struct nbr *nbr)  		send_hello(adj->source.type, adj->source.link.ia,  		    adj->source.target); -	if (connect(nbr->fd, (struct sockaddr *)&remote_sa, -	    sockaddr_len((struct sockaddr *)&remote_sa)) == -1) { +	if (connect(nbr->fd, &remote_su.sa, sockaddr_len(&remote_su.sa)) +	    == -1) {  		if (errno == EINPROGRESS) {  			thread_add_write(master, nbr_connect_cb, nbr, nbr->fd,  					 &nbr->ev_connect);  			return (0);  		}  		log_warn("%s: error while connecting to %s", __func__, -		    log_sockaddr((struct sockaddr *)&remote_sa)); +			 log_sockaddr(&remote_su.sa));  		close(nbr->fd);  		return (-1);  	}  | 
