diff options
46 files changed, 325 insertions, 992 deletions
diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst index bc561ca95c86..d6d8b0b756b6 100644 --- a/Documentation/security/keys/core.rst +++ b/Documentation/security/keys/core.rst @@ -57,9 +57,9 @@ Each key has a number of attributes: type provides an operation to perform a match between the description on a key and a criterion string. - * Each key has an owner user ID, a group ID and an ACL. These are used to - control what a process may do to a key from userspace, and whether a - kernel service will be able to find the key. + * Each key has an owner user ID, a group ID and a permissions mask. These + are used to control what a process may do to a key from userspace, and + whether a kernel service will be able to find the key. * Each key can be set to expire at a specific time by the key type's instantiation function. Keys can also be immortal. @@ -198,110 +198,43 @@ The key service provides a number of features besides keys: Key Access Permissions ====================== -Keys have an owner user ID, a group ID and an ACL. The ACL is made up of a -sequence of ACEs that each contain three elements: +Keys have an owner user ID, a group access ID, and a permissions mask. The mask +has up to eight bits each for possessor, user, group and other access. Only +six of each set of eight bits are defined. These permissions granted are: - * The type of subject. - * The subject. + * View - These two together indicate the subject to whom the permits are granted. - The type can be one of: + This permits a key or keyring's attributes to be viewed - including key + type and description. - * ``KEY_ACE_SUBJ_STANDARD`` + * Read - The subject is a standard 'macro' type. The subject can be one of: - - * ``KEY_ACE_EVERYONE`` - - The permits are granted to everyone. It replaces the old 'other' - type on the assumption that you wouldn't grant a permission to other - that you you wouldn't grant to everyone else. - - * ``KEY_ACE_OWNER`` - - The permits are granted to the owner of the key (key->uid). - - * ``KEY_ACE_GROUP`` - - The permits are granted to the key's group (key->gid). - - * ``KEY_ACE_POSSESSOR`` - - The permits are granted to anyone who possesses the key. - - * The set of permits granted to the subject. These include: - - * ``KEY_ACE_VIEW`` - - This permits a key or keyring's attributes to be viewed - including the - key type and description. - - * ``KEY_ACE_READ`` - - This permits a key's payload to be viewed or a keyring's list of linked - keys. - - * ``KEY_ACE_WRITE`` - - This permits a key's payload to be instantiated or updated, or it allows - a link to be added to or removed from a keyring. - - * ``KEY_ACE_SEARCH`` - - This permits keyrings to be searched and keys to be found. Searches can - only recurse into nested keyrings that have search permission set. - - * ``KEY_ACE_LINK`` - - This permits a key or keyring to be linked to. To create a link from a - keyring to a key, a process must have Write permission on the keyring - and Link permission on the key. - - * ``KEY_ACE_SET_SECURITY`` - - This permits a key's UID, GID and permissions mask to be changed. + This permits a key's payload to be viewed or a keyring's list of linked + keys. - * ``KEY_ACE_INVAL`` + * Write - This permits a key to be invalidated with KEYCTL_INVALIDATE. + This permits a key's payload to be instantiated or updated, or it allows a + link to be added to or removed from a keyring. - * ``KEY_ACE_REVOKE`` + * Search - This permits a key to be revoked with KEYCTL_REVOKE. + This permits keyrings to be searched and keys to be found. Searches can + only recurse into nested keyrings that have search permission set. - * ``KEY_ACE_JOIN`` + * Link - This permits a keyring to be joined as a session by - KEYCTL_JOIN_SESSION_KEYRING or KEYCTL_SESSION_TO_PARENT. + This permits a key or keyring to be linked to. To create a link from a + keyring to a key, a process must have Write permission on the keyring and + Link permission on the key. - * ``KEY_ACE_CLEAR`` + * Set Attribute - This permits a keyring to be cleared. + This permits a key's UID, GID and permissions mask to be changed. For changing the ownership, group ID or permissions mask, being the owner of the key or having the sysadmin capability is sufficient. -The legacy KEYCTL_SETPERM and KEYCTL_DESCRIBE functions can only see/generate -View, Read, Write, Search, Link and SetAttr permits, and do this for each of -possessor, user, group and other permission sets as a 32-bit flag mask. These -will be approximated/inferred: - - SETPERM Permit Implied ACE Permit - =============== ======================= - Search Inval, Join - Write Revoke, Clear - Setattr Set Security, Revoke - - ACE Permit Described as - =============== ======================= - Inval Search - Join Search - Revoke Write (unless Setattr) - Clear write - Set Security Setattr - -'Other' will be approximated as/inferred from the 'Everyone' subject. - SELinux Support =============== @@ -1151,8 +1084,7 @@ payload contents" for more information. struct key *request_key(const struct key_type *type, const char *description, - const char *callout_info, - struct key_acl *acl); + const char *callout_info); This is used to request a key or keyring with a description that matches the description specified according to the key type's match_preparse() @@ -1167,8 +1099,6 @@ payload contents" for more information. If successful, the key will have been attached to the default keyring for implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING. - If a key is created, it will be given the specified ACL. - See also Documentation/security/keys/request-key.rst. @@ -1177,8 +1107,7 @@ payload contents" for more information. struct key *request_key_tag(const struct key_type *type, const char *description, struct key_tag *domain_tag, - const char *callout_info, - struct key_acl *acl); + const char *callout_info); This is identical to request_key(), except that a domain tag may be specifies that causes search algorithm to only match keys matching that @@ -1193,8 +1122,7 @@ payload contents" for more information. struct key_tag *domain_tag, const void *callout_info, size_t callout_len, - void *aux, - struct key_acl *acl); + void *aux); This is identical to request_key_tag(), except that the auxiliary data is passed to the key_type->request_key() op if it exists, and the @@ -1267,7 +1195,7 @@ payload contents" for more information. struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, const struct cred *cred, - struct key_acl *acl, + key_perm_t perm, struct key_restriction *restrict_link, unsigned long flags, struct key *dest); diff --git a/Documentation/security/keys/request-key.rst b/Documentation/security/keys/request-key.rst index f356fd06c8d5..35f2296b704a 100644 --- a/Documentation/security/keys/request-key.rst +++ b/Documentation/security/keys/request-key.rst @@ -11,16 +11,14 @@ The process starts by either the kernel requesting a service by calling struct key *request_key(const struct key_type *type, const char *description, - const char *callout_info, - struct key_acl *acl); + const char *callout_info); or:: struct key *request_key_tag(const struct key_type *type, const char *description, const struct key_tag *domain_tag, - const char *callout_info, - struct key_acl *acl); + const char *callout_info); or:: @@ -29,8 +27,7 @@ or:: const struct key_tag *domain_tag, const char *callout_info, size_t callout_len, - void *aux, - struct key_acl *acl); + void *aux); or:: diff --git a/certs/blacklist.c b/certs/blacklist.c index 93d70b885f8e..ec00bf337eb6 100644 --- a/certs/blacklist.c +++ b/certs/blacklist.c @@ -89,7 +89,8 @@ int mark_hash_blacklisted(const char *hash) hash, NULL, 0, - &internal_key_acl, + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW), KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN); if (IS_ERR(key)) { @@ -148,7 +149,9 @@ static int __init blacklist_init(void) keyring_alloc(".blacklist", KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), - &internal_keyring_acl, + (KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW | KEY_USR_READ | + KEY_USR_SEARCH, KEY_ALLOC_NOT_IN_QUOTA | KEY_FLAG_KEEP, NULL, NULL); diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 57be78b5fdfc..1eba08a1af82 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -99,7 +99,9 @@ static __init int system_trusted_keyring_init(void) builtin_trusted_keys = keyring_alloc(".builtin_trusted_keys", KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), - &internal_key_acl, KEY_ALLOC_NOT_IN_QUOTA, + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), + KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); if (IS_ERR(builtin_trusted_keys)) panic("Can't allocate builtin trusted keyring\n"); @@ -108,7 +110,10 @@ static __init int system_trusted_keyring_init(void) secondary_trusted_keys = keyring_alloc(".secondary_trusted_keys", KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), - &internal_writable_keyring_acl, KEY_ALLOC_NOT_IN_QUOTA, + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH | + KEY_USR_WRITE), + KEY_ALLOC_NOT_IN_QUOTA, get_builtin_and_secondary_restriction(), NULL); if (IS_ERR(secondary_trusted_keys)) @@ -158,7 +163,8 @@ static __init int load_system_certificate_list(void) NULL, p, plen, - &internal_key_acl, + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW | KEY_USR_READ), KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN | KEY_ALLOC_BYPASS_RESTRICTION); diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 0fd3ca9bfe54..1b16d34bb785 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -2035,7 +2035,7 @@ static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string return -ENOMEM; key = request_key(key_string[0] == 'l' ? &key_type_logon : &key_type_user, - key_desc + 1, NULL, NULL); + key_desc + 1, NULL); if (IS_ERR(key)) { kzfree(new_key_string); return PTR_ERR(key); diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c index 99a5708b37e3..a570f2263a42 100644 --- a/drivers/nvdimm/security.c +++ b/drivers/nvdimm/security.c @@ -55,7 +55,7 @@ static struct key *nvdimm_request_key(struct nvdimm *nvdimm) struct device *dev = &nvdimm->dev; sprintf(desc, "%s%s", NVDIMM_PREFIX, nvdimm->dimm_id); - key = request_key(&key_type_encrypted, desc, "", NULL); + key = request_key(&key_type_encrypted, desc, ""); if (IS_ERR(key)) { if (PTR_ERR(key) == -ENOKEY) dev_dbg(dev, "request_key() found no key\n"); diff --git a/fs/afs/security.c b/fs/afs/security.c index 8866703b2e6c..71e71c07568f 100644 --- a/fs/afs/security.c +++ b/fs/afs/security.c @@ -28,7 +28,7 @@ struct key *afs_request_key(struct afs_cell *cell) _debug("key %s", cell->anonymous_key->description); key = request_key(&key_type_rxrpc, cell->anonymous_key->description, - NULL, NULL); + NULL); if (IS_ERR(key)) { if (PTR_ERR(key) != -ENOKEY) { _leave(" = %ld", PTR_ERR(key)); diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index d1b439ad0f1a..7f01c6e60791 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c @@ -32,25 +32,6 @@ #include "cifsproto.h" static const struct cred *spnego_cred; -static struct key_acl cifs_spnego_key_acl = { - .usage = REFCOUNT_INIT(1), - .nr_ace = 2, - .possessor_viewable = true, - .aces = { - KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_SEARCH | KEY_ACE_READ), - KEY_OWNER_ACE(KEY_ACE_VIEW), - } -}; - -static struct key_acl cifs_spnego_keyring_acl = { - .usage = REFCOUNT_INIT(1), - .nr_ace = 2, - .aces = { - KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE), - KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_CLEAR), - } -}; - /* create a new cifs key */ static int cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) @@ -189,8 +170,7 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo) cifs_dbg(FYI, "key description = %s\n", description); saved_cred = override_creds(spnego_cred); - spnego_key = request_key(&cifs_spnego_key_type, description, "", - &cifs_spnego_key_acl); + spnego_key = request_key(&cifs_spnego_key_type, description, ""); revert_creds(saved_cred); #ifdef CONFIG_CIFS_DEBUG2 @@ -227,7 +207,8 @@ init_cifs_spnego(void) keyring = keyring_alloc(".cifs_spnego", GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, - &cifs_spnego_keyring_acl, + (KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW | KEY_USR_READ, KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); if (IS_ERR(keyring)) { ret = PTR_ERR(keyring); diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 78eed72f3af0..1d377b7f2860 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -33,25 +33,6 @@ #include "cifsproto.h" #include "cifs_debug.h" -static struct key_acl cifs_idmap_key_acl = { - .usage = REFCOUNT_INIT(1), - .nr_ace = 2, - .possessor_viewable = true, - .aces = { - KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_SEARCH | KEY_ACE_READ), - KEY_OWNER_ACE(KEY_ACE_VIEW), - } -}; - -static struct key_acl cifs_idmap_keyring_acl = { - .usage = REFCOUNT_INIT(1), - .nr_ace = 2, - .aces = { - KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE), - KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ), - } -}; - /* security id for everyone/world system group */ static const struct cifs_sid sid_everyone = { 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; @@ -317,8 +298,7 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid) rc = 0; saved_cred = override_creds(root_cred); - sidkey = request_key(&cifs_idmap_key_type, desc, "", - &cifs_idmap_key_acl); + sidkey = request_key(&cifs_idmap_key_type, desc, ""); if (IS_ERR(sidkey)) { rc = -EINVAL; cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n", @@ -423,8 +403,7 @@ try_upcall_to_get_id: return -ENOMEM; saved_cred = override_creds(root_cred); - sidkey = request_key(&cifs_idmap_key_type, sidstr, "", - &cifs_idmap_key_acl); + sidkey = request_key(&cifs_idmap_key_type, sidstr, ""); if (IS_ERR(sidkey)) { rc = -EINVAL; cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n", @@ -502,7 +481,8 @@ init_cifs_idmap(void) keyring = keyring_alloc(".cifs_idmap", GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, - &cifs_idmap_keyring_acl, + (KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW | KEY_USR_READ, KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); if (IS_ERR(keyring)) { ret = PTR_ERR(keyring); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index ae6bae2ecb5d..714a359c7c8d 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2992,7 +2992,7 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses) } cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc); - key = request_key(&key_type_logon, desc, "", NULL); + key = request_key(&key_type_logon, desc, ""); if (IS_ERR(key)) { if (!ses->domainName) { cifs_dbg(FYI, "domainName is NULL\n"); @@ -3003,7 +3003,7 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses) /* didn't work, try to find a domain key */ sprintf(desc, "cifs:d:%s", ses->domainName); cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc); - key = request_key(&key_type_logon, desc, "", NULL); + key = request_key(&key_type_logon, desc, ""); if (IS_ERR(key)) { rc = PTR_ERR(key); goto out_err; diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c index 4f85af8ab239..dcd91a3fbe49 100644 --- a/fs/crypto/keyinfo.c +++ b/fs/crypto/keyinfo.c @@ -92,7 +92,7 @@ find_and_lock_process_key(const char *prefix, if (!description) return ERR_PTR(-ENOMEM); - key = request_key(&key_type_logon, description, NULL, NULL); + key = request_key(&key_type_logon, description, NULL); kfree(description); if (IS_ERR(key)) return key; diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 67844fe41a61..1c1a56be7ea2 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -91,7 +91,7 @@ ecryptfs_get_encrypted_key_payload_data(struct key *key) static inline struct key *ecryptfs_get_encrypted_key(char *sig) { - return request_key(&key_type_encrypted, sig, NULL, NULL); + return request_key(&key_type_encrypted, sig, NULL); } #else diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index ba382f135918..9536e592e25a 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c @@ -1610,7 +1610,7 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, { int rc = 0; - (*auth_tok_key) = request_key(&key_type_user, sig, NULL, NULL); + (*auth_tok_key) = request_key(&key_type_user, sig, NULL); if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) { (*auth_tok_key) = ecryptfs_get_encrypted_key(sig); if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) { diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c index 67b7bda5647a..72ebfe578f40 100644 --- a/fs/fscache/object-list.c +++ b/fs/fscache/object-list.c @@ -317,7 +317,7 @@ static void fscache_objlist_config(struct fscache_objlist_data *data) const char *buf; int len; - key = request_key(&key_type_user, "fscache:objlist", NULL, NULL); + key = request_key(&key_type_user, "fscache:objlist", NULL); if (IS_ERR(key)) goto no_config; diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c index 69679f4f2e6c..1e7296395d71 100644 --- a/fs/nfs/nfs4idmap.c +++ b/fs/nfs/nfs4idmap.c @@ -72,25 +72,6 @@ struct idmap { const struct cred *cred; }; -static struct key_acl nfs_idmap_key_acl = { - .usage = REFCOUNT_INIT(1), - .nr_ace = 2, - .possessor_viewable = true, - .aces = { - KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_SEARCH | KEY_ACE_READ), - KEY_OWNER_ACE(KEY_ACE_VIEW), - } -}; - -static struct key_acl nfs_idmap_keyring_acl = { - .usage = REFCOUNT_INIT(1), - .nr_ace = 2, - .aces = { - KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE), - KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ), - } -}; - static struct user_namespace *idmap_userns(const struct idmap *idmap) { if (idmap && idmap->cred) @@ -227,7 +208,8 @@ int nfs_idmap_init(void) keyring = keyring_alloc(".id_resolver", GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, - &nfs_idmap_keyring_acl, + (KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW | KEY_USR_READ, KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); if (IS_ERR(keyring)) { ret = PTR_ERR(keyring); @@ -305,13 +287,11 @@ static struct key *nfs_idmap_request_key(const char *name, size_t namelen, return ERR_PTR(ret); if (!idmap->cred || idmap->cred->user_ns == &init_user_ns) - rkey = request_key(&key_type_id_resolver, desc, "", - &nfs_idmap_key_acl); + rkey = request_key(&key_type_id_resolver, desc, ""); if (IS_ERR(rkey)) { mutex_lock(&idmap->idmap_mutex); rkey = request_key_with_auxdata(&key_type_id_resolver_legacy, - desc, NULL, "", 0, idmap, - &nfs_idmap_key_acl); + desc, NULL, "", 0, idmap); mutex_unlock(&idmap->idmap_mutex); } if (!IS_ERR(rkey)) @@ -340,6 +320,8 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen, } rcu_read_lock(); + rkey->perm |= KEY_USR_VIEW; + ret = key_validate(rkey); if (ret < 0) goto out_up; diff --git a/fs/ubifs/auth.c b/fs/ubifs/auth.c index 38718026ad0b..60f43b93d06e 100644 --- a/fs/ubifs/auth.c +++ b/fs/ubifs/auth.c @@ -227,7 +227,7 @@ int ubifs_init_authentication(struct ubifs_info *c) snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)", c->auth_hash_name); - keyring_key = request_key(&key_type_logon, c->auth_key_name, NULL, NULL); + keyring_key = request_key(&key_type_logon, c->auth_key_name, NULL); if (IS_ERR(keyring_key)) { ubifs_err(c, "Failed to request key: %ld", diff --git a/include/linux/key.h b/include/linux/key.h index 6fef6684501f..91f391cd272e 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -27,15 +27,50 @@ /* key handle serial number */ typedef int32_t key_serial_t; +/* key handle permissions mask */ +typedef uint32_t key_perm_t; + struct key; struct net; #ifdef CONFIG_KEYS -#include <linux/keyctl.h> - #undef KEY_DEBUGGING +#define KEY_POS_VIEW 0x01000000 /* possessor can view a key's attributes */ +#define KEY_POS_READ 0x02000000 /* possessor can read key payload / view keyring */ +#define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */ +#define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */ +#define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */ +#define KEY_POS_SETATTR 0x20000000 /* possessor can set key attributes */ +#define KEY_POS_ALL 0x3f000000 + +#define KEY_USR_VIEW 0x00010000 /* user permissions... */ +#define KEY_USR_READ 0x00020000 +#define KEY_USR_WRITE 0x00040000 +#define KEY_USR_SEARCH 0x00080000 +#define KEY_USR_LINK 0x00100000 +#define KEY_USR_SETATTR 0x00200000 +#define KEY_USR_ALL 0x003f0000 + +#define KEY_GRP_VIEW 0x00000100 /* group permissions... */ +#define KEY_GRP_READ 0x00000200 +#define KEY_GRP_WRITE 0x00000400 +#define KEY_GRP_SEARCH 0x00000800 +#define KEY_GRP_LINK 0x00001000 +#define KEY_GRP_SETATTR 0x00002000 +#define KEY_GRP_ALL 0x00003f00 + +#define KEY_OTH_VIEW 0x00000001 /* third party permissions... */ +#define KEY_OTH_READ 0x00000002 +#define KEY_OTH_WRITE 0x00000004 +#define KEY_OTH_SEARCH 0x00000008 +#define KEY_OTH_LINK 0x00000010 +#define KEY_OTH_SETATTR 0x00000020 +#define KEY_OTH_ALL 0x0000003f + +#define KEY_PERM_UNDEF 0xffffffff + struct seq_file; struct user_struct; struct signal_struct; @@ -78,36 +113,6 @@ union key_payload { void *data[4]; }; -struct key_ace { - unsigned int type; - unsigned int perm; - union { - kuid_t uid; - kgid_t gid; - unsigned int subject_id; - }; -}; - -struct key_acl { - refcount_t usage; - unsigned short nr_ace; - bool possessor_viewable; - struct rcu_head rcu; - struct key_ace aces[]; -}; - -#define KEY_POSSESSOR_ACE(perms) { \ - .type = KEY_ACE_SUBJ_STANDARD, \ - .perm = perms, \ - .subject_id = KEY_ACE_POSSESSOR \ - } - -#define KEY_OWNER_ACE(perms) { \ - .type = KEY_ACE_SUBJ_STANDARD, \ - .perm = perms, \ - .subject_id = KEY_ACE_OWNER \ - } - /*****************************************************************************/ /* * key reference with possession attribute handling @@ -174,7 +179,6 @@ struct key { struct rw_semaphore sem; /* change vs change sem */ struct key_user *user; /* owner of this key */ void *security; /* security data for this key */ - struct key_acl __rcu *acl; union { time64_t expiry; /* time at which key expires (or 0) */ time64_t revoked_at; /* time at which key was revoked */ @@ -182,6 +186,7 @@ struct key { time64_t last_used_at; /* last time used for LRU keyring discard */ kuid_t uid; kgid_t gid; + key_perm_t perm; /* access permissions */ unsigned short quotalen; /* length added to quota */ unsigned short datalen; /* payload data length * - may not match RCU dereferenced payload @@ -205,7 +210,6 @@ struct key { #define KEY_FLAG_ROOT_CAN_INVAL 7 /* set if key can be invalidated by root without permission */ #define KEY_FLAG_KEEP 8 /* set if key should not be removed */ #define KEY_FLAG_UID_KEYRING 9 /* set if key is a user or user session keyring */ -#define KEY_FLAG_HAS_ACL 10 /* Set if KEYCTL_SETACL called on key */ |