Skip to content
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

cmd/go/internal/work: building Go can fail on FreeBSD due to chmod failure #19596

Closed
siebenmann opened this issue Mar 17, 2017 · 11 comments
Closed
Labels
FrozenDueToAge help wanted OS-FreeBSD Testing An issue that has been verified to require only test changes, not just a test failure.
Milestone

Comments

@siebenmann
Copy link

The current git tip will fail to build on FreeBSD under some circumstances because it attempts to make a directory in /tmp setgid and under some (possibly common) situations this will fail. The root of the issue is a FreeBSD feature where directories always behave as if they had the sticky bit set as far as mkdir(2) is concerned, per the FreeBSD mkdir(2) manpage.

How the bug happens:

  • /tmp ownership is, say, user root and group wheel.
  • you (the UID building Go) are not in group wheel
  • you mkdir /tmp/GroupSticky. Due to the FreeBSD mkdir(2) feature this new directory winds up with owner you but in group wheel, which you are not a member of.
  • you attempt to set setgid on something that is in a group that you are not a member of. FreeBSD correctly rejects this with EPERM.

There are two ways for the Go build to still succeed on FreeBSD as far as I know. The first is for the UID doing the build to be in the group that owns /tmp. The other is to set TMPDIR to a directory which you've created and that has the group owner as one of your groups; this will typically be the case if you create it under $HOME.

What version of Go are you using (go version)?

I am trying to build the latest git tip, 42e9746 as I write this. However this build failure happens as of commit e9bb9e5 which introduces this test. Reverting to 4e0f639 results in a tree that will build.

What operating system and processor architecture are you using (go env)?

GOARCH="386"
GOHOSTARCH="386"
GOHOSTOS="freebsd"
GOOS="freebsd"

What did you do?

Attempted to build Go from git tip or any version since

What did you expect to see?

Success (ignoring issue #19592 for now, which also prevents the build from succeeding).

What did you see instead?

--- FAIL: TestRespectGroupSticky (0.00s)
        build_test.go:203: chmod /tmp/GroupSticky: operation not permitted
FAIL
FAIL    cmd/go/internal/work    0.015s

This machine's /tmp and a manually created /tmp/GroupSticky directory have the ownership:

drwxrwxrwt  146 root  wheel  13824 Mar 17 16:03 /tmp/
drwxr-xr-x    2 cks   wheel    512 Mar 17 16:02 /tmp/GroupSticky/

(I am not in group wheel on this FreeBSD server; it is run by another group entirely.)

@bradfitz bradfitz added OS-FreeBSD Testing An issue that has been verified to require only test changes, not just a test failure. labels Mar 17, 2017
@bradfitz bradfitz added this to the Go1.9Maybe milestone Mar 17, 2017
@ianlancetaylor
Copy link
Contributor

I would be inclined to just skip the test on FreeBSD.

@junkblocker
Copy link

junkblocker commented Mar 30, 2017

Seeing this on Mac OS X too.

--- FAIL: TestRespectGroupSticky (0.00s)
	build_test.go:203: chmod /tmp/GroupSticky: operation not permitted
FAIL
FAIL	cmd/go/internal/work	0.015s

@preetpalS
Copy link

preetpalS commented Mar 31, 2017

The TestRespectGroupSticky test will fail whenever you cannot set setgid on a directory in os.TempDir().

Apparently normal (operating system) user accounts that are not root cannot set setgid on a directory in the os.TempDir() directory on FreeBSD, macOS, and Google NativeClient (this test might not work on other BSD operating systems either). That doesn't mean that the behavior that the test is checking for is not working on these systems but that the behavior cannot be tested due to the user doing the build lacking permissions to perform the test.

Maybe the best solution is to just skip the test whenever the build user lacks the permission to modify setgid on a directory in os.TempDir().

@mostynb
Copy link
Contributor

mostynb commented Apr 21, 2017

If you create directories two levels deep in /tmp on FreeBSD, it's possible to make the inner dir setgid without being root, if we do this then I think the test should pass there. This trick doesn't work on darwin though.

@gopherbot
Copy link

CL https://golang.org/cl/41216 mentions this issue.

gopherbot pushed a commit that referenced this issue Apr 21, 2017
FreeBSD doesn't allow non-root users to enable the SetGID bit on
files or directories in /tmp, however it does allow this in
subdirectories, so create the test directory one level deeper.

Followup to #19596.

Change-Id: I30e71c6d6a156badc863e8068df10ef6ed817e26
Reviewed-on: https://go-review.googlesource.com/41216
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
@siebenmann
Copy link
Author

Unfortunately commit e4852aa does not fix this issue because it is missing a vital step. It is not sufficient to make a directory in /tmp, make a subdirectory, and attempt to make the subdirectory setgid; this will (and does) fail, because your initial directory inherits group wheel from /tmp and then your subdirectory inherits group wheel from your directory. Instead, you must make your directory, chgrp the directory to your group, and then make the subdirectory, which will inherit the now-correct group from your directory. Alternately, once you've chgrp'd the directory in /tmp you can proceed to immediately make it setgid, since you're no longer trying to make it setgid for a group that you're not a member of.

@mostynb
Copy link
Contributor

mostynb commented Apr 21, 2017

I will finish bringing up my FreeBSD VM and test this properly. I will also try to refactor this test a little to make it work on Darwin.

@gopherbot
Copy link

CL https://golang.org/cl/41430 mentions this issue.

@mostynb
Copy link
Contributor

mostynb commented Apr 21, 2017

The change above seems to work for me on Linux, FreeBSD and Darwin (10.12.4).

@nehaljwani
Copy link
Contributor

On Darwin (10.9.5), I had to follow what @siebenmann said to make the tests pass.

@davecheney
Copy link
Contributor

@nehaljwani please open a new issue.

@golang golang locked and limited conversation to collaborators Oct 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge help wanted OS-FreeBSD Testing An issue that has been verified to require only test changes, not just a test failure.
Projects
None yet
Development

No branches or pull requests

9 participants