diff options
| author | Joe Richey joerichey@google.com <joerichey@google.com> | 2018-08-22 05:23:00 -0700 |
|---|---|---|
| committer | Joe Richey joerichey@google.com <joerichey@google.com> | 2018-08-23 11:00:34 -0700 |
| commit | 315f9b042237200174a1fb99427f74027e191d66 (patch) | |
| tree | 8451aa6f72e232ce1ebdb7d79e393f4de26cc0a6 /security/privileges.go | |
| parent | 3022c1603d968c22f147b4a2c49c4637dd1be91b (diff) | |
Ensure keyring privilege changes are reversible
This change makes sure that, when we set the ruid and euid in order to
get the user keyring linked into the current process keyring, we will
always be able to reverse these changes (using a suid of 0).
This fixes an issue where "su <user>" would result in a system error
when called by an unprivileged user. It also explains exactly how and
why we are making these privilege changes.
Diffstat (limited to 'security/privileges.go')
| -rw-r--r-- | security/privileges.go | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/security/privileges.go b/security/privileges.go index eaee808..c9bfde7 100644 --- a/security/privileges.go +++ b/security/privileges.go @@ -142,11 +142,22 @@ func SetProcessPrivileges(privs *Privileges) error { return nil } -func setUids(ruid, euid int) error { - res, err := C.setreuid(C.uid_t(ruid), C.uid_t(euid)) - log.Printf("setreuid(%d, %d) = %d (errno %v)", ruid, euid, res, err) - if res == 0 { - return nil +func setUids(ruid, euid, suid int) error { + log.Printf("Setting ruid=%d euid=%d suid=%d", ruid, euid, suid) + // We elevate the all the privs before setting them. This prevents + // issues with (ruid=1000,euid=1000,suid=0), where just a single call + // to setresuid might fail with permission denied. + if res, err := C.setresuid(0, 0, 0); res < 0 { + return errors.Wrapf(err.(syscall.Errno), "setting uids") } - return errors.Wrapf(err.(syscall.Errno), "setting uids") + if res, err := C.setresuid(C.uid_t(ruid), C.uid_t(euid), C.uid_t(suid)); res < 0 { + return errors.Wrapf(err.(syscall.Errno), "setting uids") + } + return nil +} + +func getUids() (int, int, int) { + var ruid, euid, suid C.uid_t + C.getresuid(&ruid, &euid, &suid) + return int(ruid), int(euid), int(suid) } |