mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
[bind] Return EINVAL for under sized address
...and EAFNOSUPPORT for unexpected address family. To comply with Linux. Updates #6021, #6575. PiperOrigin-RevId: 396893590
This commit is contained in:
committed by
gVisor bot
parent
2d9883e4f1
commit
149ca00967
@@ -419,6 +419,27 @@ func bytesToIPAddress(addr []byte) tcpip.Address {
|
||||
return tcpip.Address(addr)
|
||||
}
|
||||
|
||||
// minSockAddrLen returns the minimum length in bytes of a socket address for
|
||||
// the socket's family.
|
||||
func (s *socketOpsCommon) minSockAddrLen() int {
|
||||
const addressFamilySize = 2
|
||||
|
||||
switch s.family {
|
||||
case linux.AF_UNIX:
|
||||
return addressFamilySize
|
||||
case linux.AF_INET:
|
||||
return sockAddrInetSize
|
||||
case linux.AF_INET6:
|
||||
return sockAddrInet6Size
|
||||
case linux.AF_PACKET:
|
||||
return sockAddrLinkSize
|
||||
case linux.AF_UNSPEC:
|
||||
return addressFamilySize
|
||||
default:
|
||||
panic(fmt.Sprintf("s.family unrecognized = %d", s.family))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *socketOpsCommon) isPacketBased() bool {
|
||||
return s.skType == linux.SOCK_DGRAM || s.skType == linux.SOCK_SEQPACKET || s.skType == linux.SOCK_RDM || s.skType == linux.SOCK_RAW
|
||||
}
|
||||
@@ -545,16 +566,21 @@ func (s *socketOpsCommon) Readiness(mask waiter.EventMask) waiter.EventMask {
|
||||
return s.Endpoint.Readiness(mask)
|
||||
}
|
||||
|
||||
func (s *socketOpsCommon) checkFamily(family uint16, exact bool) *syserr.Error {
|
||||
// checkFamily returns true iff the specified address family may be used with
|
||||
// the socket.
|
||||
//
|
||||
// If exact is true, then the specified address family must be an exact match
|
||||
// with the socket's family.
|
||||
func (s *socketOpsCommon) checkFamily(family uint16, exact bool) bool {
|
||||
if family == uint16(s.family) {
|
||||
return nil
|
||||
return true
|
||||
}
|
||||
if !exact && family == linux.AF_INET && s.family == linux.AF_INET6 {
|
||||
if !s.Endpoint.SocketOptions().GetV6Only() {
|
||||
return nil
|
||||
return true
|
||||
}
|
||||
}
|
||||
return syserr.ErrInvalidArgument
|
||||
return false
|
||||
}
|
||||
|
||||
// mapFamily maps the AF_INET ANY address to the IPv4-mapped IPv6 ANY if the
|
||||
@@ -587,8 +613,8 @@ func (s *socketOpsCommon) Connect(t *kernel.Task, sockaddr []byte, blocking bool
|
||||
return syserr.TranslateNetstackError(err)
|
||||
}
|
||||
|
||||
if err := s.checkFamily(family, false /* exact */); err != nil {
|
||||
return err
|
||||
if !s.checkFamily(family, false /* exact */) {
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
addr = s.mapFamily(addr, family)
|
||||
|
||||
@@ -655,14 +681,18 @@ func (s *socketOpsCommon) Bind(t *kernel.Task, sockaddr []byte) *syserr.Error {
|
||||
Addr: tcpip.Address(a.HardwareAddr[:header.EthernetAddressSize]),
|
||||
}
|
||||
} else {
|
||||
if s.minSockAddrLen() > len(sockaddr) {
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
var err *syserr.Error
|
||||
addr, family, err = socket.AddressAndFamily(sockaddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = s.checkFamily(family, true /* exact */); err != nil {
|
||||
return err
|
||||
if !s.checkFamily(family, true /* exact */) {
|
||||
return syserr.ErrAddressFamilyNotSupported
|
||||
}
|
||||
|
||||
addr = s.mapFamily(addr, family)
|
||||
@@ -2872,8 +2902,8 @@ func (s *socketOpsCommon) SendMsg(t *kernel.Task, src usermem.IOSequence, to []b
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := s.checkFamily(family, false /* exact */); err != nil {
|
||||
return 0, err
|
||||
if !s.checkFamily(family, false /* exact */) {
|
||||
return 0, syserr.ErrInvalidArgument
|
||||
}
|
||||
addrBuf = s.mapFamily(addrBuf, family)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user