diff options
author | Zach Koopmans <zkoopmans@google.com> | 2021-05-11 17:21:24 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-05-11 17:23:08 -0700 |
commit | 49eb3da98aeb436011ec9d895727b237ec2ea93f (patch) | |
tree | 68fb13d15928380344ea101b27bdd24caaba21d6 | |
parent | f8d22292ee8a8eeecd9da9ca9355250ebbd505f7 (diff) |
[syserror] Refactor abi/linux.Errno
PiperOrigin-RevId: 373265454
-rw-r--r-- | pkg/abi/linux/BUILD | 4 | ||||
-rw-r--r-- | pkg/abi/linux/errors.go | 291 | ||||
-rw-r--r-- | pkg/sentry/socket/netlink/socket.go | 2 | ||||
-rw-r--r-- | pkg/sentry/socket/netstack/netstack.go | 2 | ||||
-rw-r--r-- | pkg/sentry/socket/socket.go | 2 | ||||
-rw-r--r-- | pkg/syserr/netstack.go | 2 | ||||
-rw-r--r-- | pkg/syserr/syserr.go | 25 |
7 files changed, 158 insertions, 170 deletions
diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index 064a54547..a461bb65e 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -85,6 +85,8 @@ go_library( go_test( name = "linux_test", size = "small", - srcs = ["netfilter_test.go"], + srcs = [ + "netfilter_test.go", + ], library = ":linux", ) diff --git a/pkg/abi/linux/errors.go b/pkg/abi/linux/errors.go index 93f85a864..b08b2687e 100644 --- a/pkg/abi/linux/errors.go +++ b/pkg/abi/linux/errors.go @@ -15,158 +15,149 @@ package linux // Errno represents a Linux errno value. -type Errno struct { - number int - name string -} - -// Number returns the errno number. -func (e *Errno) Number() int { - return e.number -} - -// String implements fmt.Stringer.String. -func (e *Errno) String() string { - return e.name -} +type Errno int // Errno values from include/uapi/asm-generic/errno-base.h. -var ( - EPERM = &Errno{1, "operation not permitted"} - ENOENT = &Errno{2, "no such file or directory"} - ESRCH = &Errno{3, "no such process"} - EINTR = &Errno{4, "interrupted system call"} - EIO = &Errno{5, "I/O error"} - ENXIO = &Errno{6, "no such device or address"} - E2BIG = &Errno{7, "argument list too long"} - ENOEXEC = &Errno{8, "exec format error"} - EBADF = &Errno{9, "bad file number"} - ECHILD = &Errno{10, "no child processes"} - EAGAIN = &Errno{11, "try again"} - ENOMEM = &Errno{12, "out of memory"} - EACCES = &Errno{13, "permission denied"} - EFAULT = &Errno{14, "bad address"} - ENOTBLK = &Errno{15, "block device required"} - EBUSY = &Errno{16, "device or resource busy"} - EEXIST = &Errno{17, "file exists"} - EXDEV = &Errno{18, "cross-device link"} - ENODEV = &Errno{19, "no such device"} - ENOTDIR = &Errno{20, "not a directory"} - EISDIR = &Errno{21, "is a directory"} - EINVAL = &Errno{22, "invalid argument"} - ENFILE = &Errno{23, "file table overflow"} - EMFILE = &Errno{24, "too many open files"} - ENOTTY = &Errno{25, "not a typewriter"} - ETXTBSY = &Errno{26, "text file busy"} - EFBIG = &Errno{27, "file too large"} - ENOSPC = &Errno{28, "no space left on device"} - ESPIPE = &Errno{29, "illegal seek"} - EROFS = &Errno{30, "read-only file system"} - EMLINK = &Errno{31, "too many links"} - EPIPE = &Errno{32, "broken pipe"} - EDOM = &Errno{33, "math argument out of domain of func"} - ERANGE = &Errno{34, "math result not representable"} +const ( + NOERRNO = iota + EPERM + ENOENT + ESRCH + EINTR + EIO + ENXIO + E2BIG + ENOEXEC + EBADF + ECHILD // 10 + EAGAIN + ENOMEM + EACCES + EFAULT + ENOTBLK + EBUSY + EEXIST + EXDEV + ENODEV + ENOTDIR // 20 + EISDIR + EINVAL + ENFILE + EMFILE + ENOTTY + ETXTBSY + EFBIG + ENOSPC + ESPIPE + EROFS // 30 + EMLINK + EPIPE + EDOM + ERANGE + // Errno values from include/uapi/asm-generic/errno.h. + EDEADLK + ENAMETOOLONG + ENOLCK + ENOSYS + ENOTEMPTY + ELOOP //40 + _ // Skip for EWOULDBLOCK = EAGAIN + ENOMSG //42 + EIDRM + ECHRNG + EL2NSYNC + EL3HLT + EL3RST + ELNRNG + EUNATCH + ENOCSI + EL2HLT // 50 + EBADE + EBADR + EXFULL + ENOANO + EBADRQC + EBADSLT + _ // Skip for EDEADLOCK = EDEADLK + EBFONT + ENOSTR // 60 + ENODATA + ETIME + ENOSR + ENONET + ENOPKG + EREMOTE + ENOLINK + EADV + ESRMNT + ECOMM // 70 + EPROTO + EMULTIHOP + EDOTDOT + EBADMSG + EOVERFLOW + ENOTUNIQ + EBADFD + EREMCHG + ELIBACC + ELIBBAD // 80 + ELIBSCN + ELIBMAX + ELIBEXEC + EILSEQ + ERESTART + ESTRPIPE + EUSERS + ENOTSOCK + EDESTADDRREQ + EMSGSIZE // 90 + EPROTOTYPE + ENOPROTOOPT + EPROTONOSUPPORT + ESOCKTNOSUPPORT + EOPNOTSUPP + EPFNOSUPPORT + EAFNOSUPPORT + EADDRINUSE + EADDRNOTAVAIL + ENETDOWN // 100 + ENETUNREACH + ENETRESET + ECONNABORTED + ECONNRESET + ENOBUFS + EISCONN + ENOTCONN + ESHUTDOWN + ETOOMANYREFS + ETIMEDOUT // 110 + ECONNREFUSED + EHOSTDOWN + EHOSTUNREACH + EALREADY + EINPROGRESS + ESTALE + EUCLEAN + ENOTNAM + ENAVAIL + EISNAM // 120 + EREMOTEIO + EDQUOT + ENOMEDIUM + EMEDIUMTYPE + ECANCELED + ENOKEY + EKEYEXPIRED + EKEYREVOKED + EKEYREJECTED + EOWNERDEAD // 130 + ENOTRECOVERABLE + ERFKILL + EHWPOISON ) -// Errno values from include/uapi/asm-generic/errno.h. -var ( - EDEADLK = &Errno{35, "resource deadlock would occur"} - ENAMETOOLONG = &Errno{36, "file name too long"} - ENOLCK = &Errno{37, "no record locks available"} - ENOSYS = &Errno{38, "invalid system call number"} - ENOTEMPTY = &Errno{39, "directory not empty"} - ELOOP = &Errno{40, "too many symbolic links encountered"} - EWOULDBLOCK = &Errno{EAGAIN.number, "operation would block"} - ENOMSG = &Errno{42, "no message of desired type"} - EIDRM = &Errno{43, "identifier removed"} - ECHRNG = &Errno{44, "channel number out of range"} - EL2NSYNC = &Errno{45, "level 2 not synchronized"} - EL3HLT = &Errno{46, "level 3 halted"} - EL3RST = &Errno{47, "level 3 reset"} - ELNRNG = &Errno{48, "link number out of range"} - EUNATCH = &Errno{49, "protocol driver not attached"} - ENOCSI = &Errno{50, "no CSI structure available"} - EL2HLT = &Errno{51, "level 2 halted"} - EBADE = &Errno{52, "invalid exchange"} - EBADR = &Errno{53, "invalid request descriptor"} - EXFULL = &Errno{54, "exchange full"} - ENOANO = &Errno{55, "no anode"} - EBADRQC = &Errno{56, "invalid request code"} - EBADSLT = &Errno{57, "invalid slot"} - EDEADLOCK = EDEADLK - EBFONT = &Errno{59, "bad font file format"} - ENOSTR = &Errno{60, "device not a stream"} - ENODATA = &Errno{61, "no data available"} - ETIME = &Errno{62, "timer expired"} - ENOSR = &Errno{63, "out of streams resources"} - ENONET = &Errno{64, "machine is not on the network"} - ENOPKG = &Errno{65, "package not installed"} - EREMOTE = &Errno{66, "object is remote"} - ENOLINK = &Errno{67, "link has been severed"} - EADV = &Errno{68, "advertise error"} - ESRMNT = &Errno{69, "srmount error"} - ECOMM = &Errno{70, "communication error on send"} - EPROTO = &Errno{71, "protocol error"} - EMULTIHOP = &Errno{72, "multihop attempted"} - EDOTDOT = &Errno{73, "RFS specific error"} - EBADMSG = &Errno{74, "not a data message"} - EOVERFLOW = &Errno{75, "value too large for defined data type"} - ENOTUNIQ = &Errno{76, "name not unique on network"} - EBADFD = &Errno{77, "file descriptor in bad state"} - EREMCHG = &Errno{78, "remote address changed"} - ELIBACC = &Errno{79, "can not access a needed shared library"} - ELIBBAD = &Errno{80, "accessing a corrupted shared library"} - ELIBSCN = &Errno{81, ".lib section in a.out corrupted"} - ELIBMAX = &Errno{82, "attempting to link in too many shared libraries"} - ELIBEXEC = &Errno{83, "cannot exec a shared library directly"} - EILSEQ = &Errno{84, "illegal byte sequence"} - ERESTART = &Errno{85, "interrupted system call should be restarted"} - ESTRPIPE = &Errno{86, "streams pipe error"} - EUSERS = &Errno{87, "too many users"} - ENOTSOCK = &Errno{88, "socket operation on non-socket"} - EDESTADDRREQ = &Errno{89, "destination address required"} - EMSGSIZE = &Errno{90, "message too long"} - EPROTOTYPE = &Errno{91, "protocol wrong type for socket"} - ENOPROTOOPT = &Errno{92, "protocol not available"} - EPROTONOSUPPORT = &Errno{93, "protocol not supported"} - ESOCKTNOSUPPORT = &Errno{94, "socket type not supported"} - EOPNOTSUPP = &Errno{95, "operation not supported on transport endpoint"} - EPFNOSUPPORT = &Errno{96, "protocol family not supported"} - EAFNOSUPPORT = &Errno{97, "address family not supported by protocol"} - EADDRINUSE = &Errno{98, "address already in use"} - EADDRNOTAVAIL = &Errno{99, "cannot assign requested address"} - ENETDOWN = &Errno{100, "network is down"} - ENETUNREACH = &Errno{101, "network is unreachable"} - ENETRESET = &Errno{102, "network dropped connection because of reset"} - ECONNABORTED = &Errno{103, "software caused connection abort"} - ECONNRESET = &Errno{104, "connection reset by peer"} - ENOBUFS = &Errno{105, "no buffer space available"} - EISCONN = &Errno{106, "transport endpoint is already connected"} - ENOTCONN = &Errno{107, "transport endpoint is not connected"} - ESHUTDOWN = &Errno{108, "cannot send after transport endpoint shutdown"} - ETOOMANYREFS = &Errno{109, "too many references: cannot splice"} - ETIMEDOUT = &Errno{110, "connection timed out"} - ECONNREFUSED = &Errno{111, "connection refused"} - EHOSTDOWN = &Errno{112, "host is down"} - EHOSTUNREACH = &Errno{113, "no route to host"} - EALREADY = &Errno{114, "operation already in progress"} - EINPROGRESS = &Errno{115, "operation now in progress"} - ESTALE = &Errno{116, "stale file handle"} - EUCLEAN = &Errno{117, "structure needs cleaning"} - ENOTNAM = &Errno{118, "not a XENIX named type file"} - ENAVAIL = &Errno{119, "no XENIX semaphores available"} - EISNAM = &Errno{120, "is a named type file"} - EREMOTEIO = &Errno{121, "remote I/O error"} - EDQUOT = &Errno{122, "quota exceeded"} - ENOMEDIUM = &Errno{123, "no medium found"} - EMEDIUMTYPE = &Errno{124, "wrong medium type"} - ECANCELED = &Errno{125, "operation Canceled"} - ENOKEY = &Errno{126, "required key not available"} - EKEYEXPIRED = &Errno{127, "key has expired"} - EKEYREVOKED = &Errno{128, "key has been revoked"} - EKEYREJECTED = &Errno{129, "key was rejected by service"} - EOWNERDEAD = &Errno{130, "owner died"} - ENOTRECOVERABLE = &Errno{131, "state not recoverable"} - ERFKILL = &Errno{132, "operation not possible due to RF-kill"} - EHWPOISON = &Errno{133, "memory page has hardware error"} +// errnos derived from other errnos +const ( + EWOULDBLOCK = EAGAIN + EDEADLOCK = EDEADLK ) diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index d75a2879f..280563d09 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -656,7 +656,7 @@ func dumpErrorMesage(hdr linux.NetlinkMessageHeader, ms *MessageSet, err *syserr Type: linux.NLMSG_ERROR, }) m.Put(&linux.NetlinkErrorMessage{ - Error: int32(-err.ToLinux().Number()), + Error: int32(-err.ToLinux()), Header: hdr, }) } diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go index 455a92e53..3fd22f936 100644 --- a/pkg/sentry/socket/netstack/netstack.go +++ b/pkg/sentry/socket/netstack/netstack.go @@ -851,7 +851,7 @@ func getSockOptSocket(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, fam return &optP, nil } - optP := primitive.Int32(syserr.TranslateNetstackError(err).ToLinux().Number()) + optP := primitive.Int32(syserr.TranslateNetstackError(err).ToLinux()) return &optP, nil case linux.SO_PEERCRED: diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index 9e56487a6..353f4ade0 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -80,7 +80,7 @@ func sockErrCmsgToLinux(sockErr *tcpip.SockError) linux.SockErrCMsg { } ee := linux.SockExtendedErr{ - Errno: uint32(syserr.TranslateNetstackError(sockErr.Err).ToLinux().Number()), + Errno: uint32(syserr.TranslateNetstackError(sockErr.Err).ToLinux()), Origin: errOriginToLinux(sockErr.Cause.Origin()), Type: sockErr.Cause.Type(), Code: sockErr.Cause.Code(), diff --git a/pkg/syserr/netstack.go b/pkg/syserr/netstack.go index 79e564de6..90be24e15 100644 --- a/pkg/syserr/netstack.go +++ b/pkg/syserr/netstack.go @@ -38,7 +38,7 @@ var ( ErrPortInUse = New((&tcpip.ErrPortInUse{}).String(), linux.EADDRINUSE) ErrBadLocalAddress = New((&tcpip.ErrBadLocalAddress{}).String(), linux.EADDRNOTAVAIL) ErrClosedForSend = New((&tcpip.ErrClosedForSend{}).String(), linux.EPIPE) - ErrClosedForReceive = New((&tcpip.ErrClosedForReceive{}).String(), nil) + ErrClosedForReceive = New((&tcpip.ErrClosedForReceive{}).String(), linux.NOERRNO) ErrTimeout = New((&tcpip.ErrTimeout{}).String(), linux.ETIMEDOUT) ErrAborted = New((&tcpip.ErrAborted{}).String(), linux.EPIPE) ErrConnectStarted = New((&tcpip.ErrConnectStarted{}).String(), linux.EINPROGRESS) diff --git a/pkg/syserr/syserr.go b/pkg/syserr/syserr.go index b5881ea3c..d70521f32 100644 --- a/pkg/syserr/syserr.go +++ b/pkg/syserr/syserr.go @@ -34,24 +34,19 @@ type Error struct { // linux.Errno. noTranslation bool - // errno is the linux.Errno this Error should be translated to. nil means - // that this Error should be translated to a nil linux.Errno. - errno *linux.Errno + // errno is the linux.Errno this Error should be translated to. + errno linux.Errno } // New creates a new Error and adds a translation for it. // // New must only be called at init. -func New(message string, linuxTranslation *linux.Errno) *Error { +func New(message string, linuxTranslation linux.Errno) *Error { err := &Error{message: message, errno: linuxTranslation} - if linuxTranslation == nil { - return err - } - // TODO(b/34162363): Remove this. - errno := linuxTranslation.Number() - if errno <= 0 || errno >= len(linuxBackwardsTranslations) { + errno := linuxTranslation + if errno < 0 || int(errno) >= len(linuxBackwardsTranslations) { panic(fmt.Sprint("invalid errno: ", errno)) } @@ -74,7 +69,7 @@ func New(message string, linuxTranslation *linux.Errno) *Error { // NewDynamic should only be used sparingly and not be used for static error // messages. Errors with static error messages should be declared with New as // global variables. -func NewDynamic(message string, linuxTranslation *linux.Errno) *Error { +func NewDynamic(message string, linuxTranslation linux.Errno) *Error { return &Error{message: message, errno: linuxTranslation} } @@ -87,7 +82,7 @@ func NewWithoutTranslation(message string) *Error { return &Error{message: message, noTranslation: true} } -func newWithHost(message string, linuxTranslation *linux.Errno, hostErrno unix.Errno) *Error { +func newWithHost(message string, linuxTranslation linux.Errno, hostErrno unix.Errno) *Error { e := New(message, linuxTranslation) addLinuxHostTranslation(hostErrno, e) return e @@ -119,10 +114,10 @@ func (e *Error) ToError() error { if e.noTranslation { panic(fmt.Sprintf("error %q does not support translation", e.message)) } - if e.errno == nil { + errno := int(e.errno) + if errno == linux.NOERRNO { return nil } - errno := e.errno.Number() if errno <= 0 || errno >= len(linuxBackwardsTranslations) || !linuxBackwardsTranslations[errno].ok { panic(fmt.Sprintf("unknown error %q (%d)", e.message, errno)) } @@ -131,7 +126,7 @@ func (e *Error) ToError() error { // ToLinux converts the Error to a Linux ABI error that can be returned to the // application. -func (e *Error) ToLinux() *linux.Errno { +func (e *Error) ToLinux() linux.Errno { if e.noTranslation { panic(fmt.Sprintf("No Linux ABI translation available for %q", e.message)) } |