Linux v3.12-11097-ga5d6e63
- Drop all the keys-* patches because they were merged upstream. Yay!
This commit is contained in:
parent
464a3b8218
commit
4ef7d96463
@ -20,12 +20,6 @@ https://dev.openwrt.org/browser/trunk/package/mac80211/patches/552-ath9k_rx_dma_
|
|||||||
- Fedora secure boot support.
|
- Fedora secure boot support.
|
||||||
- Dear Matthew, this is your fault. Run sed already and get a new set out.
|
- Dear Matthew, this is your fault. Run sed already and get a new set out.
|
||||||
|
|
||||||
* keys-expand-keyring.patch
|
|
||||||
* keys-krb-support.patch
|
|
||||||
* keys-x509-improv.patch
|
|
||||||
* keyring-quota.patch
|
|
||||||
- I believe these are all now queued for 3.13 in James Morris' tree.
|
|
||||||
|
|
||||||
**** Other stuff that should go upstream (in decreasing likelyhood) ************
|
**** Other stuff that should go upstream (in decreasing likelyhood) ************
|
||||||
|
|
||||||
* defaults-acpi-video.patch
|
* defaults-acpi-video.patch
|
||||||
|
@ -2247,6 +2247,8 @@ CONFIG_TIFM_7XX1=m
|
|||||||
CONFIG_TCG_TPM=m
|
CONFIG_TCG_TPM=m
|
||||||
CONFIG_TCG_TIS=m
|
CONFIG_TCG_TIS=m
|
||||||
# CONFIG_TCG_TIS_I2C_INFINEON is not set
|
# CONFIG_TCG_TIS_I2C_INFINEON is not set
|
||||||
|
# CONFIG_TCG_TIS_I2C_ATMEL is not set
|
||||||
|
# CONFIG_TCG_TIS_I2C_NUVOTON is not set
|
||||||
CONFIG_TCG_NSC=m
|
CONFIG_TCG_NSC=m
|
||||||
CONFIG_TCG_ATMEL=m
|
CONFIG_TCG_ATMEL=m
|
||||||
# CONFIG_TCG_INFINEON is not set
|
# CONFIG_TCG_INFINEON is not set
|
||||||
|
18
kernel.spec
18
kernel.spec
@ -95,7 +95,7 @@ Summary: The Linux kernel
|
|||||||
# The rc snapshot level
|
# The rc snapshot level
|
||||||
%define rcrev 0
|
%define rcrev 0
|
||||||
# The git snapshot level
|
# The git snapshot level
|
||||||
%define gitrev 10
|
%define gitrev 11
|
||||||
# Set rpm version accordingly
|
# Set rpm version accordingly
|
||||||
%define rpmversion 3.%{upstream_sublevel}.0
|
%define rpmversion 3.%{upstream_sublevel}.0
|
||||||
%endif
|
%endif
|
||||||
@ -634,12 +634,6 @@ Patch800: crash-driver.patch
|
|||||||
|
|
||||||
# crypto/
|
# crypto/
|
||||||
|
|
||||||
# keys
|
|
||||||
Patch900: keys-expand-keyring.patch
|
|
||||||
Patch901: keys-krb-support.patch
|
|
||||||
Patch902: keys-x509-improv.patch
|
|
||||||
Patch903: keyring-quota.patch
|
|
||||||
|
|
||||||
# secure boot
|
# secure boot
|
||||||
Patch1000: secure-modules.patch
|
Patch1000: secure-modules.patch
|
||||||
Patch1001: modsign-uefi.patch
|
Patch1001: modsign-uefi.patch
|
||||||
@ -1337,12 +1331,6 @@ ApplyPatch crash-driver.patch
|
|||||||
|
|
||||||
# crypto/
|
# crypto/
|
||||||
|
|
||||||
# keys
|
|
||||||
ApplyPatch keys-expand-keyring.patch
|
|
||||||
ApplyPatch keys-krb-support.patch
|
|
||||||
ApplyPatch keys-x509-improv.patch
|
|
||||||
ApplyPatch keyring-quota.patch
|
|
||||||
|
|
||||||
# secure boot
|
# secure boot
|
||||||
ApplyPatch secure-modules.patch
|
ApplyPatch secure-modules.patch
|
||||||
ApplyPatch modsign-uefi.patch
|
ApplyPatch modsign-uefi.patch
|
||||||
@ -2210,6 +2198,10 @@ fi
|
|||||||
# ||----w |
|
# ||----w |
|
||||||
# || ||
|
# || ||
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Nov 22 2013 Josh Boyer <jwboyer@fedoraproject.org> - 3.13.0-0.rc0.git11.1
|
||||||
|
- Linux v3.12-11097-ga5d6e63
|
||||||
|
- Drop all the keys-* patches because they were merged upstream. Yay!
|
||||||
|
|
||||||
* Thu Nov 21 2013 Peter Robinson <pbrobinson@fedoraproject.org>
|
* Thu Nov 21 2013 Peter Robinson <pbrobinson@fedoraproject.org>
|
||||||
- Some minor ARM config updates
|
- Some minor ARM config updates
|
||||||
|
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
commit cb3bd4d9775d833501826832fd1562af19f8182d
|
|
||||||
Author: David Howells <dhowells@redhat.com>
|
|
||||||
Date: Fri Oct 18 17:30:30 2013 +0100
|
|
||||||
|
|
||||||
KEYS: Fix keyring quota misaccounting on key replacement and unlink
|
|
||||||
|
|
||||||
If a key is displaced from a keyring by a matching one, then four more bytes
|
|
||||||
of quota are allocated to the keyring - despite the fact that the keyring does
|
|
||||||
not change in size.
|
|
||||||
|
|
||||||
Further, when a key is unlinked from a keyring, the four bytes of quota
|
|
||||||
allocated the link isn't recovered and returned to the user's pool.
|
|
||||||
|
|
||||||
The first can be tested by repeating:
|
|
||||||
|
|
||||||
keyctl add big_key a fred @s
|
|
||||||
cat /proc/key-users
|
|
||||||
|
|
||||||
(Don't put it in a shell loop otherwise the garbage collector won't have time
|
|
||||||
to clear the displaced keys, thus affecting the result).
|
|
||||||
|
|
||||||
This was causing the kerberos keyring to run out of room fairly quickly.
|
|
||||||
|
|
||||||
The second can be tested by:
|
|
||||||
|
|
||||||
cat /proc/key-users
|
|
||||||
a=`keyctl add user a a @s`
|
|
||||||
cat /proc/key-users
|
|
||||||
keyctl unlink $a
|
|
||||||
sleep 1 # Give RCU a chance to delete the key
|
|
||||||
cat /proc/key-users
|
|
||||||
|
|
||||||
assuming no system activity that otherwise adds/removes keys, the amount of
|
|
||||||
key data allocated should go up (say 40/20000 -> 47/20000) and then return to
|
|
||||||
the original value at the end.
|
|
||||||
|
|
||||||
Reported-by: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
|
|
||||||
index 8c05ebd..d80311e 100644
|
|
||||||
--- a/security/keys/keyring.c
|
|
||||||
+++ b/security/keys/keyring.c
|
|
||||||
@@ -1063,12 +1063,6 @@ int __key_link_begin(struct key *keyring,
|
|
||||||
if (index_key->type == &key_type_keyring)
|
|
||||||
down_write(&keyring_serialise_link_sem);
|
|
||||||
|
|
||||||
- /* check that we aren't going to overrun the user's quota */
|
|
||||||
- ret = key_payload_reserve(keyring,
|
|
||||||
- keyring->datalen + KEYQUOTA_LINK_BYTES);
|
|
||||||
- if (ret < 0)
|
|
||||||
- goto error_sem;
|
|
||||||
-
|
|
||||||
/* Create an edit script that will insert/replace the key in the
|
|
||||||
* keyring tree.
|
|
||||||
*/
|
|
||||||
@@ -1078,17 +1072,25 @@ int __key_link_begin(struct key *keyring,
|
|
||||||
NULL);
|
|
||||||
if (IS_ERR(edit)) {
|
|
||||||
ret = PTR_ERR(edit);
|
|
||||||
- goto error_quota;
|
|
||||||
+ goto error_sem;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* If we're not replacing a link in-place then we're going to need some
|
|
||||||
+ * extra quota.
|
|
||||||
+ */
|
|
||||||
+ if (!edit->dead_leaf) {
|
|
||||||
+ ret = key_payload_reserve(keyring,
|
|
||||||
+ keyring->datalen + KEYQUOTA_LINK_BYTES);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ goto error_cancel;
|
|
||||||
}
|
|
||||||
|
|
||||||
*_edit = edit;
|
|
||||||
kleave(" = 0");
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
-error_quota:
|
|
||||||
- /* undo the quota changes */
|
|
||||||
- key_payload_reserve(keyring,
|
|
||||||
- keyring->datalen - KEYQUOTA_LINK_BYTES);
|
|
||||||
+error_cancel:
|
|
||||||
+ assoc_array_cancel_edit(edit);
|
|
||||||
error_sem:
|
|
||||||
if (index_key->type == &key_type_keyring)
|
|
||||||
up_write(&keyring_serialise_link_sem);
|
|
||||||
@@ -1146,7 +1148,7 @@ void __key_link_end(struct key *keyring,
|
|
||||||
if (index_key->type == &key_type_keyring)
|
|
||||||
up_write(&keyring_serialise_link_sem);
|
|
||||||
|
|
||||||
- if (edit) {
|
|
||||||
+ if (edit && !edit->dead_leaf) {
|
|
||||||
key_payload_reserve(keyring,
|
|
||||||
keyring->datalen - KEYQUOTA_LINK_BYTES);
|
|
||||||
assoc_array_cancel_edit(edit);
|
|
||||||
@@ -1243,6 +1245,7 @@ int key_unlink(struct key *keyring, struct key *key)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
assoc_array_apply_edit(edit);
|
|
||||||
+ key_payload_reserve(keyring, keyring->datalen - KEYQUOTA_LINK_BYTES);
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
error:
|
|
File diff suppressed because it is too large
Load Diff
@ -1,748 +0,0 @@
|
|||||||
From d7ccdaa17aab12a49f5e9e327b55167c4af26bf8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Howells <dhowells@redhat.com>
|
|
||||||
Date: Fri, 30 Aug 2013 15:37:54 +0100
|
|
||||||
Subject: [PATCH 1/2] KEYS: Implement a big key type that can save to tmpfs
|
|
||||||
|
|
||||||
Implement a big key type that can save its contents to tmpfs and thus
|
|
||||||
swapspace when memory is tight. This is useful for Kerberos ticket caches.
|
|
||||||
|
|
||||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
|
||||||
Tested-by: Simo Sorce <simo@redhat.com>
|
|
||||||
---
|
|
||||||
include/keys/big_key-type.h | 25 ++++++
|
|
||||||
include/linux/key.h | 1 +
|
|
||||||
security/keys/Kconfig | 11 +++
|
|
||||||
security/keys/Makefile | 1 +
|
|
||||||
security/keys/big_key.c | 204 ++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
5 files changed, 242 insertions(+)
|
|
||||||
create mode 100644 include/keys/big_key-type.h
|
|
||||||
create mode 100644 security/keys/big_key.c
|
|
||||||
|
|
||||||
diff --git a/include/keys/big_key-type.h b/include/keys/big_key-type.h
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..d69bc8a
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/include/keys/big_key-type.h
|
|
||||||
@@ -0,0 +1,25 @@
|
|
||||||
+/* Big capacity key type.
|
|
||||||
+ *
|
|
||||||
+ * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
|
|
||||||
+ * Written by David Howells (dhowells@redhat.com)
|
|
||||||
+ *
|
|
||||||
+ * This program is free software; you can redistribute it and/or
|
|
||||||
+ * modify it under the terms of the GNU General Public License
|
|
||||||
+ * as published by the Free Software Foundation; either version
|
|
||||||
+ * 2 of the License, or (at your option) any later version.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifndef _KEYS_BIG_KEY_TYPE_H
|
|
||||||
+#define _KEYS_BIG_KEY_TYPE_H
|
|
||||||
+
|
|
||||||
+#include <linux/key-type.h>
|
|
||||||
+
|
|
||||||
+extern struct key_type key_type_big_key;
|
|
||||||
+
|
|
||||||
+extern int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep);
|
|
||||||
+extern void big_key_revoke(struct key *key);
|
|
||||||
+extern void big_key_destroy(struct key *key);
|
|
||||||
+extern void big_key_describe(const struct key *big_key, struct seq_file *m);
|
|
||||||
+extern long big_key_read(const struct key *key, char __user *buffer, size_t buflen);
|
|
||||||
+
|
|
||||||
+#endif /* _KEYS_BIG_KEY_TYPE_H */
|
|
||||||
diff --git a/include/linux/key.h b/include/linux/key.h
|
|
||||||
index 2417f78..010dbb6 100644
|
|
||||||
--- a/include/linux/key.h
|
|
||||||
+++ b/include/linux/key.h
|
|
||||||
@@ -201,6 +201,7 @@ struct key {
|
|
||||||
unsigned long value;
|
|
||||||
void __rcu *rcudata;
|
|
||||||
void *data;
|
|
||||||
+ void *data2[2];
|
|
||||||
} payload;
|
|
||||||
struct assoc_array keys;
|
|
||||||
};
|
|
||||||
diff --git a/security/keys/Kconfig b/security/keys/Kconfig
|
|
||||||
index 15e0dfe..b563622 100644
|
|
||||||
--- a/security/keys/Kconfig
|
|
||||||
+++ b/security/keys/Kconfig
|
|
||||||
@@ -20,6 +20,17 @@ config KEYS
|
|
||||||
|
|
||||||
If you are unsure as to whether this is required, answer N.
|
|
||||||
|
|
||||||
+config BIG_KEYS
|
|
||||||
+ tristate "Large payload keys"
|
|
||||||
+ depends on KEYS
|
|
||||||
+ depends on TMPFS
|
|
||||||
+ help
|
|
||||||
+ This option provides support for holding large keys within the kernel
|
|
||||||
+ (for example Kerberos ticket caches). The data may be stored out to
|
|
||||||
+ swapspace by tmpfs.
|
|
||||||
+
|
|
||||||
+ If you are unsure as to whether this is required, answer N.
|
|
||||||
+
|
|
||||||
config TRUSTED_KEYS
|
|
||||||
tristate "TRUSTED KEYS"
|
|
||||||
depends on KEYS && TCG_TPM
|
|
||||||
diff --git a/security/keys/Makefile b/security/keys/Makefile
|
|
||||||
index 504aaa0..c487c77 100644
|
|
||||||
--- a/security/keys/Makefile
|
|
||||||
+++ b/security/keys/Makefile
|
|
||||||
@@ -22,5 +22,6 @@ obj-$(CONFIG_SYSCTL) += sysctl.o
|
|
||||||
#
|
|
||||||
# Key types
|
|
||||||
#
|
|
||||||
+obj-$(CONFIG_BIG_KEYS) += big_key.o
|
|
||||||
obj-$(CONFIG_TRUSTED_KEYS) += trusted.o
|
|
||||||
obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted-keys/
|
|
||||||
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..5f9defc
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/security/keys/big_key.c
|
|
||||||
@@ -0,0 +1,204 @@
|
|
||||||
+/* Large capacity key type
|
|
||||||
+ *
|
|
||||||
+ * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
|
|
||||||
+ * Written by David Howells (dhowells@redhat.com)
|
|
||||||
+ *
|
|
||||||
+ * This program is free software; you can redistribute it and/or
|
|
||||||
+ * modify it under the terms of the GNU General Public Licence
|
|
||||||
+ * as published by the Free Software Foundation; either version
|
|
||||||
+ * 2 of the Licence, or (at your option) any later version.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#include <linux/module.h>
|
|
||||||
+#include <linux/init.h>
|
|
||||||
+#include <linux/seq_file.h>
|
|
||||||
+#include <linux/file.h>
|
|
||||||
+#include <linux/shmem_fs.h>
|
|
||||||
+#include <linux/err.h>
|
|
||||||
+#include <keys/user-type.h>
|
|
||||||
+#include <keys/big_key-type.h>
|
|
||||||
+
|
|
||||||
+MODULE_LICENSE("GPL");
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * If the data is under this limit, there's no point creating a shm file to
|
|
||||||
+ * hold it as the permanently resident metadata for the shmem fs will be at
|
|
||||||
+ * least as large as the data.
|
|
||||||
+ */
|
|
||||||
+#define BIG_KEY_FILE_THRESHOLD (sizeof(struct inode) + sizeof(struct dentry))
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * big_key defined keys take an arbitrary string as the description and an
|
|
||||||
+ * arbitrary blob of data as the payload
|
|
||||||
+ */
|
|
||||||
+struct key_type key_type_big_key = {
|
|
||||||
+ .name = "big_key",
|
|
||||||
+ .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
|
||||||
+ .instantiate = big_key_instantiate,
|
|
||||||
+ .match = user_match,
|
|
||||||
+ .revoke = big_key_revoke,
|
|
||||||
+ .destroy = big_key_destroy,
|
|
||||||
+ .describe = big_key_describe,
|
|
||||||
+ .read = big_key_read,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Instantiate a big key
|
|
||||||
+ */
|
|
||||||
+int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
|
|
||||||
+{
|
|
||||||
+ struct path *path = (struct path *)&key->payload.data2;
|
|
||||||
+ struct file *file;
|
|
||||||
+ ssize_t written;
|
|
||||||
+ size_t datalen = prep->datalen;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = -EINVAL;
|
|
||||||
+ if (datalen <= 0 || datalen > 1024 * 1024 || !prep->data)
|
|
||||||
+ goto error;
|
|
||||||
+
|
|
||||||
+ /* Set an arbitrary quota */
|
|
||||||
+ ret = key_payload_reserve(key, 16);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ goto error;
|
|
||||||
+
|
|
||||||
+ key->type_data.x[1] = datalen;
|
|
||||||
+
|
|
||||||
+ if (datalen > BIG_KEY_FILE_THRESHOLD) {
|
|
||||||
+ /* Create a shmem file to store the data in. This will permit the data
|
|
||||||
+ * to be swapped out if needed.
|
|
||||||
+ *
|
|
||||||
+ * TODO: Encrypt the stored data with a temporary key.
|
|
||||||
+ */
|
|
||||||
+ file = shmem_file_setup("", datalen, 0);
|
|
||||||
+ if (IS_ERR(file))
|
|
||||||
+ goto err_quota;
|
|
||||||
+
|
|
||||||
+ written = kernel_write(file, prep->data, prep->datalen, 0);
|
|
||||||
+ if (written != datalen) {
|
|
||||||
+ if (written >= 0)
|
|
||||||
+ ret = -ENOMEM;
|
|
||||||
+ goto err_fput;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Pin the mount and dentry to the key so that we can open it again
|
|
||||||
+ * later
|
|
||||||
+ */
|
|
||||||
+ *path = file->f_path;
|
|
||||||
+ path_get(path);
|
|
||||||
+ fput(file);
|
|
||||||
+ } else {
|
|
||||||
+ /* Just store the data in a buffer */
|
|
||||||
+ void *data = kmalloc(datalen, GFP_KERNEL);
|
|
||||||
+ if (!data) {
|
|
||||||
+ ret = -ENOMEM;
|
|
||||||
+ goto err_quota;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ key->payload.data = memcpy(data, prep->data, prep->datalen);
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+err_fput:
|
|
||||||
+ fput(file);
|
|
||||||
+err_quota:
|
|
||||||
+ key_payload_reserve(key, 0);
|
|
||||||
+error:
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * dispose of the links from a revoked keyring
|
|
||||||
+ * - called with the key sem write-locked
|
|
||||||
+ */
|
|
||||||
+void big_key_revoke(struct key *key)
|
|
||||||
+{
|
|
||||||
+ struct path *path = (struct path *)&key->payload.data2;
|
|
||||||
+
|
|
||||||
+ /* clear the quota */
|
|
||||||
+ key_payload_reserve(key, 0);
|
|
||||||
+ if (key_is_instantiated(key) && key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD)
|
|
||||||
+ vfs_truncate(path, 0);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * dispose of the data dangling from the corpse of a big_key key
|
|
||||||
+ */
|
|
||||||
+void big_key_destroy(struct key *key)
|
|
||||||
+{
|
|
||||||
+ if (key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD) {
|
|
||||||
+ struct path *path = (struct path *)&key->payload.data2;
|
|
||||||
+ path_put(path);
|
|
||||||
+ path->mnt = NULL;
|
|
||||||
+ path->dentry = NULL;
|
|
||||||
+ } else {
|
|
||||||
+ kfree(key->payload.data);
|
|
||||||
+ key->payload.data = NULL;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * describe the big_key key
|
|
||||||
+ */
|
|
||||||
+void big_key_describe(const struct key *key, struct seq_file *m)
|
|
||||||
+{
|
|
||||||
+ unsigned long datalen = key->type_data.x[1];
|
|
||||||
+
|
|
||||||
+ seq_puts(m, key->description);
|
|
||||||
+
|
|
||||||
+ if (key_is_instantiated(key))
|
|
||||||
+ seq_printf(m, ": %lu [%s]",
|
|
||||||
+ datalen,
|
|
||||||
+ datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff");
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * read the key data
|
|
||||||
+ * - the key's semaphore is read-locked
|
|
||||||
+ */
|
|
||||||
+long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
|
|
||||||
+{
|
|
||||||
+ unsigned long datalen = key->type_data.x[1];
|
|
||||||
+ long ret;
|
|
||||||
+
|
|
||||||
+ if (!buffer || buflen < datalen)
|
|
||||||
+ return datalen;
|
|
||||||
+
|
|
||||||
+ if (datalen > BIG_KEY_FILE_THRESHOLD) {
|
|
||||||
+ struct path *path = (struct path *)&key->payload.data2;
|
|
||||||
+ struct file *file;
|
|
||||||
+ loff_t pos;
|
|
||||||
+
|
|
||||||
+ file = dentry_open(path, O_RDONLY, current_cred());
|
|
||||||
+ if (IS_ERR(file))
|
|
||||||
+ return PTR_ERR(file);
|
|
||||||
+
|
|
||||||
+ pos = 0;
|
|
||||||
+ ret = vfs_read(file, buffer, datalen, &pos);
|
|
||||||
+ fput(file);
|
|
||||||
+ if (ret >= 0 && ret != datalen)
|
|
||||||
+ ret = -EIO;
|
|
||||||
+ } else {
|
|
||||||
+ ret = datalen;
|
|
||||||
+ if (copy_to_user(buffer, key->payload.data, datalen) != 0)
|
|
||||||
+ ret = -EFAULT;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Module stuff
|
|
||||||
+ */
|
|
||||||
+static int __init big_key_init(void)
|
|
||||||
+{
|
|
||||||
+ return register_key_type(&key_type_big_key);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __exit big_key_cleanup(void)
|
|
||||||
+{
|
|
||||||
+ unregister_key_type(&key_type_big_key);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+module_init(big_key_init);
|
|
||||||
+module_exit(big_key_cleanup);
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
||||||
|
|
||||||
From 862e98313b10123fa4352117b0b0c0f5a530cefb Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Howells <dhowells@redhat.com>
|
|
||||||
Date: Fri, 30 Aug 2013 15:37:54 +0100
|
|
||||||
Subject: [PATCH 2/2] KEYS: Add per-user_namespace registers for persistent
|
|
||||||
per-UID kerberos caches
|
|
||||||
|
|
||||||
Add support for per-user_namespace registers of persistent per-UID kerberos
|
|
||||||
caches held within the kernel.
|
|
||||||
|
|
||||||
This allows the kerberos cache to be retained beyond the life of all a user's
|
|
||||||
processes so that the user's cron jobs can work.
|
|
||||||
|
|
||||||
The kerberos cache is envisioned as a keyring/key tree looking something like:
|
|
||||||
|
|
||||||
struct user_namespace
|
|
||||||
\___ .krb_cache keyring - The register
|
|
||||||
\___ _krb.0 keyring - Root's Kerberos cache
|
|
||||||
\___ _krb.5000 keyring - User 5000's Kerberos cache
|
|
||||||
\___ _krb.5001 keyring - User 5001's Kerberos cache
|
|
||||||
\___ tkt785 big_key - A ccache blob
|
|
||||||
\___ tkt12345 big_key - Another ccache blob
|
|
||||||
|
|
||||||
Or possibly:
|
|
||||||
|
|
||||||
struct user_namespace
|
|
||||||
\___ .krb_cache keyring - The register
|
|
||||||
\___ _krb.0 keyring - Root's Kerberos cache
|
|
||||||
\___ _krb.5000 keyring - User 5000's Kerberos cache
|
|
||||||
\___ _krb.5001 keyring - User 5001's Kerberos cache
|
|
||||||
\___ tkt785 keyring - A ccache
|
|
||||||
\___ krbtgt/REDHAT.COM@REDHAT.COM big_key
|
|
||||||
\___ http/REDHAT.COM@REDHAT.COM user
|
|
||||||
\___ afs/REDHAT.COM@REDHAT.COM user
|
|
||||||
\___ nfs/REDHAT.COM@REDHAT.COM user
|
|
||||||
\___ krbtgt/KERNEL.ORG@KERNEL.ORG big_key
|
|
||||||
\___ http/KERNEL.ORG@KERNEL.ORG big_key
|
|
||||||
|
|
||||||
What goes into a particular Kerberos cache is entirely up to userspace. Kernel
|
|
||||||
support is limited to giving you the Kerberos cache keyring that you want.
|
|
||||||
|
|
||||||
The user asks for their Kerberos cache by:
|
|
||||||
|
|
||||||
krb_cache = keyctl_get_krbcache(uid, dest_keyring);
|
|
||||||
|
|
||||||
The uid is -1 or the user's own UID for the user's own cache or the uid of some
|
|
||||||
other user's cache (requires CAP_SETUID). This permits rpc.gssd or whatever to
|
|
||||||
mess with the cache.
|
|
||||||
|
|
||||||
The cache returned is a keyring named "_krb.<uid>" that the possessor can read,
|
|
||||||
search, clear, invalidate, unlink from and add links to. Active LSMs get a
|
|
||||||
chance to rule on whether the caller is permitted to make a link.
|
|
||||||
|
|
||||||
Each uid's cache keyring is created when it first accessed and is given a
|
|
||||||
timeout that is extended each time this function is called so that the keyring
|
|
||||||
goes away after a while. The timeout is configurable by sysctl but defaults to
|
|
||||||
three days.
|
|
||||||
|
|
||||||
Each user_namespace struct gets a lazily-created keyring that serves as the
|
|
||||||
register. The cache keyrings are added to it. This means that standard key
|
|
||||||
search and garbage collection facilities are available.
|
|
||||||
|
|
||||||
The user_namespace struct's register goes away when it does and anything left
|
|
||||||
in it is then automatically gc'd.
|
|
||||||
|
|
||||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
|
||||||
Tested-by: Simo Sorce <simo@redhat.com>
|
|
||||||
cc: Serge E. Hallyn <serge.hallyn@ubuntu.com>
|
|
||||||
cc: Eric W. Biederman <ebiederm@xmission.com>
|
|
||||||
---
|
|
||||||
include/linux/user_namespace.h | 7 ++
|
|
||||||
include/uapi/linux/keyctl.h | 1 +
|
|
||||||
kernel/user.c | 4 +
|
|
||||||
kernel/user_namespace.c | 6 ++
|
|
||||||
security/keys/Kconfig | 17 +++++
|
|
||||||
security/keys/Makefile | 1 +
|
|
||||||
security/keys/compat.c | 3 +
|
|
||||||
security/keys/internal.h | 9 +++
|
|
||||||
security/keys/keyctl.c | 3 +
|
|
||||||
security/keys/persistent.c | 169 +++++++++++++++++++++++++++++++++++++++++
|
|
||||||
security/keys/sysctl.c | 11 +++
|
|
||||||
11 files changed, 231 insertions(+)
|
|
||||||
create mode 100644 security/keys/persistent.c
|
|
||||||
|
|
||||||
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
|
|
||||||
index 4db2985..bb0639d 100644
|
|
||||||
--- a/include/linux/user_namespace.h
|
|
||||||
+++ b/include/linux/user_namespace.h
|
|
||||||
@@ -27,6 +27,13 @@ struct user_namespace {
|
|
||||||
kuid_t owner;
|
|
||||||
kgid_t group;
|
|
||||||
unsigned int proc_inum;
|
|
||||||
+
|
|
||||||
+ /* Register of per-UID persistent keyrings for this namespace */
|
|
||||||
+#ifdef CONFIG_PERSISTENT_KEYRINGS
|
|
||||||
+ struct key *persistent_keyring_register;
|
|
||||||
+ struct rw_semaphore persistent_keyring_register_sem;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct user_namespace init_user_ns;
|
|
||||||
diff --git a/include/uapi/linux/keyctl.h b/include/uapi/linux/keyctl.h
|
|
||||||
index c9b7f4fa..840cb99 100644
|
|
||||||
--- a/include/uapi/linux/keyctl.h
|
|
||||||
+++ b/include/uapi/linux/keyctl.h
|
|
||||||
@@ -56,5 +56,6 @@
|
|
||||||
#define KEYCTL_REJECT 19 /* reject a partially constructed key */
|
|
||||||
#define KEYCTL_INSTANTIATE_IOV 20 /* instantiate a partially constructed key */
|
|
||||||
#define KEYCTL_INVALIDATE 21 /* invalidate a key */
|
|
||||||
+#define KEYCTL_GET_PERSISTENT 22 /* get a user's persistent keyring */
|
|
||||||
|
|
||||||
#endif /* _LINUX_KEYCTL_H */
|
|
||||||
diff --git a/kernel/user.c b/kernel/user.c
|
|
||||||
index 5bbb919..a3a0dbf 100644
|
|
||||||
--- a/kernel/user.c
|
|
||||||
+++ b/kernel/user.c
|
|
||||||
@@ -51,6 +51,10 @@ struct user_namespace init_user_ns = {
|
|
||||||
.owner = GLOBAL_ROOT_UID,
|
|
||||||
.group = GLOBAL_ROOT_GID,
|
|
||||||
.proc_inum = PROC_USER_INIT_INO,
|
|
||||||
+#ifdef CONFIG_KEYS_KERBEROS_CACHE
|
|
||||||
+ .krb_cache_register_sem =
|
|
||||||
+ __RWSEM_INITIALIZER(init_user_ns.krb_cache_register_sem),
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
EXPORT_SYMBOL_GPL(init_user_ns);
|
|
||||||
|
|
||||||
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
|
|
||||||
index 13fb113..2dbc299 100644
|
|
||||||
--- a/kernel/user_namespace.c
|
|
||||||
+++ b/kernel/user_namespace.c
|
|
||||||
@@ -101,6 +101,9 @@ int create_user_ns(struct cred *new)
|
|
||||||
|
|
||||||
set_cred_user_ns(new, ns);
|
|
||||||
|
|
||||||
+#ifdef CONFIG_PERSISTENT_KEYRINGS
|
|
||||||
+ init_rwsem(&ns->persistent_keyring_register_sem);
|
|
||||||
+#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -130,6 +133,9 @@ void free_user_ns(struct user_namespace *ns)
|
|
||||||
|
|
||||||
do {
|
|
||||||
parent = ns->parent;
|
|
||||||
+#ifdef CONFIG_PERSISTENT_KEYRINGS
|
|
||||||
+ key_put(ns->persistent_keyring_register);
|
|
||||||
+#endif
|
|
||||||
proc_free_inum(ns->proc_inum);
|
|
||||||
kmem_cache_free(user_ns_cachep, ns);
|
|
||||||
ns = parent;
|
|
||||||
diff --git a/security/keys/Kconfig b/security/keys/Kconfig
|
|
||||||
index b563622..53d8748 100644
|
|
||||||
--- a/security/keys/Kconfig
|
|
||||||
+++ b/security/keys/Kconfig
|
|
||||||
@@ -20,6 +20,23 @@ config KEYS
|
|
||||||
|
|
||||||
If you are unsure as to whether this is required, answer N.
|
|
||||||
|
|
||||||
+config PERSISTENT_KEYRINGS
|
|
||||||
+ bool "Enable register of persistent per-UID keyrings"
|
|
||||||
+ depends on KEYS
|
|
||||||
+ help
|
|
||||||
+ This option provides a register of persistent per-UID keyrings,
|
|
||||||
+ primarily aimed at Kerberos key storage. The keyrings are persistent
|
|
||||||
+ in the sense that they stay around after all processes of that UID
|
|
||||||
+ have exited, not that they survive the machine being rebooted.
|
|
||||||
+
|
|
||||||
+ A particular keyring may be accessed by either the user whose keyring
|
|
||||||
+ it is or by a process with administrative privileges. The active
|
|
||||||
+ LSMs gets to rule on which admin-level processes get to access the
|
|
||||||
+ cache.
|
|
||||||
+
|
|
||||||
+ Keyrings are created and added into the register upon demand and get
|
|
||||||
+ removed if they expire (a default timeout is set upon creation).
|
|
||||||
+
|
|
||||||
config BIG_KEYS
|
|
||||||
tristate "Large payload keys"
|
|
||||||
depends on KEYS
|
|
||||||
diff --git a/security/keys/Makefile b/security/keys/Makefile
|
|
||||||
index c487c77..dfb3a7b 100644
|
|
||||||
--- a/security/keys/Makefile
|
|
||||||
+++ b/security/keys/Makefile
|
|
||||||
@@ -18,6 +18,7 @@ obj-y := \
|
|
||||||
obj-$(CONFIG_KEYS_COMPAT) += compat.o
|
|
||||||
obj-$(CONFIG_PROC_FS) += proc.o
|
|
||||||
obj-$(CONFIG_SYSCTL) += sysctl.o
|
|
||||||
+obj-$(CONFIG_PERSISTENT_KEYRINGS) += persistent.o
|
|
||||||
|
|
||||||
#
|
|
||||||
# Key types
|
|
||||||
diff --git a/security/keys/compat.c b/security/keys/compat.c
|
|
||||||
index d65fa7f..bbd32c7 100644
|
|
||||||
--- a/security/keys/compat.c
|
|
||||||
+++ b/security/keys/compat.c
|
|
||||||
@@ -138,6 +138,9 @@ asmlinkage long compat_sys_keyctl(u32 option,
|
|
||||||
case KEYCTL_INVALIDATE:
|
|
||||||
return keyctl_invalidate_key(arg2);
|
|
||||||
|
|
||||||
+ case KEYCTL_GET_PERSISTENT:
|
|
||||||
+ return keyctl_get_persistent(arg2, arg3);
|
|
||||||
+
|
|
||||||
default:
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
diff --git a/security/keys/internal.h b/security/keys/internal.h
|
|
||||||
index 581c6f6..80b2aac 100644
|
|
||||||
--- a/security/keys/internal.h
|
|
||||||
+++ b/security/keys/internal.h
|
|
||||||
@@ -255,6 +255,15 @@ extern long keyctl_invalidate_key(key_serial_t);
|
|
||||||
extern long keyctl_instantiate_key_common(key_serial_t,
|
|
||||||
const struct iovec *,
|
|
||||||
unsigned, size_t, key_serial_t);
|
|
||||||
+#ifdef CONFIG_PERSISTENT_KEYRINGS
|
|
||||||
+extern long keyctl_get_persistent(uid_t, key_serial_t);
|
|
||||||
+extern unsigned persistent_keyring_expiry;
|
|
||||||
+#else
|
|
||||||
+static inline long keyctl_get_persistent(uid_t uid, key_serial_t destring)
|
|
||||||
+{
|
|
||||||
+ return -EOPNOTSUPP;
|
|
||||||
+}
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Debugging key validation
|
|
||||||
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
|
|
||||||
index 33cfd27..cee72ce 100644
|
|
||||||
--- a/security/keys/keyctl.c
|
|
||||||
+++ b/security/keys/keyctl.c
|
|
||||||
@@ -1667,6 +1667,9 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
|
|
||||||
case KEYCTL_INVALIDATE:
|
|
||||||
return keyctl_invalidate_key((key_serial_t) arg2);
|
|
||||||
|
|
||||||
+ case KEYCTL_GET_PERSISTENT:
|
|
||||||
+ return keyctl_get_persistent((uid_t)arg2, (key_serial_t)arg3);
|
|
||||||
+
|
|
||||||
default:
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
diff --git a/security/keys/persistent.c b/security/keys/persistent.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..631a022
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/security/keys/persistent.c
|
|
||||||
@@ -0,0 +1,169 @@
|
|
||||||
+/* General persistent per-UID keyrings register
|
|
||||||
+ *
|
|
||||||
+ * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
|
|
||||||
+ * Written by David Howells (dhowells@redhat.com)
|
|
||||||
+ *
|
|
||||||
+ * This program is free software; you can redistribute it and/or
|
|
||||||
+ * modify it under the terms of the GNU General Public Licence
|
|
||||||
+ * as published by the Free Software Foundation; either version
|
|
||||||
+ * 2 of the Licence, or (at your option) any later version.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#include <linux/user_namespace.h>
|
|
||||||
+#include "internal.h"
|
|
||||||
+
|
|
||||||
+unsigned persistent_keyring_expiry = 3 * 24 * 3600; /* Expire after 3 days of non-use */
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Create the persistent keyring register for the current user namespace.
|
|
||||||
+ *
|
|
||||||
+ * Called with the namespace's sem locked for writing.
|
|
||||||
+ */
|
|
||||||
+static int key_create_persistent_register(struct user_namespace *ns)
|
|
||||||
+{
|
|
||||||
+ struct key *reg = keyring_alloc(".persistent_register",
|
|
||||||
+ KUIDT_INIT(0), KGIDT_INIT(0),
|
|
||||||
+ current_cred(),
|
|
||||||
+ ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
|
|
||||||
+ KEY_USR_VIEW | KEY_USR_READ),
|
|
||||||
+ KEY_ALLOC_NOT_IN_QUOTA, NULL);
|
|
||||||
+ if (IS_ERR(reg))
|
|
||||||
+ return PTR_ERR(reg);
|
|
||||||
+
|
|
||||||
+ ns->persistent_keyring_register = reg;
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Create the persistent keyring for the specified user.
|
|
||||||
+ *
|
|
||||||
+ * Called with the namespace's sem locked for writing.
|
|
||||||
+ */
|
|
||||||
+static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
|
|
||||||
+ struct keyring_index_key *index_key)
|
|
||||||
+{
|
|
||||||
+ struct key *persistent;
|
|
||||||
+ key_ref_t reg_ref, persistent_ref;
|
|
||||||
+
|
|
||||||
+ if (!ns->persistent_keyring_register) {
|
|
||||||
+ long err = key_create_persistent_register(ns);
|
|
||||||
+ if (err < 0)
|
|
||||||
+ return ERR_PTR(err);
|
|
||||||
+ } else {
|
|
||||||
+ reg_ref = make_key_ref(ns->persistent_keyring_register, true);
|
|
||||||
+ persistent_ref = find_key_to_update(reg_ref, index_key);
|
|
||||||
+ if (persistent_ref)
|
|
||||||
+ return persistent_ref;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ persistent = keyring_alloc(index_key->description,
|
|
||||||
+ uid, INVALID_GID, current_cred(),
|
|
||||||
+ ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
|
|
||||||
+ KEY_USR_VIEW | KEY_USR_READ),
|
|
||||||
+ KEY_ALLOC_NOT_IN_QUOTA,
|
|
||||||
+ ns->persistent_keyring_register);
|
|
||||||
+ if (IS_ERR(persistent))
|
|
||||||
+ return ERR_CAST(persistent);
|
|
||||||
+
|
|
||||||
+ return make_key_ref(persistent, true);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Get the persistent keyring for a specific UID and link it to the nominated
|
|
||||||
+ * keyring.
|
|
||||||
+ */
|
|
||||||
+static long key_get_persistent(struct user_namespace *ns, kuid_t uid,
|
|
||||||
+ key_ref_t dest_ref)
|
|
||||||
+{
|
|
||||||
+ struct keyring_index_key index_key;
|
|
||||||
+ struct key *persistent;
|
|
||||||
+ key_ref_t reg_ref, persistent_ref;
|
|
||||||
+ char buf[32];
|
|
||||||
+ long ret;
|
|
||||||
+
|
|
||||||
+ /* Look in the register if it exists */
|
|
||||||
+ index_key.type = &key_type_keyring;
|
|
||||||
+ index_key.description = buf;
|
|
||||||
+ index_key.desc_len = sprintf(buf, "_persistent.%u", from_kuid(ns, uid));
|
|
||||||
+
|
|
||||||
+ if (ns->persistent_keyring_register) {
|
|
||||||
+ reg_ref = make_key_ref(ns->persistent_keyring_register, true);
|
|
||||||
+ down_read(&ns->persistent_keyring_register_sem);
|
|
||||||
+ persistent_ref = find_key_to_update(reg_ref, &index_key);
|
|
||||||
+ up_read(&ns->persistent_keyring_register_sem);
|
|
||||||
+
|
|
||||||
+ if (persistent_ref)
|
|
||||||
+ goto found;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* It wasn't in the register, so we'll need to create it. We might
|
|
||||||
+ * also need to create the register.
|
|
||||||
+ */
|
|
||||||
+ down_write(&ns->persistent_keyring_register_sem);
|
|
||||||
+ persistent_ref = key_create_persistent(ns, uid, &index_key);
|
|
||||||
+ up_write(&ns->persistent_keyring_register_sem);
|
|
||||||
+ if (!IS_ERR(persistent_ref))
|
|
||||||
+ goto found;
|
|
||||||
+
|
|
||||||
+ return PTR_ERR(persistent_ref);
|
|
||||||
+
|
|
||||||
+found:
|
|
||||||
+ ret = key_task_permission(persistent_ref, current_cred(), KEY_LINK);
|
|
||||||
+ if (ret == 0) {
|
|
||||||
+ persistent = key_ref_to_ptr(persistent_ref);
|
|
||||||
+ ret = key_link(key_ref_to_ptr(dest_ref), persistent);
|
|
||||||
+ if (ret == 0) {
|
|
||||||
+ key_set_timeout(persistent, persistent_keyring_expiry);
|
|
||||||
+ ret = persistent->serial;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ key_ref_put(persistent_ref);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Get the persistent keyring for a specific UID and link it to the nominated
|
|
||||||
+ * keyring.
|
|
||||||
+ */
|
|
||||||
+long keyctl_get_persistent(uid_t _uid, key_serial_t destid)
|
|
||||||
+{
|
|
||||||
+ struct user_namespace *ns = current_user_ns();
|
|
||||||
+ key_ref_t dest_ref;
|
|
||||||
+ kuid_t uid;
|
|
||||||
+ long ret;
|
|
||||||
+
|
|
||||||
+ /* -1 indicates the current user */
|
|
||||||
+ if (_uid == (uid_t)-1) {
|
|
||||||
+ uid = current_uid();
|
|
||||||
+ } else {
|
|
||||||
+ uid = make_kuid(ns, _uid);
|
|
||||||
+ if (!uid_valid(uid))
|
|
||||||
+ return -EINVAL;
|
|
||||||
+
|
|
||||||
+ /* You can only see your own persistent cache if you're not
|
|
||||||
+ * sufficiently privileged.
|
|
||||||
+ */
|
|
||||||
+ if (!uid_eq(uid, current_uid()) &&
|
|
||||||
+ /* uid_eq(uid, current_suid()) && */
|
|
||||||
+ !uid_eq(uid, current_euid()) &&
|
|
||||||
+ /* uid_eq(uid, current_fsuid()) && */
|
|
||||||
+ !ns_capable(ns, CAP_SETUID))
|
|
||||||
+ return -EPERM;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* There must be a destination keyring */
|
|
||||||
+ dest_ref = lookup_user_key(destid, KEY_LOOKUP_CREATE, KEY_WRITE);
|
|
||||||
+ if (IS_ERR(dest_ref))
|
|
||||||
+ return PTR_ERR(dest_ref);
|
|
||||||
+ if (key_ref_to_ptr(dest_ref)->type != &key_type_keyring) {
|
|
||||||
+ ret = -ENOTDIR;
|
|
||||||
+ goto out_put_dest;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = key_get_persistent(ns, uid, dest_ref);
|
|
||||||
+
|
|
||||||
+out_put_dest:
|
|
||||||
+ key_ref_put(dest_ref);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
diff --git a/security/keys/sysctl.c b/security/keys/sysctl.c
|
|
||||||
index ee32d18..8c0af08 100644
|
|
||||||
--- a/security/keys/sysctl.c
|
|
||||||
+++ b/security/keys/sysctl.c
|
|
||||||
@@ -61,5 +61,16 @@ ctl_table key_sysctls[] = {
|
|
||||||
.extra1 = (void *) &zero,
|
|
||||||
.extra2 = (void *) &max,
|
|
||||||
},
|
|
||||||
+#ifdef CONFIG_PERSISTENT_KEYRINGS
|
|
||||||
+ {
|
|
||||||
+ .procname = "persistent_keyring_expiry",
|
|
||||||
+ .data = &persistent_keyring_expiry,
|
|
||||||
+ .maxlen = sizeof(unsigned),
|
|
||||||
+ .mode = 0644,
|
|
||||||
+ .proc_handler = proc_dointvec_minmax,
|
|
||||||
+ .extra1 = (void *) &zero,
|
|
||||||
+ .extra2 = (void *) &max,
|
|
||||||
+ },
|
|
||||||
+#endif
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
--
|
|
||||||
1.8.3.1
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user