Skip to content

Commit e208a10

Browse files
boydjeffDanStough
andauthored
Prevent a nil pointer dereference segfault (#120)
* Prevent a nil pointer dereference segfault A nil pointer dereference segfault may occur when [ipv4, ipv6].NewPacketConn() is called with an argument that is nil. The four arguments to the four calls to NewPacketConn() may be nil if the functions that set them, inside the newClient() function, return a non-nil error. In newClient() there are two calls to net.ListenUDP that set uconn4 and uconn6, and two calls to net.ListenMulticastUDP that set mconn4 and mconn6. There are network scenarios where multicast may be allowed for IPv4 addresses, but not IPv6 addresses, for example. In this case the check in newClient() that returns an error, (if mconn4 == nil && mconn6 == nil), is not hit because only mconn6 is nil. Then, ipv6MulticastConn is set to nil in the returned client object. This nil value for ipv6MulticastConn is then used as an argument to ipv6.NewPacketConn in setInterface() and a nil pointer dereference segfault occurs. This PR prevents the segfault by checking that each protocol (IPv4 and IPv6) has both unicast and multicast connections. If either unicast or multicast is not present for a protocol, then both are disabled and the `use_ipv[4, 6]` flag is set to false. * Apply suggestions from code review Co-authored-by: Dan Stough <Daniel.Stough@gmail.com> --------- Co-authored-by: Dan Stough <Daniel.Stough@gmail.com>
1 parent 901c2c5 commit e208a10

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

client.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,24 +157,24 @@ func newClient(v4 bool, v6 bool, logger *log.Logger) (*client, error) {
157157
var mconn6 *net.UDPConn
158158
var err error
159159

160+
// Establish unicast connections
160161
if v4 {
161162
uconn4, err = net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
162163
if err != nil {
163164
logger.Printf("[ERR] mdns: Failed to bind to udp4 port: %v", err)
164165
}
165166
}
166-
167167
if v6 {
168168
uconn6, err = net.ListenUDP("udp6", &net.UDPAddr{IP: net.IPv6zero, Port: 0})
169169
if err != nil {
170170
logger.Printf("[ERR] mdns: Failed to bind to udp6 port: %v", err)
171171
}
172172
}
173-
174173
if uconn4 == nil && uconn6 == nil {
175174
return nil, fmt.Errorf("failed to bind to any unicast udp port")
176175
}
177176

177+
// Establish multicast connections
178178
if v4 {
179179
mconn4, err = net.ListenMulticastUDP("udp4", nil, ipv4Addr)
180180
if err != nil {
@@ -187,11 +187,28 @@ func newClient(v4 bool, v6 bool, logger *log.Logger) (*client, error) {
187187
logger.Printf("[ERR] mdns: Failed to bind to udp6 port: %v", err)
188188
}
189189
}
190-
191190
if mconn4 == nil && mconn6 == nil {
192191
return nil, fmt.Errorf("failed to bind to any multicast udp port")
193192
}
194193

194+
// Check that unicast and multicast connections have been made for IPv4 and IPv6
195+
// and disable the respective protocol if not.
196+
if uconn4 == nil || mconn4 == nil {
197+
logger.Printf("[INFO] mdns: Failed to listen to both unicast and multicast on IPv4")
198+
uconn4 = nil
199+
mconn4 = nil
200+
v4 = false
201+
}
202+
if uconn6 == nil || mconn6 == nil {
203+
logger.Printf("[INFO] mdns: Failed to listen to both unicast and multicast on IPv6")
204+
uconn6 = nil
205+
mconn6 = nil
206+
v6 = false
207+
}
208+
if !v4 && !v6 {
209+
return nil, fmt.Errorf("at least one of IPv4 and IPv6 must be enabled for querying")
210+
}
211+
195212
c := &client{
196213
use_ipv4: v4,
197214
use_ipv6: v6,

0 commit comments

Comments
 (0)