aboutsummaryrefslogtreecommitdiff
path: root/include/linux/key.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/key.h')
-rw-r--r--include/linux/key.h81
1 files changed, 75 insertions, 6 deletions
diff --git a/include/linux/key.h b/include/linux/key.h
index ad17c8f30b4c..91f391cd272e 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -31,6 +31,7 @@ typedef int32_t key_serial_t;
typedef uint32_t key_perm_t;
struct key;
+struct net;
#ifdef CONFIG_KEYS
@@ -77,13 +78,34 @@ struct cred;
struct key_type;
struct key_owner;
+struct key_tag;
struct keyring_list;
struct keyring_name;
+struct key_tag {
+ struct rcu_head rcu;
+ refcount_t usage;
+ bool removed; /* T when subject removed */
+};
+
struct keyring_index_key {
+ /* [!] If this structure is altered, the union in struct key must change too! */
+ unsigned long hash; /* Hash value */
+ union {
+ struct {
+#ifdef __LITTLE_ENDIAN /* Put desc_len at the LSB of x */
+ u8 desc_len;
+ char desc[sizeof(long) - 1]; /* First few chars of description */
+#else
+ char desc[sizeof(long) - 1]; /* First few chars of description */
+ u8 desc_len;
+#endif
+ };
+ unsigned long x;
+ };
struct key_type *type;
+ struct key_tag *domain_tag; /* Domain of operation */
const char *description;
- size_t desc_len;
};
union key_payload {
@@ -197,7 +219,10 @@ struct key {
union {
struct keyring_index_key index_key;
struct {
+ unsigned long hash;
+ unsigned long len_desc;
struct key_type *type; /* type of key */
+ struct key_tag *domain_tag; /* Domain of operation */
char *description;
};
};
@@ -248,6 +273,8 @@ extern struct key *key_alloc(struct key_type *type,
extern void key_revoke(struct key *key);
extern void key_invalidate(struct key *key);
extern void key_put(struct key *key);
+extern bool key_put_tag(struct key_tag *tag);
+extern void key_remove_domain(struct key_tag *domain_tag);
static inline struct key *__key_get(struct key *key)
{
@@ -265,19 +292,57 @@ static inline void key_ref_put(key_ref_t key_ref)
key_put(key_ref_to_ptr(key_ref));
}
-extern struct key *request_key(struct key_type *type,
- const char *description,
- const char *callout_info);
+extern struct key *request_key_tag(struct key_type *type,
+ const char *description,
+ struct key_tag *domain_tag,
+ const char *callout_info);
extern struct key *request_key_rcu(struct key_type *type,
- const char *description);
+ const char *description,
+ struct key_tag *domain_tag);
extern struct key *request_key_with_auxdata(struct key_type *type,
const char *description,
+ struct key_tag *domain_tag,
const void *callout_info,
size_t callout_len,
void *aux);
+/**
+ * request_key - Request a key and wait for construction
+ * @type: Type of key.
+ * @description: The searchable description of the key.
+ * @callout_info: The data to pass to the instantiation upcall (or NULL).
+ *
+ * As for request_key_tag(), but with the default global domain tag.
+ */
+static inline struct key *request_key(struct key_type *type,
+ const char *description,
+ const char *callout_info)
+{
+ return request_key_tag(type, description, NULL, callout_info);
+}
+
+#ifdef CONFIG_NET
+/*
+ * request_key_net - Request a key for a net namespace and wait for construction
+ * @type: Type of key.
+ * @description: The searchable description of the key.
+ * @net: The network namespace that is the key's domain of operation.
+ * @callout_info: The data to pass to the instantiation upcall (or NULL).
+ *
+ * As for request_key() except that it does not add the returned key to a
+ * keyring if found, new keys are always allocated in the user's quota, the
+ * callout_info must be a NUL-terminated string and no auxiliary data can be
+ * passed. Only keys that operate the specified network namespace are used.
+ *
+ * Furthermore, it then works as wait_for_key_construction() to wait for the
+ * completion of keys undergoing construction with a non-interruptible wait.
+ */
+#define request_key_net(type, description, net, callout_info) \
+ request_key_tag(type, description, net->key_domain, callout_info);
+#endif /* CONFIG_NET */
+
extern int wait_for_key_construction(struct key *key, bool intr);
extern int key_validate(const struct key *key);
@@ -321,7 +386,8 @@ extern int keyring_clear(struct key *keyring);
extern key_ref_t keyring_search(key_ref_t keyring,
struct key_type *type,
- const char *description);
+ const char *description,
+ bool recurse);
extern int keyring_add_key(struct key *keyring,
struct key *key);
@@ -340,6 +406,7 @@ extern void key_set_timeout(struct key *, unsigned);
extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
key_perm_t perm);
+extern void key_free_user_ns(struct user_namespace *);
/*
* The permissions required on a key that we're looking up.
@@ -413,6 +480,8 @@ extern void key_init(void);
#define key_fsuid_changed(c) do { } while(0)
#define key_fsgid_changed(c) do { } while(0)
#define key_init() do { } while(0)
+#define key_free_user_ns(ns) do { } while(0)
+#define key_remove_domain(d) do { } while(0)
#endif /* CONFIG_KEYS */
#endif /* __KERNEL__ */