Skip to content

Commit

Permalink
Add function preconditionIsNotBlacklistedErrno (#1201)
Browse files Browse the repository at this point in the history
Motivation:

Certain POSIX error numbers mean the NIO program is broken beyond repair and should crash. One such value is EBADF, which indicates that the file descriptor that NIO passed to the kernel is invalid for some reason. SR-11557 was discovered in part because debug builds of NIO crash for this.
I have promoted these checks from an assertion to a precondition adding a function preconditionIsNotBlacklistedErrno. Issue was raised in issue #1156

Modifications:

- Add function preconditionIsNotBlacklistedErrno to enable option to stop program execution in both debug mode and release mode if the errno is blacklisted.
- Update assertIsNotBlacklistedErrno to all preconditionIsNotBlacklistedErrno when the program is in debug mode
- Update wrapSyscallMayBlock, wrapSyscall, wrapErrorIsNullReturnCall, and close to call preconditionIsNotBlacklistedErrno in stead of assertIsNotBlacklistedErrno

Result:

Functions wrapSyscallMayBlock, wrapSyscall, wrapErrorIsNullReturnCall, and close will stop the execution in both debug mode and release mode if the errno is blacklisted.
  • Loading branch information
heidipuk authored and Lukasa committed Oct 31, 2019
1 parent 62fd872 commit bad79c5
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,8 @@ for mode in debug release; do
else
exit_code=$?
# expecting illegal instruction as it should fail with a blacklisted errno
if [[ "$mode" == "release" ]]; then
assert_equal 42 $exit_code
else
assert_equal $(( 128 + 4 )) $exit_code # 4 == SIGILL
assert_equal $(( 128 + 4 )) $exit_code # 4 == SIGILL
if [[ "$mode" == "debug" ]]; then
grep -q blacklisted\ errno "$temp_file"
fi
fi
Expand Down
12 changes: 6 additions & 6 deletions Sources/NIO/System.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ private func isBlacklistedErrno(_ code: Int32) -> Bool {
}
}

private func assertIsNotBlacklistedErrno(err: CInt, where function: StaticString) -> Void {
private func preconditionIsNotBlacklistedErrno(err: CInt, where function: StaticString) -> Void {
// strerror is documented to return "Unknown error: ..." for illegal value so it won't ever fail
assert(!isBlacklistedErrno(err), "blacklisted errno \(err) \(String(cString: strerror(err)!)) in \(function))")
precondition(!isBlacklistedErrno(err), "blacklisted errno \(err) \(String(cString: strerror(err)!)) in \(function))")
}

/* Sorry, we really try hard to not use underscored attributes. In this case however we seem to break the inlining threshold which makes a system call take twice the time, ie. we need this exception. */
Expand All @@ -125,7 +125,7 @@ internal func wrapSyscallMayBlock<T: FixedWidthInteger>(where function: StaticSt
case EWOULDBLOCK:
return .wouldBlock(0)
default:
assertIsNotBlacklistedErrno(err: err, where: function)
preconditionIsNotBlacklistedErrno(err: err, where: function)
throw IOError(errnoCode: err, function: function)
}

Expand All @@ -145,7 +145,7 @@ internal func wrapSyscall<T: FixedWidthInteger>(where function: StaticString = #
if err == EINTR {
continue
}
assertIsNotBlacklistedErrno(err: err, where: function)
preconditionIsNotBlacklistedErrno(err: err, where: function)
throw IOError(errnoCode: err, function: function)
}
return res
Expand All @@ -161,7 +161,7 @@ internal func wrapErrorIsNullReturnCall<T>(where function: StaticString = #funct
if err == EINTR {
continue
}
assertIsNotBlacklistedErrno(err: err, where: function)
preconditionIsNotBlacklistedErrno(err: err, where: function)
throw IOError(errnoCode: err, function: function)
}
return res
Expand Down Expand Up @@ -244,7 +244,7 @@ internal enum Posix {
// - https://bugs.chromium.org/p/chromium/issues/detail?id=269623
// - https://lwn.net/Articles/576478/
if err != EINTR {
assertIsNotBlacklistedErrno(err: err, where: #function)
preconditionIsNotBlacklistedErrno(err: err, where: #function)
throw IOError(errnoCode: err, function: "close")
}
}
Expand Down

0 comments on commit bad79c5

Please sign in to comment.