[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:
Ghanan Gowripalan
2021-09-15 12:20:51 -07:00
committed by gVisor bot
parent 2d9883e4f1
commit 149ca00967
3 changed files with 44 additions and 24 deletions
+40 -10
View File
@@ -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)