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

security: drop and regain privileges in all threads #97

Merged
merged 1 commit into from
Apr 19, 2018
Merged

security: drop and regain privileges in all threads #97

merged 1 commit into from
Apr 19, 2018

Conversation

ebiggers
Copy link
Collaborator

After enabling pam_fscrypt for "session" and creating a directory
protected with a login protector, I was no longer able to log in as that
user. The problem is that the Go runtime is creating threads after
pam_fscrypt drops privileges, but pam_fscrypt is not re-acquiring
privileges on those threads because the Go wrappers for setreuid(),
setregid(), and setgroups() in the "sys/unix" package are using the raw
syscalls which operate on the calling thread only.

This violates glibc's assumption that all threads have the same uids and
gids, causing it to abort() the process when a later module in the PAM
stack (pam_mail in my case) tries to drop privileges using the glibc
functions.

Fix it by dropping and regaining privileges using the glibc functions
rather than the "sys/unix" functions.

This also avoids any possibility that privileges could be changed in a
thread other than the "main" one for pam_fscrypt, since the Go runtime
does not guarantee which OS-level thread runs what.

It would be nice to also exit all Go worker threads before returning
from pam_fscrypt, but the Go runtime doesn't seem to support that.

After enabling pam_fscrypt for "session" and creating a directory
protected with a login protector, I was no longer able to log in as that
user.  The problem is that the Go runtime is creating threads after
pam_fscrypt drops privileges, but pam_fscrypt is not re-acquiring
privileges on those threads because the Go wrappers for setreuid(),
setregid(), and setgroups() in the "sys/unix" package are using the raw
syscalls which operate on the calling thread only.

This violates glibc's assumption that all threads have the same uids and
gids, causing it to abort() the process when a later module in the PAM
stack (pam_mail in my case) tries to drop privileges using the glibc
functions.

Fix it by dropping and regaining privileges using the glibc functions
rather than the "sys/unix" functions.

This also avoids any possibility that privileges could be changed in a
thread other than the "main" one for pam_fscrypt, since the Go runtime
does not guarantee which OS-level thread runs what.

It would be nice to also exit all Go worker threads before returning
from pam_fscrypt, but the Go runtime doesn't seem to support that.
@josephlr josephlr merged commit 3e32282 into google:master Apr 19, 2018
@ebiggers ebiggers deleted the privileges_fix branch August 22, 2018 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants