aboutsummaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/cache.go41
-rw-r--r--security/keyring.go19
-rw-r--r--security/privileges.go1
3 files changed, 59 insertions, 2 deletions
diff --git a/security/cache.go b/security/cache.go
new file mode 100644
index 0000000..7002014
--- /dev/null
+++ b/security/cache.go
@@ -0,0 +1,41 @@
+/*
+ * 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"
+)
+
+// DropInodeCache instructs the kernel to clear the global cache of inodes and
+// dentries. This has the effect of making encrypted directories whose keys
+// are not present no longer accessible. Requires root privileges.
+func DropInodeCache() error {
+ log.Print("dropping page caches")
+ // See: https://www.kernel.org/doc/Documentation/sysctl/vm.txt
+ 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 clears the inodes and dentries
+ _, err = file.WriteString("2")
+ return err
+}
diff --git a/security/keyring.go b/security/keyring.go
index f75b189..ef56364 100644
--- a/security/keyring.go
+++ b/security/keyring.go
@@ -141,6 +141,13 @@ func getUserKeyringID() (int, error) {
}
keyringID := int(parsedID)
+ // For some stupid reason, a thread does not automaticaly "possess" keys
+ // in the user keyring. So we link it into the process keyring so that
+ // we will not get "permission denied" when purging or modifying keys.
+ if err := keyringLink(keyringID, unix.KEY_SPEC_PROCESS_KEYRING); err != nil {
+ return 0, err
+ }
+
keyringIDCache[euid] = keyringID
return keyringID, nil
}
@@ -151,11 +158,19 @@ func getUserKeyringID() (int, error) {
func keyringLink(keyID int, keyringID int) error {
_, err := unix.KeyctlInt(unix.KEYCTL_LINK, keyID, keyringID, 0, 0)
log.Printf("KeyctlLink(%d, %d) = %v", keyID, keyringID, err)
- return errors.Wrap(ErrKeyringLink, err.Error())
+
+ if err != nil {
+ return errors.Wrap(ErrKeyringLink, err.Error())
+ }
+ return err
}
func keyringUnlink(keyID int, keyringID int) error {
_, err := unix.KeyctlInt(unix.KEYCTL_UNLINK, keyID, keyringID, 0, 0)
log.Printf("KeyctlUnlink(%d, %d) = %v", keyID, keyringID, err)
- return errors.Wrap(ErrKeyringUnlink, err.Error())
+
+ if err != nil {
+ return errors.Wrap(ErrKeyringUnlink, err.Error())
+ }
+ return err
}
diff --git a/security/privileges.go b/security/privileges.go
index f6e8098..aff41a7 100644
--- a/security/privileges.go
+++ b/security/privileges.go
@@ -18,6 +18,7 @@
*/
// Package security manages:
+// - Cache clearing (cache.go)
// - Keyring Operations (keyring.go)
// - Privilege manipulation (privileges.go)
// - Maintaining the link between the root and user keyrings.