mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
fuse: handle bad response errors
FUSE is supposed to receive an error code corresponding to Linux errors, but since it's running in another process we can't guarantee that. So instead of propogating a nonsensical error code (that can lead, in some cases, to panics), warn and convert the failure to EINVAL. PiperOrigin-RevId: 660274364
This commit is contained in:
committed by
gVisor bot
parent
4748786350
commit
b1ade52f24
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
// Package linuxerr contains syscall error codes exported as an error interface
|
||||
// pointers. This allows for fast comparison and return operations comperable
|
||||
// pointers. This allows for fast comparison and return operations comparable
|
||||
// to unix.Errno constants.
|
||||
package linuxerr
|
||||
|
||||
@@ -29,7 +29,7 @@ const maxErrno uint32 = errno.EHWPOISON + 1
|
||||
|
||||
// The following errors are semantically identical to Errno of type unix.Errno
|
||||
// or sycall.Errno. However, since the type are distinct ( these are
|
||||
// *errors.Error), they are not directly comperable. However, the Errno method
|
||||
// *errors.Error), they are not directly comparable. However, the Errno method
|
||||
// returns an Errno number such that the error can be compared to unix/syscall.Errno
|
||||
// (e.g. unix.Errno(EPERM.Errno()) == unix.EPERM is true). Converting unix/syscall.Errno
|
||||
// to the errors should be done via the lookup methods provided.
|
||||
@@ -355,7 +355,7 @@ func ToUnix(e *errors.Error) unix.Errno {
|
||||
return unixErr
|
||||
}
|
||||
|
||||
// Equals compars a linuxerr to a given error.
|
||||
// Equals compares a linuxerr to a given error.
|
||||
func Equals(e *errors.Error, err error) bool {
|
||||
var unixErr unix.Errno
|
||||
if e != noError {
|
||||
@@ -366,3 +366,8 @@ func Equals(e *errors.Error, err error) bool {
|
||||
}
|
||||
return e == err || unixErr == err
|
||||
}
|
||||
|
||||
// IsValid returns whether err is a valid error number.
|
||||
func IsValid(errno unix.Errno) bool {
|
||||
return errno < unix.Errno(maxErrno)
|
||||
}
|
||||
|
||||
@@ -195,7 +195,12 @@ func (r *Response) Error() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If we get a bad error in the response, warn and convert it to EINVAL.
|
||||
sysErrNo := unix.Errno(-errno)
|
||||
if !linuxerr.IsValid(sysErrNo) {
|
||||
log.Warningf("fusefs: invalid response error %d does not correspond to a Linux error", sysErrNo)
|
||||
sysErrNo = unix.Errno(unix.EINVAL)
|
||||
}
|
||||
return error(sysErrNo)
|
||||
}
|
||||
|
||||
@@ -213,7 +218,6 @@ func (r *Response) UnmarshalPayload(m marshal.Marshallable) error {
|
||||
if haveDataLen < wantDataLen {
|
||||
log.Warningf("fusefs: Payload too small. Minimum data length required: %d, but got data length %d", wantDataLen, haveDataLen)
|
||||
return linuxerr.EINVAL
|
||||
|
||||
}
|
||||
|
||||
// The response data is empty unless there is some payload. And so, doesn't
|
||||
|
||||
Reference in New Issue
Block a user