socket/unix: Implemented the autobind feature

If a bind call specifies addrlen as sizeof(sa_family_t) ,then the socket
is auto-bound to an abstract address. The address consists of a null byte
followed by 5 bytes in the character set [0-9a-f].

PiperOrigin-RevId: 572810162
This commit is contained in:
Andrei Vagin
2023-10-12 00:44:32 -07:00
committed by gVisor bot
parent 1f04a514e8
commit c6a583126e
3 changed files with 88 additions and 18 deletions
+11 -10
View File
@@ -211,17 +211,18 @@ func (s *Socket) Bind(t *kernel.Task, sockaddr []byte) *syserr.Error {
return syserr.ErrInvalidArgument
}
if p[0] == 0 {
// If path is empty, the socket is autobound to an abstract address.
if len(p) == 0 || p[0] == 0 {
// Abstract socket. See net/unix/af_unix.c:unix_bind_abstract().
if t.IsNetworkNamespaced() {
return syserr.ErrInvalidEndpointState
}
asn := t.AbstractSockets()
name := p[1:]
if err := asn.Bind(t, name, bep, s); err != nil {
// syserr.ErrPortInUse corresponds to EADDRINUSE.
return syserr.ErrPortInUse
p, err := asn.Bind(t, p, bep, s)
if err != nil {
return err
}
name := p[1:]
if err := s.ep.Bind(transport.Address{Addr: p}); err != nil {
asn.Remove(name, s)
return err
@@ -449,11 +450,7 @@ func extractPath(sockaddr []byte) (string, *syserr.Error) {
// The address is trimmed by GetAddress.
p := addr.Addr
if p == "" {
// Not allowed.
return "", syserr.ErrInvalidArgument
}
if p[len(p)-1] == '/' {
if len(p) > 0 && p[len(p)-1] == '/' {
// Weird, they tried to bind '/a/b/c/'?
return "", syserr.ErrIsDir
}
@@ -526,6 +523,10 @@ func extractEndpoint(t *kernel.Task, sockaddr []byte) (transport.BoundEndpoint,
if err != nil {
return nil, err
}
if path == "" {
// Not allowed.
return nil, syserr.ErrInvalidArgument
}
// Is it abstract?
if path[0] == 0 {