@@ -862,7 +862,7 @@ static void coalesce_peers(struct wgdevice *device)
862862 struct wgpeer * old_next_peer , * peer = device -> first_peer ;
863863
864864 while (peer && peer -> next_peer ) {
865- if (memcmp (peer -> public_key , peer -> next_peer -> public_key , WG_KEY_LEN )) {
865+ if (memcmp (peer -> public_key , peer -> next_peer -> public_key , sizeof ( peer -> public_key ) )) {
866866 peer = peer -> next_peer ;
867867 continue ;
868868 }
@@ -926,42 +926,38 @@ static int kernel_get_device(struct wgdevice **device, const char *iface)
926926#endif
927927
928928#ifdef __OpenBSD__
929- int s = -1 ;
930-
931- void
932- getsock ()
929+ static int get_dgram_socket (void )
933930{
934- if (s < 0 )
935- s = socket (AF_INET , SOCK_DGRAM , 0 );
931+ static int sock = -1 ;
932+ if (sock < 0 )
933+ sock = socket (AF_INET , SOCK_DGRAM , 0 );
934+ return sock ;
936935}
937936
938937static int kernel_get_wireguard_interfaces (struct string_list * list )
939938{
940- struct ifgroupreq ifgr ;
939+ struct ifgroupreq ifgr = { . ifgr_name = "wg" } ;
941940 struct ifg_req * ifg ;
942- size_t len = 0 ;
943- int ret = 0 ;
944-
945- getsock ();
941+ int s = get_dgram_socket (), ret = 0 ;
946942
947- bzero ( & ifgr , sizeof ( ifgr ));
948- strlcpy ( ifgr . ifgr_name , "wg" , sizeof ( ifgr . ifgr_name )) ;
943+ if ( s < 0 )
944+ return - errno ;
949945
950- if (ioctl (s , SIOCGIFGMEMB , (caddr_t )& ifgr ) == -1 )
951- return errno ;
946+ if (ioctl (s , SIOCGIFGMEMB , (caddr_t )& ifgr ) < 0 )
947+ return errno == ENOENT ? 0 : - errno ;
952948
953- len = ifgr .ifgr_len ;
954- if (( ifgr .ifgr_groups = calloc ( 1 , len )) == NULL )
955- return errno ;
956- if (ioctl (s , SIOCGIFGMEMB , (caddr_t )& ifgr ) == -1 ) {
957- ret = errno ;
949+ ifgr . ifgr_groups = calloc ( 1 , ifgr .ifgr_len ) ;
950+ if (! ifgr .ifgr_groups )
951+ return - errno ;
952+ if (ioctl (s , SIOCGIFGMEMB , (caddr_t )& ifgr ) < 0 ) {
953+ ret = - errno ;
958954 goto out ;
959955 }
960956
961- for (ifg = ifgr .ifgr_groups ; ifg && len > 0 ; ifg ++ ) {
957+ for (ifg = ifgr .ifgr_groups ; ifg && ifgr . ifgr_len > 0 ; ++ ifg ) {
962958 if ((ret = string_list_add (list , ifg -> ifgrq_member )) < 0 )
963959 goto out ;
964- len -= sizeof (struct ifg_req );
960+ ifgr . ifgr_len -= sizeof (struct ifg_req );
965961 }
966962
967963out :
@@ -971,40 +967,34 @@ static int kernel_get_wireguard_interfaces(struct string_list *list)
971967
972968static int kernel_get_device (struct wgdevice * * device , const char * iface )
973969{
974- struct wg_data_io wgdata ;
970+ struct wg_data_io wgdata = { . wgd_size = 0 } ;
975971 struct wg_interface_io * wg_iface ;
976972 struct wg_peer_io * wg_peer ;
977973 struct wg_aip_io * wg_aip ;
978-
979974 struct wgdevice * dev ;
980975 struct wgpeer * peer ;
981976 struct wgallowedip * aip ;
977+ int s = get_dgram_socket (), ret ;
982978
983- size_t size ;
984-
985- getsock ();
979+ if (s < 0 )
980+ return - errno ;
986981
987982 * device = NULL ;
988-
989983 strlcpy (wgdata .wgd_name , iface , sizeof (wgdata .wgd_name ));
990- wgdata .wgd_size = size = 0 ;
991- wgdata .wgd_mem = NULL ;
992-
993- if (ioctl (s , SIOCGWG , (caddr_t )& wgdata ) == -1 &&
994- (errno == ENOTTY || errno == EPERM ))
995- return - errno ;
996-
997- while (size < wgdata .wgd_size ) {
998- size = wgdata .wgd_size ;
999- wgdata .wgd_mem = realloc (wgdata .wgd_mem , size );
1000- if (ioctl (s , SIOCGWG , (caddr_t )& wgdata ) == -1 )
1001- return - errno ;
984+ for (size_t last_size = wgdata .wgd_size ;; last_size = wgdata .wgd_size ) {
985+ if (ioctl (s , SIOCGWG , (caddr_t )& wgdata ) < 0 )
986+ goto out ;
987+ if (last_size >= wgdata .wgd_size )
988+ break ;
989+ wgdata .wgd_mem = realloc (wgdata .wgd_mem , wgdata .wgd_size );
990+ if (!wgdata .wgd_mem )
991+ goto out ;
1002992 }
1003993
1004994 wg_iface = wgdata .wgd_mem ;
1005-
1006- if (( dev = calloc ( 1 , sizeof ( * dev ))) == NULL )
1007- return - errno ;
995+ dev = calloc ( 1 , sizeof ( * dev ));
996+ if (! dev )
997+ goto out ;
1008998 strlcpy (dev -> name , iface , sizeof (dev -> name ));
1009999
10101000 if (wg_iface -> i_flags & WG_INTERFACE_HAS_RTABLE ) {
@@ -1013,23 +1003,24 @@ static int kernel_get_device(struct wgdevice **device, const char *iface)
10131003 }
10141004
10151005 if (wg_iface -> i_flags & WG_INTERFACE_HAS_PORT ) {
1016- dev -> listen_port = ntohs ( wg_iface -> i_port ) ;
1006+ dev -> listen_port = wg_iface -> i_port ;
10171007 dev -> flags |= WGDEVICE_HAS_LISTEN_PORT ;
10181008 }
10191009
10201010 if (wg_iface -> i_flags & WG_INTERFACE_HAS_PUBLIC ) {
1021- memcpy (dev -> public_key , wg_iface -> i_public , WG_KEY_SIZE );
1011+ memcpy (dev -> public_key , wg_iface -> i_public , sizeof ( dev -> public_key ) );
10221012 dev -> flags |= WGDEVICE_HAS_PUBLIC_KEY ;
10231013 }
10241014
10251015 if (wg_iface -> i_flags & WG_INTERFACE_HAS_PRIVATE ) {
1026- memcpy (dev -> private_key , wg_iface -> i_private , WG_KEY_SIZE );
1016+ memcpy (dev -> private_key , wg_iface -> i_private , sizeof ( dev -> private_key ) );
10271017 dev -> flags |= WGDEVICE_HAS_PRIVATE_KEY ;
10281018 }
10291019
1030- for (wg_peer = wg_iface -> i_peers ; wg_peer != NULL ; wg_peer = wg_peer -> p_next ) {
1031- if ((peer = calloc (1 , sizeof (* peer ))) == NULL )
1032- return - errno ;
1020+ for (wg_peer = wg_iface -> i_peers ; wg_peer ; wg_peer = wg_peer -> p_next ) {
1021+ peer = calloc (1 , sizeof (* peer ));
1022+ if (!peer )
1023+ goto out ;
10331024
10341025 if (dev -> first_peer == NULL )
10351026 dev -> first_peer = peer ;
@@ -1038,12 +1029,12 @@ static int kernel_get_device(struct wgdevice **device, const char *iface)
10381029 dev -> last_peer = peer ;
10391030
10401031 if (wg_peer -> p_flags & WG_PEER_HAS_PUBLIC ) {
1041- memcpy (peer -> public_key , wg_peer -> p_public , WG_KEY_SIZE );
1032+ memcpy (peer -> public_key , wg_peer -> p_public , sizeof ( peer -> public_key ) );
10421033 peer -> flags |= WGPEER_HAS_PUBLIC_KEY ;
10431034 }
10441035
10451036 if (wg_peer -> p_flags & WG_PEER_HAS_PSK ) {
1046- memcpy (peer -> preshared_key , wg_peer -> p_psk , WG_KEY_SIZE );
1037+ memcpy (peer -> preshared_key , wg_peer -> p_psk , sizeof ( peer -> preshared_key ) );
10471038 peer -> flags |= WGPEER_HAS_PRESHARED_KEY ;
10481039 }
10491040
@@ -1052,19 +1043,19 @@ static int kernel_get_device(struct wgdevice **device, const char *iface)
10521043 peer -> flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL ;
10531044 }
10541045
1055- if (wg_peer -> p_flags & WG_PEER_HAS_SOCKADDR )
1056- memcpy (& peer -> endpoint .addr , & wg_peer -> p_sa ,
1057- wg_peer -> p_sa .sa_len );
1046+ if (wg_peer -> p_flags & WG_PEER_HAS_ENDPOINT && wg_peer -> p_sa .sa_len <= sizeof (peer -> endpoint .addr ))
1047+ memcpy (& peer -> endpoint .addr , & wg_peer -> p_sa , wg_peer -> p_sa .sa_len );
10581048
10591049 peer -> rx_bytes = wg_peer -> p_rxbytes ;
10601050 peer -> tx_bytes = wg_peer -> p_txbytes ;
10611051
10621052 peer -> last_handshake_time .tv_sec = wg_peer -> p_last_handshake .tv_sec ;
10631053 peer -> last_handshake_time .tv_nsec = wg_peer -> p_last_handshake .tv_nsec ;
10641054
1065- for (wg_aip = wg_peer -> p_aips ; wg_aip != NULL ; wg_aip = wg_aip -> a_next ) {
1066- if ((aip = calloc (1 , sizeof (* aip ))) == NULL )
1067- return - errno ;
1055+ for (wg_aip = wg_peer -> p_aips ; wg_aip ; wg_aip = wg_aip -> a_next ) {
1056+ aip = calloc (1 , sizeof (* aip ));
1057+ if (!aip )
1058+ goto out ;
10681059
10691060 if (peer -> first_allowedip == NULL )
10701061 peer -> first_allowedip = aip ;
@@ -1075,43 +1066,44 @@ static int kernel_get_device(struct wgdevice **device, const char *iface)
10751066 aip -> family = wg_aip -> a_af ;
10761067 if (wg_aip -> a_af == AF_INET ) {
10771068 memcpy (& aip -> ip4 , & wg_aip -> a_ipv4 , sizeof (aip -> ip4 ));
1078- aip -> cidr = wg_aip -> a_mask ;
1069+ aip -> cidr = wg_aip -> a_cidr ;
10791070 } else if (wg_aip -> a_af == AF_INET6 ) {
10801071 memcpy (& aip -> ip6 , & wg_aip -> a_ipv6 , sizeof (aip -> ip6 ));
1081- aip -> cidr = wg_aip -> a_mask ;
1072+ aip -> cidr = wg_aip -> a_cidr ;
10821073 }
10831074 }
10841075 }
1085-
10861076 * device = dev ;
1077+ errno = 0 ;
1078+ out :
1079+ ret = - errno ;
10871080 free (wgdata .wgd_mem );
1088- return 0 ;
1081+ return ret ;
10891082}
10901083
10911084static int kernel_set_device (struct wgdevice * dev )
10921085{
1093- struct wg_data_io wgdata ;
1094- struct wg_interface_io wg_iface ;
1095- struct wg_peer_io * wg_peer ;
1096- struct wg_aip_io * wg_aip ;
1097-
1086+ struct wg_data_io wgdata = { .wgd_size = 0 };
1087+ struct wg_interface_io wg_iface = { 0 };
1088+ struct wg_peer_io * wg_peer , * wg_peer_next ;
1089+ struct wg_aip_io * wg_aip , * wg_aip_next ;
10981090 struct wgpeer * peer ;
10991091 struct wgallowedip * aip ;
1092+ int s = get_dgram_socket (), ret ;
11001093
1101- getsock ();
1094+ if (s < 0 )
1095+ return - errno ;
11021096
11031097 strlcpy (wgdata .wgd_name , dev -> name , sizeof (wgdata .wgd_name ));
11041098 wgdata .wgd_mem = & wg_iface ;
11051099
1106- bzero (& wg_iface , sizeof (wg_iface ));
1107-
11081100 if (dev -> flags & WGDEVICE_HAS_PRIVATE_KEY ) {
1109- memcpy (wg_iface .i_private , dev -> private_key , WG_KEY_SIZE );
1101+ memcpy (wg_iface .i_private , dev -> private_key , sizeof ( wg_iface . i_private ) );
11101102 wg_iface .i_flags |= WG_INTERFACE_HAS_PRIVATE ;
11111103 }
11121104
11131105 if (dev -> flags & WGDEVICE_HAS_LISTEN_PORT ) {
1114- wg_iface .i_port = htons ( dev -> listen_port ) ;
1106+ wg_iface .i_port = dev -> listen_port ;
11151107 wg_iface .i_flags |= WG_INTERFACE_HAS_PORT ;
11161108 }
11171109
@@ -1124,14 +1116,15 @@ static int kernel_set_device(struct wgdevice *dev)
11241116 wg_iface .i_flags |= WG_INTERFACE_REPLACE_PEERS ;
11251117
11261118 for_each_wgpeer (dev , peer ) {
1127- if ((wg_peer = calloc (1 , sizeof (* wg_peer ))) == NULL )
1128- return - errno ;
1119+ wg_peer = calloc (1 , sizeof (* wg_peer ));
1120+ if (!wg_peer )
1121+ goto out ;
11291122
11301123 wg_peer -> p_flags = WG_PEER_HAS_PUBLIC ;
1131- memcpy (wg_peer -> p_public , peer -> public_key , WG_KEY_SIZE );
1124+ memcpy (wg_peer -> p_public , peer -> public_key , sizeof ( wg_peer -> p_public ) );
11321125
11331126 if (peer -> flags & WGPEER_HAS_PRESHARED_KEY ) {
1134- memcpy (wg_peer -> p_psk , peer -> preshared_key , WG_KEY_SIZE );
1127+ memcpy (wg_peer -> p_psk , peer -> preshared_key , sizeof ( wg_peer -> p_psk ) );
11351128 wg_peer -> p_flags |= WG_PEER_HAS_PSK ;
11361129 }
11371130
@@ -1140,10 +1133,10 @@ static int kernel_set_device(struct wgdevice *dev)
11401133 wg_peer -> p_flags |= WG_PEER_HAS_PKA ;
11411134 }
11421135
1143- if (peer -> endpoint .addr .sa_family == AF_INET ||
1144- peer -> endpoint .addr .sa_family == AF_INET6 ) {
1145- memcpy (& wg_peer -> p_sa , & peer -> endpoint .addr , peer -> endpoint .addr .sa_len );
1146- wg_peer -> p_flags |= WG_PEER_HAS_SOCKADDR ;
1136+ if (( peer -> endpoint .addr .sa_family == AF_INET || peer -> endpoint . addr . sa_family == AF_INET6 ) &&
1137+ peer -> endpoint .addr .sa_len <= sizeof ( wg_peer -> p_endpoint ) ) {
1138+ memcpy (& wg_peer -> p_endpoint , & peer -> endpoint .addr , peer -> endpoint .addr .sa_len );
1139+ wg_peer -> p_flags |= WG_PEER_HAS_ENDPOINT ;
11471140 }
11481141
11491142 if (peer -> flags & WGPEER_REPLACE_ALLOWEDIPS )
@@ -1156,30 +1149,44 @@ static int kernel_set_device(struct wgdevice *dev)
11561149 wg_iface .i_peers = wg_peer ;
11571150
11581151 for_each_wgallowedip (peer , aip ) {
1159- if ((wg_aip = calloc (1 , sizeof (* wg_aip ))) == NULL )
1160- return - errno ;
1152+ wg_aip = calloc (1 , sizeof (* wg_aip ));
1153+ if (!wg_aip )
1154+ goto out ;
11611155
11621156 wg_aip -> a_af = aip -> family ;
1163- wg_aip -> a_mask = aip -> cidr ;
1157+ wg_aip -> a_cidr = aip -> cidr ;
11641158
1165- if (aip -> family == AF_INET )
1166- memcpy (& wg_aip -> a_ipv4 , & aip -> ip4 , sizeof (aip -> ip4 ));
1167- else if (aip -> family == AF_INET6 )
1168- memcpy (& wg_aip -> a_ipv6 , & aip -> ip6 , sizeof (aip -> ip6 ));
1169- else
1170- return -1 ;
1159+ if (aip -> family == AF_INET ) {
1160+ memcpy (& wg_aip -> a_ipv4 , & aip -> ip4 , sizeof (wg_aip -> a_ipv4 ));
1161+ } else if (aip -> family == AF_INET6 ) {
1162+ memcpy (& wg_aip -> a_ipv6 , & aip -> ip6 , sizeof (wg_aip -> a_ipv6 ));
1163+ } else {
1164+ free (wg_aip );
1165+ continue ;
1166+ }
11711167
11721168 wg_aip -> a_next = wg_peer -> p_aips ;
11731169 wg_peer -> p_aips = wg_aip ;
11741170 }
11751171 }
11761172
1177- if (ioctl (s , SIOCSWG , (caddr_t )& wgdata ) == -1 )
1178- return - errno ;
1173+ if (ioctl (s , SIOCSWG , (caddr_t )& wgdata ) < 0 )
1174+ goto out ;
1175+ errno = 0 ;
11791176
1180- return 0 ;
1177+ out :
1178+ ret = - errno ;
1179+ for (wg_peer = wg_iface .i_peers ; wg_peer ; wg_peer = wg_peer_next ) {
1180+ for (wg_aip = wg_peer -> p_aips ; wg_aip ; wg_aip = wg_aip_next ) {
1181+ wg_aip_next = wg_aip -> a_next ;
1182+ free (wg_aip );
1183+ }
1184+ wg_peer_next = wg_peer -> p_next ;
1185+ free (wg_peer );
1186+ }
1187+ return ret ;
11811188}
1182- #endif /* OpenBSD */
1189+ #endif
11831190
11841191/* first\0second\0third\0forth\0last\0\0 */
11851192char * ipc_list_devices (void )
0 commit comments