mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
vendor: vendor fscrypt integration dependencies
Signed-off-by: Marcel Lauhoff <marcel.lauhoff@suse.com>
This commit is contained in:
committed by
mergify[bot]
parent
cfea8d7562
commit
f8faffac89
49
vendor/github.com/google/fscrypt/security/cache.go
generated
vendored
Normal file
49
vendor/github.com/google/fscrypt/security/cache.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* cache.go - Handles cache clearing and management.
|
||||
*
|
||||
* Copyright 2017 Google Inc.
|
||||
* Author: Joe Richey (joerichey@google.com)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package security
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// DropFilesystemCache instructs the kernel to free the reclaimable inodes and
|
||||
// dentries. This has the effect of making encrypted directories whose keys are
|
||||
// not present no longer accessible. Requires root privileges.
|
||||
func DropFilesystemCache() error {
|
||||
// Dirty reclaimable inodes must be synced so that they will be freed.
|
||||
log.Print("syncing changes to filesystem")
|
||||
unix.Sync()
|
||||
|
||||
// See: https://www.kernel.org/doc/Documentation/sysctl/vm.txt
|
||||
log.Print("freeing reclaimable inodes and dentries")
|
||||
file, err := os.OpenFile("/proc/sys/vm/drop_caches", os.O_WRONLY|os.O_SYNC, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
// "2" just frees the reclaimable inodes and dentries. The associated
|
||||
// pages to these inodes will be freed. We do not need to free the
|
||||
// entire pagecache (as this will severely impact performance).
|
||||
_, err = file.WriteString("2")
|
||||
return err
|
||||
}
|
156
vendor/github.com/google/fscrypt/security/privileges.go
generated
vendored
Normal file
156
vendor/github.com/google/fscrypt/security/privileges.go
generated
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* privileges.go - Functions for managing users and privileges.
|
||||
*
|
||||
* Copyright 2017 Google Inc.
|
||||
* Author: Joe Richey (joerichey@google.com)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
// Package security manages:
|
||||
// - Cache clearing (cache.go)
|
||||
// - Privilege manipulation (privileges.go)
|
||||
package security
|
||||
|
||||
// Use the libc versions of setreuid, setregid, and setgroups instead of the
|
||||
// "sys/unix" versions. The "sys/unix" versions use the raw syscalls which
|
||||
// operate on the calling thread only, whereas the libc versions operate on the
|
||||
// whole process. And we need to operate on the whole process, firstly for
|
||||
// pam_fscrypt to prevent the privileges of Go worker threads from diverging
|
||||
// from the PAM stack's "main" thread, violating libc's assumption and causing
|
||||
// an abort() later in the PAM stack; and secondly because Go code may migrate
|
||||
// between OS-level threads while it's running.
|
||||
//
|
||||
// See also: https://github.com/golang/go/issues/1435
|
||||
|
||||
/*
|
||||
#define _GNU_SOURCE // for getresuid and setresuid
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h> // getting and setting uids and gids
|
||||
#include <grp.h> // setgroups
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os/user"
|
||||
"syscall"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/google/fscrypt/util"
|
||||
)
|
||||
|
||||
// Privileges encapsulate the effective uid/gid and groups of a process.
|
||||
type Privileges struct {
|
||||
euid C.uid_t
|
||||
egid C.gid_t
|
||||
groups []C.gid_t
|
||||
}
|
||||
|
||||
// ProcessPrivileges returns the process's current effective privileges.
|
||||
func ProcessPrivileges() (*Privileges, error) {
|
||||
ruid := C.getuid()
|
||||
euid := C.geteuid()
|
||||
rgid := C.getgid()
|
||||
egid := C.getegid()
|
||||
|
||||
var groups []C.gid_t
|
||||
n, err := C.getgroups(0, nil)
|
||||
if n < 0 {
|
||||
return nil, err
|
||||
}
|
||||
// If n == 0, the user isn't in any groups, so groups == nil is fine.
|
||||
if n > 0 {
|
||||
groups = make([]C.gid_t, n)
|
||||
n, err = C.getgroups(n, &groups[0])
|
||||
if n < 0 {
|
||||
return nil, err
|
||||
}
|
||||
groups = groups[:n]
|
||||
}
|
||||
log.Printf("Current privs (real, effective): uid=(%d,%d) gid=(%d,%d) groups=%v",
|
||||
ruid, euid, rgid, egid, groups)
|
||||
return &Privileges{euid, egid, groups}, nil
|
||||
}
|
||||
|
||||
// UserPrivileges returns the default privileges for the specified user.
|
||||
func UserPrivileges(user *user.User) (*Privileges, error) {
|
||||
privs := &Privileges{
|
||||
euid: C.uid_t(util.AtoiOrPanic(user.Uid)),
|
||||
egid: C.gid_t(util.AtoiOrPanic(user.Gid)),
|
||||
}
|
||||
userGroups, err := user.GroupIds()
|
||||
if err != nil {
|
||||
return nil, util.SystemError(err.Error())
|
||||
}
|
||||
privs.groups = make([]C.gid_t, len(userGroups))
|
||||
for i, group := range userGroups {
|
||||
privs.groups[i] = C.gid_t(util.AtoiOrPanic(group))
|
||||
}
|
||||
return privs, nil
|
||||
}
|
||||
|
||||
// SetProcessPrivileges sets the privileges of the current process to have those
|
||||
// specified by privs. The original privileges can be obtained by first saving
|
||||
// the output of ProcessPrivileges, calling SetProcessPrivileges with the
|
||||
// desired privs, then calling SetProcessPrivileges with the saved privs.
|
||||
func SetProcessPrivileges(privs *Privileges) error {
|
||||
log.Printf("Setting euid=%d egid=%d groups=%v", privs.euid, privs.egid, privs.groups)
|
||||
|
||||
// If setting privs as root, we need to set the euid to 0 first, so that
|
||||
// we will have the necessary permissions to make the other changes to
|
||||
// the groups/egid/euid, regardless of our original euid.
|
||||
C.seteuid(0)
|
||||
|
||||
// Separately handle the case where the user is in no groups.
|
||||
numGroups := C.size_t(len(privs.groups))
|
||||
groupsPtr := (*C.gid_t)(nil)
|
||||
if numGroups > 0 {
|
||||
groupsPtr = &privs.groups[0]
|
||||
}
|
||||
|
||||
if res, err := C.setgroups(numGroups, groupsPtr); res < 0 {
|
||||
return errors.Wrapf(err.(syscall.Errno), "setting groups")
|
||||
}
|
||||
if res, err := C.setegid(privs.egid); res < 0 {
|
||||
return errors.Wrapf(err.(syscall.Errno), "setting egid")
|
||||
}
|
||||
if res, err := C.seteuid(privs.euid); res < 0 {
|
||||
return errors.Wrapf(err.(syscall.Errno), "setting euid")
|
||||
}
|
||||
ProcessPrivileges()
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetUids sets the process's real, effective, and saved UIDs.
|
||||
func SetUids(ruid, euid, suid int) error {
|
||||
log.Printf("Setting ruid=%d euid=%d suid=%d", ruid, euid, suid)
|
||||
// We elevate 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")
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// GetUids gets the process's real, effective, and saved UIDs.
|
||||
func GetUids() (int, int, int) {
|
||||
var ruid, euid, suid C.uid_t
|
||||
C.getresuid(&ruid, &euid, &suid)
|
||||
return int(ruid), int(euid), int(suid)
|
||||
}
|
Reference in New Issue
Block a user