-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
net: Moving listenerBacklog from init interferes with use of OpenBSD's pledge syscall #31927
Comments
You can add these lines before your // Force initialization of lazy sysctls in package net:
if ln, err := net.Listen("tcp", "localhost:0"); err != nil {
log.Fatal(err)
} else {
ln.Close()
} |
@bradfitz Haha, I guess that'll work for now because it's kept in a cache. Still feels like a hack though since it's relying on the underlying implementation. |
One could also argue that dropping a random system call into a random lifetime of a program is kinda hacky. Or you could counter-argue that it's a low-level thing and you know what you're doing. If so, you can also know how the net package works. You have tests, right? If OpenBSD doesn't kill your test, that's a good sign. |
Yeah fair point, it's a pretty easy thing to test for, even if only to test that the net implementation hasn't changed to no longer justify lazy init in a program. |
I'm doing to close this for now. We're not ready to commit to a supported place to make pledges but we can revisit in the future if this gets more painful or gets to be a more common request (especially over more operating systems). |
Future versions of OpenBSD should allow https://marc.info/?l=openbsd-tech&m=158069595809463&w=2 https://cvsweb.openbsd.org/src/sys/kern/kern_pledge.c?rev=1.258&content-type=text/x-cvsweb-markup |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Most likely, since the code that causes the issue is still there, but 1.12.1 is the latest version in ports for OpenBSD 6.5.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Use the
pledge(2)
system call before something which reaches line 57 ofsocket()
insrc/net/sock_posix.go
callingmaxListenerBacklog()
.What did you expect to see?
A functioning web server listening on port 8080.
What did you see instead?
Details
This is caused by @bradfitz's commit (related to #26775). The minimal example above would work fine prior to this commit.
In OpenBSD the
pledge(2)
system call is used to reduce the operating mode of the running process. It is common to reduce the permitted operations during the lifetime of the process. For example: allowing calls toread(2)
andsocket(2)
then reducing to allow onlysocket(2)
from then on out --- done through first pledging"rpath inet"
then"inet"
later. This greatly improves security during runtime and is used everywhere in OpenBSD.When
pledge(2)
is first called it immediately restricts whichsysctl(2)
information can be queried (see here). This includes disallowingkern.somaxconn
ie[CTL_KERN, KERN_SOMAXCONN]
.Before the commit above,
kern.somaxconn
would be queried during initialization and thus would not interfere with any calls topledge(2)
during run time. After the commit,kern.somaxconn
is queried insocket()
causing pledge to shoot the disobeying process in the head.This greatly restricts how
pledge(2)
can be used with certain aspects of thenet
package. For example, to bypass this issue one would need to do something like below (and still no calls topledge(2)
can happen before the call tohttp.ListenAndServe()
.I think we should opt to move the call to
maxListenerBacklog()
back into initialization. Perhaps it is possible to only have this done on OpenBSD systems where it's an issue. But I am open to other suggestions which are cleaner than my workaround above.The text was updated successfully, but these errors were encountered: