Revert "Merge tag 'keys-acl-20190703' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Jul 2019 01:43:43 +0000 (18:43 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Jul 2019 01:43:43 +0000 (18:43 -0700)
This reverts merge 0f75ef6a9cff49ff612f7ce0578bced9d0b38325 (and thus
effectively commits

   7a1ade847596 ("keys: Provide KEYCTL_GRANT_PERMISSION")
   2e12256b9a76 ("keys: Replace uid/gid/perm permissions checking with an ACL")

that the merge brought in).

It turns out that it breaks booting with an encrypted volume, and Eric
biggers reports that it also breaks the fscrypt tests [1] and loading of
in-kernel X.509 certificates [2].

The root cause of all the breakage is likely the same, but David Howells
is off email so rather than try to work it out it's getting reverted in
order to not impact the rest of the merge window.

 [1] https://lore.kernel.org/lkml/20190710011559.GA7973@sol.localdomain/
 [2] https://lore.kernel.org/lkml/20190710013225.GB7973@sol.localdomain/

Link: https://lore.kernel.org/lkml/CAHk-=wjxoeMJfeBahnWH=9zShKp2bsVy527vo3_y8HfOdhwAAw@mail.gmail.com/
Reported-by: Eric Biggers <ebiggers@kernel.org>
Cc: David Howells <dhowells@redhat.com>
Cc: James Morris <jmorris@namei.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
46 files changed:
Documentation/security/keys/core.rst
Documentation/security/keys/request-key.rst
certs/blacklist.c
certs/system_keyring.c
drivers/md/dm-crypt.c
drivers/nvdimm/security.c
fs/afs/security.c
fs/cifs/cifs_spnego.c
fs/cifs/cifsacl.c
fs/cifs/connect.c
fs/crypto/keyinfo.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/keystore.c
fs/fscache/object-list.c
fs/nfs/nfs4idmap.c
fs/ubifs/auth.c
include/linux/key.h
include/uapi/linux/keyctl.h
lib/digsig.c
net/ceph/ceph_common.c
net/dns_resolver/dns_key.c
net/dns_resolver/dns_query.c
net/rxrpc/key.c
net/wireless/reg.c
security/integrity/digsig.c
security/integrity/digsig_asymmetric.c
security/integrity/evm/evm_crypto.c
security/integrity/ima/ima_mok.c
security/integrity/integrity.h
security/integrity/platform_certs/platform_keyring.c
security/keys/compat.c
security/keys/encrypted-keys/encrypted.c
security/keys/encrypted-keys/masterkey_trusted.c
security/keys/gc.c
security/keys/internal.h
security/keys/key.c
security/keys/keyctl.c
security/keys/keyring.c
security/keys/permission.c
security/keys/persistent.c
security/keys/proc.c
security/keys/process_keys.c
security/keys/request_key.c
security/keys/request_key_auth.c
security/selinux/hooks.c
security/smack/smack_lsm.c

index bc561ca95c869443500f879fefaa34ea7be47eb3..d6d8b0b756b6961442bf6fdf1a743e880fea3f04 100644 (file)
@@ -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);
index f356fd06c8d54ac4640450a1a49b290520eb5445..35f2296b704a3841924b3bb829d354380927ea30 100644 (file)
@@ -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::
 
index 93d70b885f8ea38980be751357909a6264558ae3..ec00bf337eb673b28bced4f1521d9d0a007a0c2e 100644 (file)
@@ -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);
index 57be78b5fdfc30fd77b76ce29d00d4b63b12cfe4..1eba08a1af82733dc84b08fcdd8797d022922329 100644 (file)
@@ -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);
index 0fd3ca9bfe54066afa4bcb60ff995d25367d3e4e..1b16d34bb78518a1849aa331c6da2ac1da0e8586 100644 (file)
@@ -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);
index 99a5708b37e3cafcd936b34b2ba6c51fe5ddeda5..a570f2263a424e96908c559750454a086a3df3e2 100644 (file)
@@ -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");
index 8866703b2e6c061f7aa63c6a08dc7e8ae6625801..71e71c07568f6f0675662ae976a0061c7132b8c7 100644 (file)
@@ -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));
index d1b439ad0f1a03035a4697417212ced696ef727b..7f01c6e607918d4e1356a9e7d305113777910089 100644 (file)
 #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);
index 78eed72f3af01a86e558bdb1f3bc8ae76fcf9422..1d377b7f286055fa0b8c2117c89f843704fb9c3c 100644 (file)
 #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);
index ae6bae2ecb5dbc0081764b9ff8e79874b82a0006..714a359c7c8de6fc0c1fb9cecafb695d590b4c28 100644 (file)
@@ -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;
index 4f85af8ab239c2840ccaae7f55365ba19a272b8c..dcd91a3fbe49a082ca60e2d08cf53dd70d5aded8 100644 (file)
@@ -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;
index 67844fe41a61d17ac94ea6c58457c4a858fdb59d..1c1a56be7ea2feb35314419f79aa08ceb12dbd62 100644 (file)
@@ -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
index ba382f1359181b38391ebb04eda432b6719f345e..9536e592e25a4caa0fd4154671e58f8d466f50af 100644 (file)
@@ -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)) {
index 67b7bda5647a6e5e2639b6f90e0d7c83472ae36b..72ebfe578f4098e7e0880ac1ddc65775ce2fa3a0 100644 (file)
@@ -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;
 
index 69679f4f2e6cff31b6639a036b7fe36b95c46663..1e7296395d71bfc3144d5a57c6658712d7730c09 100644 (file)
@@ -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;
index 38718026ad0b15c26762eeb780b47a8fbb7ff951..60f43b93d06e4b479fa2543f90619ffa841d0fe7 100644 (file)
@@ -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",
index 6fef6684501f56c86a3686d4cb609be9f76ac29e..91f391cd272e094d3d74683f08ac226fe8e1ce20 100644 (file)
 /* 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 */
 
        /* the key type and key description string
         * - the desc is used to match a key against search criteria
@@ -254,7 +258,7 @@ extern struct key *key_alloc(struct key_type *type,
                             const char *desc,
                             kuid_t uid, kgid_t gid,
                             const struct cred *cred,
-                            struct key_acl *acl,
+                            key_perm_t perm,
                             unsigned long flags,
                             struct key_restriction *restrict_link);
 
@@ -291,8 +295,7 @@ static inline void key_ref_put(key_ref_t key_ref)
 extern struct key *request_key_tag(struct key_type *type,
                                   const char *description,
                                   struct key_tag *domain_tag,
-                                  const char *callout_info,
-                                  struct key_acl *acl);
+                                  const char *callout_info);
 
 extern struct key *request_key_rcu(struct key_type *type,
                                   const char *description,
@@ -303,24 +306,21 @@ extern struct key *request_key_with_auxdata(struct key_type *type,
                                            struct key_tag *domain_tag,
                                            const void *callout_info,
                                            size_t callout_len,
-                                           void *aux,
-                                           struct key_acl *acl);
+                                           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).
- * @acl: The ACL to attach to a new key (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,
-                                     struct key_acl *acl)
+                                     const char *callout_info)
 {
-       return request_key_tag(type, description, NULL, callout_info, acl);
+       return request_key_tag(type, description, NULL, callout_info);
 }
 
 #ifdef CONFIG_NET
@@ -330,7 +330,6 @@ static inline struct key *request_key(struct key_type *type,
  * @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).
- * @acl: The ACL to attach to a new key (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
@@ -340,8 +339,8 @@ static inline struct key *request_key(struct key_type *type,
  * 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, acl)     \
-       request_key_tag(type, description, net->key_domain, callout_info, acl);
+#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);
@@ -353,7 +352,7 @@ extern key_ref_t key_create_or_update(key_ref_t keyring,
                                      const char *description,
                                      const void *payload,
                                      size_t plen,
-                                     struct key_acl *acl,
+                                     key_perm_t perm,
                                      unsigned long flags);
 
 extern int key_update(key_ref_t key,
@@ -373,7 +372,7 @@ extern int key_unlink(struct key *keyring,
 
 extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
                                 const struct cred *cred,
-                                struct key_acl *acl,
+                                key_perm_t perm,
                                 unsigned long flags,
                                 struct key_restriction *restrict_link,
                                 struct key *dest);
@@ -406,29 +405,19 @@ static inline key_serial_t key_serial(const struct key *key)
 extern void key_set_timeout(struct key *, unsigned);
 
 extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
-                                u32 desired_perm);
+                                key_perm_t perm);
 extern void key_free_user_ns(struct user_namespace *);
 
 /*
  * The permissions required on a key that we're looking up.
  */
-#define        KEY_NEED_VIEW   0x001   /* Require permission to view attributes */
-#define        KEY_NEED_READ   0x002   /* Require permission to read content */
-#define        KEY_NEED_WRITE  0x004   /* Require permission to update / modify */
-#define        KEY_NEED_SEARCH 0x008   /* Require permission to search (keyring) or find (key) */
-#define        KEY_NEED_LINK   0x010   /* Require permission to link */
-#define        KEY_NEED_SETSEC 0x020   /* Require permission to set owner, group, ACL */
-#define        KEY_NEED_INVAL  0x040   /* Require permission to invalidate key */
-#define        KEY_NEED_REVOKE 0x080   /* Require permission to revoke key */
-#define        KEY_NEED_JOIN   0x100   /* Require permission to join keyring as session */
-#define        KEY_NEED_CLEAR  0x200   /* Require permission to clear a keyring */
-#define KEY_NEED_ALL   0x3ff
-
-#define OLD_KEY_NEED_SETATTR 0x20 /* Used to be Require permission to change attributes */
-
-extern struct key_acl internal_key_acl;
-extern struct key_acl internal_keyring_acl;
-extern struct key_acl internal_writable_keyring_acl;
+#define        KEY_NEED_VIEW   0x01    /* Require permission to view attributes */
+#define        KEY_NEED_READ   0x02    /* Require permission to read content */
+#define        KEY_NEED_WRITE  0x04    /* Require permission to update / modify */
+#define        KEY_NEED_SEARCH 0x08    /* Require permission to search (keyring) or find (key) */
+#define        KEY_NEED_LINK   0x10    /* Require permission to link */
+#define        KEY_NEED_SETATTR 0x20   /* Require permission to change attributes */
+#define        KEY_NEED_ALL    0x3f    /* All the above permissions */
 
 static inline short key_read_state(const struct key *key)
 {
index 1f7a4e7372147f69639dce69145822b61e3fad32..ed3d5893830df5fb8deb24171409117acf558b86 100644 (file)
 
 #include <linux/types.h>
 
-/*
- * Keyring permission grant definitions
- */
-enum key_ace_subject_type {
-       KEY_ACE_SUBJ_STANDARD   = 0,    /* subject is one of key_ace_standard_subject */
-       nr__key_ace_subject_type
-};
-
-enum key_ace_standard_subject {
-       KEY_ACE_EVERYONE        = 0,    /* Everyone, including owner and group */
-       KEY_ACE_GROUP           = 1,    /* The key's group */
-       KEY_ACE_OWNER           = 2,    /* The owner of the key */
-       KEY_ACE_POSSESSOR       = 3,    /* Any process that possesses of the key */
-       nr__key_ace_standard_subject
-};
-
-#define KEY_ACE_VIEW           0x00000001 /* Can describe the key */
-#define KEY_ACE_READ           0x00000002 /* Can read the key content */
-#define KEY_ACE_WRITE          0x00000004 /* Can update/modify the key content */
-#define KEY_ACE_SEARCH         0x00000008 /* Can find the key by search */
-#define KEY_ACE_LINK           0x00000010 /* Can make a link to the key */
-#define KEY_ACE_SET_SECURITY   0x00000020 /* Can set owner, group, ACL */
-#define KEY_ACE_INVAL          0x00000040 /* Can invalidate the key */
-#define KEY_ACE_REVOKE         0x00000080 /* Can revoke the key */
-#define KEY_ACE_JOIN           0x00000100 /* Can join keyring */
-#define KEY_ACE_CLEAR          0x00000200 /* Can clear keyring */
-#define KEY_ACE__PERMS         0xffffffff
-
-/*
- * Old-style permissions mask, deprecated in favour of ACL.
- */
-#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
-
 /* special process keyring shortcut IDs */
 #define KEY_SPEC_THREAD_KEYRING                -1      /* - key ID for thread-specific keyring */
 #define KEY_SPEC_PROCESS_KEYRING       -2      /* - key ID for process-specific keyring */
@@ -132,7 +69,6 @@ enum key_ace_standard_subject {
 #define KEYCTL_RESTRICT_KEYRING                29      /* Restrict keys allowed to link to a keyring */
 #define KEYCTL_MOVE                    30      /* Move keys between keyrings */
 #define KEYCTL_CAPABILITIES            31      /* Find capabilities of keyrings subsystem */
-#define KEYCTL_GRANT_PERMISSION                32      /* Grant a permit to a key */
 
 /* keyctl structures */
 struct keyctl_dh_params {
@@ -194,6 +130,5 @@ struct keyctl_pkey_params {
 #define KEYCTL_CAPS0_MOVE              0x80 /* KEYCTL_MOVE supported */
 #define KEYCTL_CAPS1_NS_KEYRING_NAME   0x01 /* Keyring names are per-user_namespace */
 #define KEYCTL_CAPS1_NS_KEY_TAG                0x02 /* Key indexing can include a namespace tag */
-#define KEYCTL_CAPS1_ACL_ALTERABLE     0x04 /* Keys have internal ACL that can be altered */
 
 #endif /*  _LINUX_KEYCTL_H */
index ab0800f98eaf06df45fa7820bb547194e149c3aa..e0627c3e53b2e77ea3d0835e1b7666e24da5e93d 100644 (file)
@@ -224,7 +224,7 @@ int digsig_verify(struct key *keyring, const char *sig, int siglen,
                else
                        key = key_ref_to_ptr(kref);
        } else {
-               key = request_key(&key_type_user, name, NULL, NULL);
+               key = request_key(&key_type_user, name, NULL);
        }
        if (IS_ERR(key)) {
                pr_err("key not found, id: %s\n", name);
index 38de80d01aae121f7129c55f731e0a92c3bb77a0..1c811c74bfc0f3123eb2ad481822aca91590c997 100644 (file)
@@ -306,7 +306,7 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name) {
        int err = 0;
        struct ceph_crypto_key *ckey;
 
-       ukey = request_key(&key_type_ceph, name, NULL, NULL);
+       ukey = request_key(&key_type_ceph, name, NULL);
        if (IS_ERR(ukey)) {
                /* request_key errors don't map nicely to mount(2)
                   errors; don't even try, but still printk */
index 6b201531b1655a90404630419503a81ae34aaf92..3e1a906690063fab671e9d077cf500a190423157 100644 (file)
@@ -46,15 +46,6 @@ const struct cred *dns_resolver_cache;
 
 #define        DNS_ERRORNO_OPTION      "dnserror"
 
-static struct key_acl dns_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),
-       }
-};
-
 /*
  * Preparse instantiation data for a dns_resolver key.
  *
@@ -352,7 +343,8 @@ static int __init init_dns_resolver(void)
 
        keyring = keyring_alloc(".dns_resolver",
                                GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
-                               &dns_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);
index 236baf2bfa4c6fc4e11a017ccca866666116d6fb..cab4e0df924f5c5f3ae9d67b22903ae8411b53ba 100644 (file)
 
 #include "internal.h"
 
-static struct key_acl dns_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 | KEY_ACE_INVAL),
-       }
-};
-
 /**
  * dns_query - Query the DNS
  * @net: The network namespace to operate in.
@@ -135,8 +125,7 @@ int dns_query(struct net *net,
         * add_key() to preinstall malicious redirections
         */
        saved_cred = override_creds(dns_resolver_cache);
-       rkey = request_key_net(&key_type_dns_resolver, desc, net, options,
-                              &dns_key_acl);
+       rkey = request_key_net(&key_type_dns_resolver, desc, net, options);
        revert_creds(saved_cred);
        kfree(desc);
        if (IS_ERR(rkey)) {
@@ -146,6 +135,8 @@ int dns_query(struct net *net,
 
        down_read(&rkey->sem);
        set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags);
+       rkey->perm |= KEY_USR_VIEW;
+
        ret = key_validate(rkey);
        if (ret < 0)
                goto put;
index 2032f6a8225e5df4c49f821fb501cdad0d5c437c..6c3f35fac42d57eeb4449e403c4267ae7bcb9d11 100644 (file)
 #include <keys/user-type.h>
 #include "ar-internal.h"
 
-static struct key_acl rxrpc_null_key_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .nr_ace = 1,
-       .aces = {
-               KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_READ),
-       }
-};
-
 static int rxrpc_vet_description_s(const char *);
 static int rxrpc_preparse(struct key_preparsed_payload *);
 static int rxrpc_preparse_s(struct key_preparsed_payload *);
@@ -918,8 +910,7 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
        if (IS_ERR(description))
                return PTR_ERR(description);
 
-       key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk),
-                             NULL, NULL);
+       key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), NULL);
        if (IS_ERR(key)) {
                kfree(description);
                _leave(" = %ld", PTR_ERR(key));
@@ -950,8 +941,7 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
        if (IS_ERR(description))
                return PTR_ERR(description);
 
-       key = request_key_net(&key_type_keyring, description, sock_net(&rx->sk),
-                             NULL, NULL);
+       key = request_key_net(&key_type_keyring, description, sock_net(&rx->sk), NULL);
        if (IS_ERR(key)) {
                kfree(description);
                _leave(" = %ld", PTR_ERR(key));
@@ -984,8 +974,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
        _enter("");
 
        key = key_alloc(&key_type_rxrpc, "x",
-                       GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
-                       &internal_key_acl,
+                       GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0,
                        KEY_ALLOC_NOT_IN_QUOTA, NULL);
        if (IS_ERR(key)) {
                _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
@@ -1033,7 +1022,7 @@ struct key *rxrpc_get_null_key(const char *keyname)
 
        key = key_alloc(&key_type_rxrpc, keyname,
                        GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
-                       &rxrpc_null_key_acl, KEY_ALLOC_NOT_IN_QUOTA, NULL);
+                       KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL);
        if (IS_ERR(key))
                return key;
 
index 298fe91557f7984e386b13afec6d9d438cb736c3..4831ad745f912dd0e82e0a87b49414a175a28c68 100644 (file)
@@ -741,7 +741,8 @@ static void __init load_keys_from_buffer(const u8 *p, unsigned int buflen)
 
                key = key_create_or_update(make_key_ref(builtin_regdb_keys, 1),
                                           "asymmetric", 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);
@@ -767,7 +768,8 @@ static int __init load_builtin_regdb_keys(void)
        builtin_regdb_keys =
                keyring_alloc(".builtin_regdb_keys",
                              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, NULL, NULL);
        if (IS_ERR(builtin_regdb_keys))
                return PTR_ERR(builtin_regdb_keys);
index f9f3c8ffe7864e1f9b6441f0e6c1aa3cabdfc322..868ade3e89702ba7ec7831e03048498443c1e64e 100644 (file)
@@ -47,8 +47,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
 
        if (!keyring[id]) {
                keyring[id] =
-                       request_key(&key_type_keyring, keyring_name[id],
-                                   NULL, NULL);
+                       request_key(&key_type_keyring, keyring_name[id], NULL);
                if (IS_ERR(keyring[id])) {
                        int err = PTR_ERR(keyring[id]);
                        pr_err("no %s keyring: %d\n", keyring_name[id], err);
@@ -71,14 +70,14 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
 }
 
 static int __init __integrity_init_keyring(const unsigned int id,
-                                          struct key_acl *acl,
+                                          key_perm_t perm,
                                           struct key_restriction *restriction)
 {
        const struct cred *cred = current_cred();
        int err = 0;
 
        keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
-                                   KGIDT_INIT(0), cred, acl,
+                                   KGIDT_INIT(0), cred, perm,
                                    KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL);
        if (IS_ERR(keyring[id])) {
                err = PTR_ERR(keyring[id]);
@@ -96,7 +95,10 @@ static int __init __integrity_init_keyring(const unsigned int id,
 int __init integrity_init_keyring(const unsigned int id)
 {
        struct key_restriction *restriction;
-       struct key_acl *acl = &internal_keyring_acl;
+       key_perm_t perm;
+
+       perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
+               | KEY_USR_READ | KEY_USR_SEARCH;
 
        if (id == INTEGRITY_KEYRING_PLATFORM) {
                restriction = NULL;
@@ -111,14 +113,14 @@ int __init integrity_init_keyring(const unsigned int id)
                return -ENOMEM;
 
        restriction->check = restrict_link_to_ima;
-       acl = &internal_writable_keyring_acl;
+       perm |= KEY_USR_WRITE;
 
 out:
-       return __integrity_init_keyring(id, acl, restriction);
+       return __integrity_init_keyring(id, perm, restriction);
 }
 
-static int __init integrity_add_key(const unsigned int id, const void *data,
-                                   off_t size, struct key_acl *acl)
+int __init integrity_add_key(const unsigned int id, const void *data,
+                            off_t size, key_perm_t perm)
 {
        key_ref_t key;
        int rc = 0;
@@ -127,7 +129,7 @@ static int __init integrity_add_key(const unsigned int id, const void *data,
                return -EINVAL;
 
        key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric",
-                                  NULL, data, size, acl ?: &internal_key_acl,
+                                  NULL, data, size, perm,
                                   KEY_ALLOC_NOT_IN_QUOTA);
        if (IS_ERR(key)) {
                rc = PTR_ERR(key);
@@ -147,6 +149,7 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
        void *data;
        loff_t size;
        int rc;
+       key_perm_t perm;
 
        rc = kernel_read_file_from_path(path, &data, &size, 0,
                                        READING_X509_CERTIFICATE);
@@ -155,19 +158,21 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
                return rc;
        }
 
+       perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;
+
        pr_info("Loading X.509 certificate: %s\n", path);
-       rc = integrity_add_key(id, data, size, NULL);
+       rc = integrity_add_key(id, (const void *)data, size, perm);
 
        vfree(data);
        return rc;
 }
 
 int __init integrity_load_cert(const unsigned int id, const char *source,
-                              const void *data, size_t len, struct key_acl *acl)
+                              const void *data, size_t len, key_perm_t perm)
 {
        if (!data)
                return -EINVAL;
 
        pr_info("Loading X.509 certificate: %s\n", source);
-       return integrity_add_key(id, data, len, acl);
+       return integrity_add_key(id, data, len, perm);
 }
index a29df775fdd8db55b17ac9ed27985be33eface11..55aec161d0e1c9e73cda8fab91ca5442065162d2 100644 (file)
@@ -53,7 +53,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
                else
                        key = key_ref_to_ptr(kref);
        } else {
-               key = request_key(&key_type_asymmetric, name, NULL, NULL);
+               key = request_key(&key_type_asymmetric, name, NULL);
        }
 
        if (IS_ERR(key)) {
index 466eebd3b4aa47e96991acde531f0ef06df13755..d485f6fc908e50bc5857c39a51ade369a9cfedad 100644 (file)
@@ -356,7 +356,7 @@ int evm_init_key(void)
        struct encrypted_key_payload *ekp;
        int rc;
 
-       evm_key = request_key(&key_type_encrypted, EVMKEY, NULL, NULL);
+       evm_key = request_key(&key_type_encrypted, EVMKEY, NULL);
        if (IS_ERR(evm_key))
                return -ENOENT;
 
index b52ae1476ec3f0087d4a82ea2a1b290500e663dc..36cadadbfba47394ef9e2cee74b11e302107bc01 100644 (file)
 #include <keys/system_keyring.h>
 
 
-static struct key_acl integrity_blacklist_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_WRITE | KEY_ACE_SEARCH),
-       }
-};
-
 struct key *ima_blacklist_keyring;
 
 /*
@@ -44,7 +35,9 @@ __init int ima_mok_init(void)
 
        ima_blacklist_keyring = keyring_alloc(".ima_blacklist",
                                KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
-                               &integrity_blacklist_keyring_acl,
+                               (KEY_POS_ALL & ~KEY_POS_SETATTR) |
+                               KEY_USR_VIEW | KEY_USR_READ |
+                               KEY_USR_WRITE | KEY_USR_SEARCH,
                                KEY_ALLOC_NOT_IN_QUOTA,
                                restriction, NULL);
 
index 875c6a7a5af1a63113e838d86caa7112274cd77a..ed12d8e13d043c164425d0dff5be161a7143881f 100644 (file)
@@ -12,8 +12,6 @@
 #include <linux/key.h>
 #include <linux/audit.h>
 
-struct key_acl;
-
 /* iint action cache flags */
 #define IMA_MEASURE            0x00000001
 #define IMA_MEASURED           0x00000002
@@ -157,7 +155,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
 int __init integrity_init_keyring(const unsigned int id);
 int __init integrity_load_x509(const unsigned int id, const char *path);
 int __init integrity_load_cert(const unsigned int id, const char *source,
-                              const void *data, size_t len, struct key_acl *acl);
+                              const void *data, size_t len, key_perm_t perm);
 #else
 
 static inline int integrity_digsig_verify(const unsigned int id,
@@ -175,7 +173,7 @@ static inline int integrity_init_keyring(const unsigned int id)
 static inline int __init integrity_load_cert(const unsigned int id,
                                             const char *source,
                                             const void *data, size_t len,
-                                            struct key_acl *acl)
+                                            key_perm_t perm)
 {
        return 0;
 }
index 7646e35f2d91dbde140fd20a034cbd073b2203b9..bcafd73877296f17bb4dfc3c1bd6caa54ce9213b 100644 (file)
 #include <linux/slab.h>
 #include "../integrity.h"
 
-static struct key_acl platform_key_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .nr_ace = 2,
-       .aces = {
-               KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_READ),
-               KEY_OWNER_ACE(KEY_ACE_VIEW),
-       }
-};
-
 /**
  * add_to_platform_keyring - Add to platform keyring without validation.
  * @source: Source of key
@@ -35,10 +26,13 @@ static struct key_acl platform_key_acl = {
 void __init add_to_platform_keyring(const char *source, const void *data,
                                    size_t len)
 {
+       key_perm_t perm;
        int rc;
 
+       perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;
+
        rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, data, len,
-                                &platform_key_acl);
+                                perm);
        if (rc)
                pr_info("Error adding keys to platform keyring %s\n", source);
 }
index b0e59546e7bd1296c4fe9785d98625a0ad1b9c66..9bcc404131aa0d30c86045d2b24a03856e939398 100644 (file)
@@ -157,8 +157,6 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option,
 
        case KEYCTL_MOVE:
                return keyctl_keyring_move(arg2, arg3, arg4, arg5);
-       case KEYCTL_GRANT_PERMISSION:
-               return keyctl_grant_permission(arg2, arg3, arg4, arg5);
 
        case KEYCTL_CAPABILITIES:
                return keyctl_capabilities(compat_ptr(arg2), arg3);
index 9df560e477c2d90dc290a3ef190f0e24c6d2f13f..60720f58cbe015f2639805bce9cc366e13cfb3ee 100644 (file)
@@ -304,7 +304,7 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k
        const struct user_key_payload *upayload;
        struct key *ukey;
 
-       ukey = request_key(&key_type_user, master_desc, NULL, NULL);
+       ukey = request_key(&key_type_user, master_desc, NULL);
        if (IS_ERR(ukey))
                goto error;
 
index d649f2f29475fa2b4fd4cbbf8d5f4082cac3bac5..c68528aa49c6dc3369d3c36beba29687dec059be 100644 (file)
@@ -30,7 +30,7 @@ struct key *request_trusted_key(const char *trusted_desc,
        struct trusted_key_payload *tpayload;
        struct key *tkey;
 
-       tkey = request_key(&key_type_trusted, trusted_desc, NULL, NULL);
+       tkey = request_key(&key_type_trusted, trusted_desc, NULL);
        if (IS_ERR(tkey))
                goto error;
 
index 48c3e124c2729bcaf198841b381d56b096a6cc89..671dd730ecfc9e62395b2a7bf046f76f0f9ad313 100644 (file)
@@ -151,7 +151,6 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
 
                key_user_put(key->user);
                key_put_tag(key->domain_tag);
-               key_put_acl(rcu_access_pointer(key->acl));
                kfree(key->description);
 
                memzero_explicit(key, sizeof(*key));
@@ -221,6 +220,7 @@ continue_scanning:
                        if (key->type == key_gc_dead_keytype) {
                                gc_state |= KEY_GC_FOUND_DEAD_KEY;
                                set_bit(KEY_FLAG_DEAD, &key->flags);
+                               key->perm = 0;
                                goto skip_dead_key;
                        } else if (key->type == &key_type_keyring &&
                                   key->restrict_link) {
index e0c5bb8b16859ae089fb328ec16fd205500fd665..c039373488bd940d2a1c6dac919e46e586cd3002 100644 (file)
@@ -84,11 +84,8 @@ extern struct rb_root key_serial_tree;
 extern spinlock_t key_serial_lock;
 extern struct mutex key_construction_mutex;
 extern wait_queue_head_t request_key_conswq;
-extern struct key_acl default_key_acl;
-extern struct key_acl joinable_keyring_acl;
 
 extern void key_set_index_key(struct keyring_index_key *index_key);
-
 extern struct key_type *key_type_lookup(const char *type);
 extern void key_type_put(struct key_type *ktype);
 
@@ -159,7 +156,6 @@ extern struct key *request_key_and_link(struct key_type *type,
                                        const void *callout_info,
                                        size_t callout_len,
                                        void *aux,
-                                       struct key_acl *acl,
                                        struct key *dest_keyring,
                                        unsigned long flags);
 
@@ -183,10 +179,7 @@ extern void key_gc_keytype(struct key_type *ktype);
 
 extern int key_task_permission(const key_ref_t key_ref,
                               const struct cred *cred,
-                              u32 desired_perm);
-extern unsigned int key_acl_to_perm(const struct key_acl *acl);
-extern long key_set_acl(struct key *key, struct key_acl *acl);
-extern void key_put_acl(struct key_acl *acl);
+                              key_perm_t perm);
 
 /*
  * Check to see whether permission is granted to use a key in the desired way.
@@ -233,7 +226,7 @@ extern long keyctl_keyring_search(key_serial_t, const char __user *,
                                  const char __user *, key_serial_t);
 extern long keyctl_read_key(key_serial_t, char __user *, size_t);
 extern long keyctl_chown_key(key_serial_t, uid_t, gid_t);
-extern long keyctl_setperm_key(key_serial_t, unsigned int);
+extern long keyctl_setperm_key(key_serial_t, key_perm_t);
 extern long keyctl_instantiate_key(key_serial_t, const void __user *,
                                   size_t, key_serial_t);
 extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
@@ -338,11 +331,6 @@ static inline long keyctl_pkey_e_d_s(int op,
 
 extern long keyctl_capabilities(unsigned char __user *_buffer, size_t buflen);
 
-extern long keyctl_grant_permission(key_serial_t keyid,
-                                   enum key_ace_subject_type type,
-                                   unsigned int subject,
-                                   unsigned int perm);
-
 /*
  * Debugging key validation
  */
index 519211a996e713946c031354b9363bb6774c021a..764f4c57913e95ee5836e523079f7bdb30f6a695 100644 (file)
@@ -195,7 +195,7 @@ serial_exists:
  * @uid: The owner of the new key.
  * @gid: The group ID for the new key's group permissions.
  * @cred: The credentials specifying UID namespace.
- * @acl: The ACL to attach to the new key.
+ * @perm: The permissions mask of the new key.
  * @flags: Flags specifying quota properties.
  * @restrict_link: Optional link restriction for new keyrings.
  *
@@ -223,7 +223,7 @@ serial_exists:
  */
 struct key *key_alloc(struct key_type *type, const char *desc,
                      kuid_t uid, kgid_t gid, const struct cred *cred,
-                     struct key_acl *acl, unsigned long flags,
+                     key_perm_t perm, unsigned long flags,
                      struct key_restriction *restrict_link)
 {
        struct key_user *user = NULL;
@@ -246,9 +246,6 @@ struct key *key_alloc(struct key_type *type, const char *desc,
        desclen = strlen(desc);
        quotalen = desclen + 1 + type->def_datalen;
 
-       if (!acl)
-               acl = &default_key_acl;
-
        /* get hold of the key tracking for this user */
        user = key_user_lookup(uid);
        if (!user)
@@ -295,8 +292,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
        key->datalen = type->def_datalen;
        key->uid = uid;
        key->gid = gid;
-       refcount_inc(&acl->usage);
-       rcu_assign_pointer(key->acl, acl);
+       key->perm = perm;
        key->restrict_link = restrict_link;
        key->last_used_at = ktime_get_real_seconds();
 
@@ -791,7 +787,7 @@ error:
  * @description: The searchable description for the key.
  * @payload: The data to use to instantiate or update the key.
  * @plen: The length of @payload.
- * @acl: The ACL to attach if a key is created.
+ * @perm: The permissions mask for a new key.
  * @flags: The quota flags for a new key.
  *
  * Search the destination keyring for a key of the same description and if one
@@ -814,7 +810,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
                               const char *description,
                               const void *payload,
                               size_t plen,
-                              struct key_acl *acl,
+                              key_perm_t perm,
                               unsigned long flags)
 {
        struct keyring_index_key index_key = {
@@ -911,9 +907,22 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
                        goto found_matching_key;
        }
 
+       /* if the client doesn't provide, decide on the permissions we want */
+       if (perm == KEY_PERM_UNDEF) {
+               perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
+               perm |= KEY_USR_VIEW;
+
+               if (index_key.type->read)
+                       perm |= KEY_POS_READ;
+
+               if (index_key.type == &key_type_keyring ||
+                   index_key.type->update)
+                       perm |= KEY_POS_WRITE;
+       }
+
        /* allocate a new key */
        key = key_alloc(index_key.type, index_key.description,
-                       cred->fsuid, cred->fsgid, cred, acl, flags, NULL);
+                       cred->fsuid, cred->fsgid, cred, perm, flags, NULL);
        if (IS_ERR(key)) {
                key_ref = ERR_CAST(key);
                goto error_link_end;
index c2dd66d556d4a1612622c0b2e04b4b219e1f79c4..9b898c9695583da389c4129544081c334f679e26 100644 (file)
@@ -37,8 +37,7 @@ static const unsigned char keyrings_capabilities[2] = {
               KEYCTL_CAPS0_MOVE
               ),
        [1] = (KEYCTL_CAPS1_NS_KEYRING_NAME |
-              KEYCTL_CAPS1_NS_KEY_TAG |
-              KEYCTL_CAPS1_ACL_ALTERABLE),
+              KEYCTL_CAPS1_NS_KEY_TAG),
 };
 
 static int key_get_type_from_user(char *type,
@@ -131,7 +130,8 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
        /* create or update the requested key and add it to the target
         * keyring */
        key_ref = key_create_or_update(keyring_ref, type, description,
-                                      payload, plen, NULL, KEY_ALLOC_IN_QUOTA);
+                                      payload, plen, KEY_PERM_UNDEF,
+                                      KEY_ALLOC_IN_QUOTA);
        if (!IS_ERR(key_ref)) {
                ret = key_ref_to_ptr(key_ref)->serial;
                key_ref_put(key_ref);
@@ -221,8 +221,7 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
 
        /* do the search */
        key = request_key_and_link(ktype, description, NULL, callout_info,
-                                  callout_len, NULL, NULL,
-                                  key_ref_to_ptr(dest_ref),
+                                  callout_len, NULL, key_ref_to_ptr(dest_ref),
                                   KEY_ALLOC_IN_QUOTA);
        if (IS_ERR(key)) {
                ret = PTR_ERR(key);
@@ -384,10 +383,16 @@ long keyctl_revoke_key(key_serial_t id)
        struct key *key;
        long ret;
 
-       key_ref = lookup_user_key(id, 0, KEY_NEED_REVOKE);
+       key_ref = lookup_user_key(id, 0, KEY_NEED_WRITE);
        if (IS_ERR(key_ref)) {
                ret = PTR_ERR(key_ref);
-               goto error;
+               if (ret != -EACCES)
+                       goto error;
+               key_ref = lookup_user_key(id, 0, KEY_NEED_SETATTR);
+               if (IS_ERR(key_ref)) {
+                       ret = PTR_ERR(key_ref);
+                       goto error;
+               }
        }
 
        key = key_ref_to_ptr(key_ref);
@@ -421,7 +426,7 @@ long keyctl_invalidate_key(key_serial_t id)
 
        kenter("%d", id);
 
-       key_ref = lookup_user_key(id, 0, KEY_NEED_INVAL);
+       key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH);
        if (IS_ERR(key_ref)) {
                ret = PTR_ERR(key_ref);
 
@@ -466,7 +471,7 @@ long keyctl_keyring_clear(key_serial_t ringid)
        struct key *keyring;
        long ret;
 
-       keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_CLEAR);
+       keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
        if (IS_ERR(keyring_ref)) {
                ret = PTR_ERR(keyring_ref);
 
@@ -641,7 +646,6 @@ long keyctl_describe_key(key_serial_t keyid,
                         size_t buflen)
 {
        struct key *key, *instkey;
-       unsigned int perm;
        key_ref_t key_ref;
        char *infobuf;
        long ret;
@@ -671,10 +675,6 @@ okay:
        key = key_ref_to_ptr(key_ref);
        desclen = strlen(key->description);
 
-       rcu_read_lock();
-       perm = key_acl_to_perm(rcu_dereference(key->acl));
-       rcu_read_unlock();
-
        /* calculate how much information we're going to return */
        ret = -ENOMEM;
        infobuf = kasprintf(GFP_KERNEL,
@@ -682,7 +682,7 @@ okay:
                            key->type->name,
                            from_kuid_munged(current_user_ns(), key->uid),
                            from_kgid_munged(current_user_ns(), key->gid),
-                           perm);
+                           key->perm);
        if (!infobuf)
                goto error2;
        infolen = strlen(infobuf);
@@ -899,7 +899,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
                goto error;
 
        key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
-                                 KEY_NEED_SETSEC);
+                                 KEY_NEED_SETATTR);
        if (IS_ERR(key_ref)) {
                ret = PTR_ERR(key_ref);
                goto error;
@@ -994,25 +994,18 @@ quota_overrun:
  * the key need not be fully instantiated yet.  If the caller does not have
  * sysadmin capability, it may only change the permission on keys that it owns.
  */
-long keyctl_setperm_key(key_serial_t id, unsigned int perm)
+long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
 {
-       struct key_acl *acl;
        struct key *key;
        key_ref_t key_ref;
        long ret;
-       int nr, i, j;
 
+       ret = -EINVAL;
        if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
-               return -EINVAL;
-
-       nr = 0;
-       if (perm & KEY_POS_ALL) nr++;
-       if (perm & KEY_USR_ALL) nr++;
-       if (perm & KEY_GRP_ALL) nr++;
-       if (perm & KEY_OTH_ALL) nr++;
+               goto error;
 
        key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
-                                 KEY_NEED_SETSEC);
+                                 KEY_NEED_SETATTR);
        if (IS_ERR(key_ref)) {
                ret = PTR_ERR(key_ref);
                goto error;
@@ -1020,45 +1013,17 @@ long keyctl_setperm_key(key_serial_t id, unsigned int perm)
 
        key = key_ref_to_ptr(key_ref);
 
-       ret = -EOPNOTSUPP;
-       if (test_bit(KEY_FLAG_HAS_ACL, &key->flags))
-               goto error_key;
+       /* make the changes with the locks held to prevent chown/chmod races */
+       ret = -EACCES;
+       down_write(&key->sem);
 
-       ret = -ENOMEM;
-       acl = kzalloc(struct_size(acl, aces, nr), GFP_KERNEL);
-       if (!acl)
-               goto error_key;
-
-       refcount_set(&acl->usage, 1);
-       acl->nr_ace = nr;
-       j = 0;
-       for (i = 0; i < 4; i++) {
-               struct key_ace *ace = &acl->aces[j];
-               unsigned int subset = (perm >> (i * 8)) & KEY_OTH_ALL;
-
-               if (!subset)
-                       continue;
-               ace->type = KEY_ACE_SUBJ_STANDARD;
-               ace->subject_id = KEY_ACE_EVERYONE + i;
-               ace->perm = subset;
-               if (subset & (KEY_OTH_WRITE | KEY_OTH_SETATTR))
-                       ace->perm |= KEY_ACE_REVOKE;
-               if (subset & KEY_OTH_SEARCH)
-                       ace->perm |= KEY_ACE_INVAL;
-               if (key->type == &key_type_keyring) {
-                       if (subset & KEY_OTH_SEARCH)
-                               ace->perm |= KEY_ACE_JOIN;
-                       if (subset & KEY_OTH_WRITE)
-                               ace->perm |= KEY_ACE_CLEAR;
-               }
-               j++;
+       /* if we're not the sysadmin, we can only change a key that we own */
+       if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) {
+               key->perm = perm;
+               ret = 0;
        }
 
-       /* make the changes with the locks held to prevent chown/chmod races */
-       down_write(&key->sem);
-       ret = key_set_acl(key, acl);
        up_write(&key->sem);
-error_key:
        key_put(key);
 error:
        return ret;
@@ -1423,7 +1388,7 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout)
        long ret;
 
        key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
-                                 KEY_NEED_SETSEC);
+                                 KEY_NEED_SETATTR);
        if (IS_ERR(key_ref)) {
                /* setting the timeout on a key under construction is permitted
                 * if we have the authorisation token handy */
@@ -1574,7 +1539,7 @@ long keyctl_get_security(key_serial_t keyid,
  * Attempt to install the calling process's session keyring on the process's
  * parent process.
  *
- * The keyring must exist and must grant the caller JOIN permission, and the
+ * The keyring must exist and must grant the caller LINK permission, and the
  * parent process must be single-threaded and must have the same effective
  * ownership as this process and mustn't be SUID/SGID.
  *
@@ -1591,7 +1556,7 @@ long keyctl_session_to_parent(void)
        struct cred *cred;
        int ret;
 
-       keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_NEED_JOIN);
+       keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_NEED_LINK);
        if (IS_ERR(keyring_r))
                return PTR_ERR(keyring_r);
 
@@ -1693,7 +1658,7 @@ long keyctl_restrict_keyring(key_serial_t id, const char __user *_type,
        char *restriction = NULL;
        long ret;
 
-       key_ref = lookup_user_key(id, 0, KEY_NEED_SETSEC);
+       key_ref = lookup_user_key(id, 0, KEY_NEED_SETATTR);
        if (IS_ERR(key_ref))
                return PTR_ERR(key_ref);
 
@@ -1799,7 +1764,7 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
 
        case KEYCTL_SETPERM:
                return keyctl_setperm_key((key_serial_t) arg2,
-                                         (unsigned int)arg3);
+                                         (key_perm_t) arg3);
 
        case KEYCTL_INSTANTIATE:
                return keyctl_instantiate_key((key_serial_t) arg2,
@@ -1888,11 +1853,6 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
                                           (key_serial_t)arg3,
                                           (key_serial_t)arg4,
                                           (unsigned int)arg5);
-       case KEYCTL_GRANT_PERMISSION:
-               return keyctl_grant_permission((key_serial_t)arg2,
-                                              (enum key_ace_subject_type)arg3,
-                                              (unsigned int)arg4,
-                                              (unsigned int)arg5);
 
        case KEYCTL_CAPABILITIES:
                return keyctl_capabilities((unsigned char __user *)arg2, (size_t)arg3);
index 3b5458f23a954f54415ac1bfebc0316a0767f739..febf36c6ddc5dbc06098dd5913f77fba115f78bf 100644 (file)
@@ -515,19 +515,11 @@ static long keyring_read(const struct key *keyring,
        return ret;
 }
 
-/**
- * keyring_alloc - Allocate a keyring and link into the destination
- * @description: The key description to allow the key to be searched out.
- * @uid: The owner of the new key.
- * @gid: The group ID for the new key's group permissions.
- * @cred: The credentials specifying UID namespace.
- * @acl: The ACL to attach to the new key.
- * @flags: Flags specifying quota properties.
- * @restrict_link: Optional link restriction for new keyrings.
- * @dest: Destination keyring.
+/*
+ * Allocate a keyring and link into the destination keyring.
  */
 struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
-                         const struct cred *cred, struct key_acl *acl,
+                         const struct cred *cred, key_perm_t perm,
                          unsigned long flags,
                          struct key_restriction *restrict_link,
                          struct key *dest)
@@ -536,7 +528,7 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
        int ret;
 
        keyring = key_alloc(&key_type_keyring, description,
-                           uid, gid, cred, acl, flags, restrict_link);
+                           uid, gid, cred, perm, flags, restrict_link);
        if (!IS_ERR(keyring)) {
                ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
                if (ret < 0) {
@@ -1140,11 +1132,10 @@ found:
 /*
  * Find a keyring with the specified name.
  *
- * Only keyrings that have nonzero refcount, are not revoked, and are owned by
- * a user in the current user namespace are considered.  If @uid_keyring is
- * %true, the keyring additionally must have been allocated as a user or user
- * session keyring; otherwise, it must grant JOIN permission directly to the
- * caller (ie. not through possession).
+ * Only keyrings that have nonzero refcount, are not revoked, and are owned by a
+ * user in the current user namespace are considered.  If @uid_keyring is %true,
+ * the keyring additionally must have been allocated as a user or user session
+ * keyring; otherwise, it must grant Search permission directly to the caller.
  *
  * Returns a pointer to the keyring with the keyring's refcount having being
  * incremented on success.  -ENOKEY is returned if a key could not be found.
@@ -1178,7 +1169,7 @@ struct key *find_keyring_by_name(const char *name, bool uid_keyring)
                                continue;
                } else {
                        if (key_permission(make_key_ref(keyring, 0),
-                                          KEY_NEED_JOIN) < 0)
+                                          KEY_NEED_SEARCH) < 0)
                                continue;
                }
 
index fd8a5dc6910ae2bc6baa0e129461c9096f744bad..085f907b64ac5c4161fe188a599354103ec3ff88 100644 (file)
@@ -7,67 +7,13 @@
 
 #include <linux/export.h>
 #include <linux/security.h>
-#include <linux/user_namespace.h>
-#include <linux/uaccess.h>
 #include "internal.h"
 
-struct key_acl default_key_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .nr_ace = 2,
-       .possessor_viewable = true,
-       .aces = {
-               KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~KEY_ACE_JOIN),
-               KEY_OWNER_ACE(KEY_ACE_VIEW),
-       }
-};
-EXPORT_SYMBOL(default_key_acl);
-
-struct key_acl joinable_keyring_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .nr_ace = 2,
-       .possessor_viewable = true,
-       .aces   = {
-               KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~KEY_ACE_JOIN),
-               KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_LINK | KEY_ACE_JOIN),
-       }
-};
-EXPORT_SYMBOL(joinable_keyring_acl);
-
-struct key_acl internal_key_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .nr_ace = 2,
-       .aces = {
-               KEY_POSSESSOR_ACE(KEY_ACE_SEARCH),
-               KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_SEARCH),
-       }
-};
-EXPORT_SYMBOL(internal_key_acl);
-
-struct key_acl internal_keyring_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .nr_ace = 2,
-       .aces = {
-               KEY_POSSESSOR_ACE(KEY_ACE_SEARCH),
-               KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_SEARCH),
-       }
-};
-EXPORT_SYMBOL(internal_keyring_acl);
-
-struct key_acl internal_writable_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_WRITE | KEY_ACE_SEARCH),
-       }
-};
-EXPORT_SYMBOL(internal_writable_keyring_acl);
-
 /**
  * key_task_permission - Check a key can be used
  * @key_ref: The key to check.
  * @cred: The credentials to use.
- * @desired_perm: The permission to check for.
+ * @perm: The permissions to check for.
  *
  * Check to see whether permission is granted to use a key in the desired way,
  * but permit the security modules to override.
@@ -78,73 +24,53 @@ EXPORT_SYMBOL(internal_writable_keyring_acl);
  * permissions bits or the LSM check.
  */
 int key_task_permission(const key_ref_t key_ref, const struct cred *cred,
-                       unsigned int desired_perm)
+                       unsigned perm)
 {
-       const struct key_acl *acl;
-       const struct key *key;
-       unsigned int allow = 0;
-       int i;
-
-       BUILD_BUG_ON(KEY_NEED_VIEW      != KEY_ACE_VIEW         ||
-                    KEY_NEED_READ      != KEY_ACE_READ         ||
-                    KEY_NEED_WRITE     != KEY_ACE_WRITE        ||
-                    KEY_NEED_SEARCH    != KEY_ACE_SEARCH       ||
-                    KEY_NEED_LINK      != KEY_ACE_LINK         ||
-                    KEY_NEED_SETSEC    != KEY_ACE_SET_SECURITY ||
-                    KEY_NEED_INVAL     != KEY_ACE_INVAL        ||
-                    KEY_NEED_REVOKE    != KEY_ACE_REVOKE       ||
-                    KEY_NEED_JOIN      != KEY_ACE_JOIN         ||
-                    KEY_NEED_CLEAR     != KEY_ACE_CLEAR);
+       struct key *key;
+       key_perm_t kperm;
+       int ret;
 
        key = key_ref_to_ptr(key_ref);
 
-       rcu_read_lock();
-
-       acl = rcu_dereference(key->acl);
-       if (!acl || acl->nr_ace == 0)
-               goto no_access_rcu;
+       /* use the second 8-bits of permissions for keys the caller owns */
+       if (uid_eq(key->uid, cred->fsuid)) {
+               kperm = key->perm >> 16;
+               goto use_these_perms;
+       }
 
-       for (i = 0; i < acl->nr_ace; i++) {
-               const struct key_ace *ace = &acl->aces[i];
+       /* use the third 8-bits of permissions for keys the caller has a group
+        * membership in common with */
+       if (gid_valid(key->gid) && key->perm & KEY_GRP_ALL) {
+               if (gid_eq(key->gid, cred->fsgid)) {
+                       kperm = key->perm >> 8;
+                       goto use_these_perms;
+               }
 
-               switch (ace->type) {
-               case KEY_ACE_SUBJ_STANDARD:
-                       switch (ace->subject_id) {
-                       case KEY_ACE_POSSESSOR:
-                               if (is_key_possessed(key_ref))
-                                       allow |= ace->perm;
-                               break;
-                       case KEY_ACE_OWNER:
-                               if (uid_eq(key->uid, cred->fsuid))
-                                       allow |= ace->perm;
-                               break;
-                       case KEY_ACE_GROUP:
-                               if (gid_valid(key->gid)) {
-                                       if (gid_eq(key->gid, cred->fsgid))
-                                               allow |= ace->perm;
-                                       else if (groups_search(cred->group_info, key->gid))
-                                               allow |= ace->perm;
-                               }
-                               break;
-                       case KEY_ACE_EVERYONE:
-                               allow |= ace->perm;
-                               break;
-                       }
-                       break;
+               ret = groups_search(cred->group_info, key->gid);
+               if (ret) {
+                       kperm = key->perm >> 8;
+                       goto use_these_perms;
                }
        }
 
-       rcu_read_unlock();
+       /* otherwise use the least-significant 8-bits */
+       kperm = key->perm;
+
+use_these_perms:
 
-       if (!(allow & desired_perm))
-               goto no_access;
+       /* use the top 8-bits of permissions for keys the caller possesses
+        * - possessor permissions are additive with other permissions
+        */
+       if (is_key_possessed(key_ref))
+               kperm |= key->perm >> 24;
 
-       return security_key_permission(key_ref, cred, desired_perm);
+       kperm = kperm & perm & KEY_NEED_ALL;
 
-no_access_rcu:
-       rcu_read_unlock();
-no_access:
-       return -EACCES;
+       if (kperm != perm)
+               return -EACCES;
+
+       /* let LSM be the final arbiter */
+       return security_key_permission(key_ref, cred, perm);
 }
 EXPORT_SYMBOL(key_task_permission);
 
@@ -178,218 +104,3 @@ int key_validate(const struct key *key)
        return 0;
 }
 EXPORT_SYMBOL(key_validate);
-
-/*
- * Roughly render an ACL to an old-style permissions mask.  We cannot
- * accurately render what the ACL, particularly if it has ACEs that represent
- * subjects outside of { poss, user, group, other }.
- */
-unsigned int key_acl_to_perm(const struct key_acl *acl)
-{
-       unsigned int perm = 0, tperm;
-       int i;
-
-       BUILD_BUG_ON(KEY_OTH_VIEW       != KEY_ACE_VIEW         ||
-                    KEY_OTH_READ       != KEY_ACE_READ         ||
-                    KEY_OTH_WRITE      != KEY_ACE_WRITE        ||
-                    KEY_OTH_SEARCH     != KEY_ACE_SEARCH       ||
-                    KEY_OTH_LINK       != KEY_ACE_LINK         ||
-                    KEY_OTH_SETATTR    != KEY_ACE_SET_SECURITY);
-
-       if (!acl || acl->nr_ace == 0)
-               return 0;
-
-       for (i = 0; i < acl->nr_ace; i++) {
-               const struct key_ace *ace = &acl->aces[i];
-
-               switch (ace->type) {
-               case KEY_ACE_SUBJ_STANDARD:
-                       tperm = ace->perm & KEY_OTH_ALL;
-
-                       /* Invalidation and joining were allowed by SEARCH */
-                       if (ace->perm & (KEY_ACE_INVAL | KEY_ACE_JOIN))
-                               tperm |= KEY_OTH_SEARCH;
-
-                       /* Revocation was allowed by either SETATTR or WRITE */
-                       if ((ace->perm & KEY_ACE_REVOKE) && !(tperm & KEY_OTH_SETATTR))
-                               tperm |= KEY_OTH_WRITE;
-
-                       /* Clearing was allowed by WRITE */
-                       if (ace->perm & KEY_ACE_CLEAR)
-                               tperm |= KEY_OTH_WRITE;
-
-                       switch (ace->subject_id) {
-                       case KEY_ACE_POSSESSOR:
-                               perm |= tperm << 24;
-                               break;
-                       case KEY_ACE_OWNER:
-                               perm |= tperm << 16;
-                               break;
-                       case KEY_ACE_GROUP:
-                               perm |= tperm << 8;
-                               break;
-                       case KEY_ACE_EVERYONE:
-                               perm |= tperm << 0;
-                               break;
-                       }
-               }
-       }
-
-       return perm;
-}
-
-/*
- * Destroy a key's ACL.
- */
-void key_put_acl(struct key_acl *acl)
-{
-       if (acl && refcount_dec_and_test(&acl->usage))
-               kfree_rcu(acl, rcu);
-}
-
-/*
- * Try to set the ACL.  This either attaches or discards the proposed ACL.
- */
-long key_set_acl(struct key *key, struct key_acl *acl)
-{
-       int i;
-
-       /* If we're not the sysadmin, we can only change a key that we own. */
-       if (!capable(CAP_SYS_ADMIN) && !uid_eq(key->uid, current_fsuid())) {
-               key_put_acl(acl);
-               return -EACCES;
-       }
-
-       for (i = 0; i < acl->nr_ace; i++) {
-               const struct key_ace *ace = &acl->aces[i];
-               if (ace->type == KEY_ACE_SUBJ_STANDARD &&
-                   ace->subject_id == KEY_ACE_POSSESSOR) {
-                       if (ace->perm & KEY_ACE_VIEW)
-                               acl->possessor_viewable = true;
-                       break;
-               }
-       }
-
-       rcu_swap_protected(key->acl, acl, lockdep_is_held(&key->sem));
-       key_put_acl(acl);
-       return 0;
-}
-
-/*
- * Allocate a new ACL with an extra ACE slot.
- */
-static struct key_acl *key_alloc_acl(const struct key_acl *old_acl, int nr, int skip)
-{
-       struct key_acl *acl;
-       int nr_ace, i, j = 0;
-
-       nr_ace = old_acl->nr_ace + nr;
-       if (nr_ace > 16)
-               return ERR_PTR(-EINVAL);
-
-       acl = kzalloc(struct_size(acl, aces, nr_ace), GFP_KERNEL);
-       if (!acl)
-               return ERR_PTR(-ENOMEM);
-
-       refcount_set(&acl->usage, 1);
-       acl->nr_ace = nr_ace;
-       for (i = 0; i < old_acl->nr_ace; i++) {
-               if (i == skip)
-                       continue;
-               acl->aces[j] = old_acl->aces[i];
-               j++;
-       }
-       return acl;
-}
-
-/*
- * Generate the revised ACL.
- */
-static long key_change_acl(struct key *key, struct key_ace *new_ace)
-{
-       struct key_acl *acl, *old;
-       int i;
-
-       old = rcu_dereference_protected(key->acl, lockdep_is_held(&key->sem));
-
-       for (i = 0; i < old->nr_ace; i++)
-               if (old->aces[i].type == new_ace->type &&
-                   old->aces[i].subject_id == new_ace->subject_id)
-                       goto found_match;
-
-       if (new_ace->perm == 0)
-               return 0; /* No permissions to remove.  Add deny record? */
-
-       acl = key_alloc_acl(old, 1, -1);
-       if (IS_ERR(acl))
-               return PTR_ERR(acl);
-       acl->aces[i] = *new_ace;
-       goto change;
-
-found_match:
-       if (new_ace->perm == 0)
-               goto delete_ace;
-       if (new_ace->perm == old->aces[i].perm)
-               return 0;
-       acl = key_alloc_acl(old, 0, -1);
-       if (IS_ERR(acl))
-               return PTR_ERR(acl);
-       acl->aces[i].perm = new_ace->perm;
-       goto change;
-
-delete_ace:
-       acl = key_alloc_acl(old, -1, i);
-       if (IS_ERR(acl))
-               return PTR_ERR(acl);
-       goto change;
-
-change:
-       return key_set_acl(key, acl);
-}
-
-/*
- * Add, alter or remove (if perm == 0) an ACE in a key's ACL.
- */
-long keyctl_grant_permission(key_serial_t keyid,
-                            enum key_ace_subject_type type,
-                            unsigned int subject,
-                            unsigned int perm)
-{
-       struct key_ace new_ace;
-       struct key *key;
-       key_ref_t key_ref;
-       long ret;
-
-       new_ace.type = type;
-       new_ace.perm = perm;
-
-       switch (type) {
-       case KEY_ACE_SUBJ_STANDARD:
-               if (subject >= nr__key_ace_standard_subject)
-                       return -ENOENT;
-               new_ace.subject_id = subject;
-               break;
-
-       default:
-               return -ENOENT;
-       }
-
-       key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_SETSEC);
-       if (IS_ERR(key_ref)) {
-               ret = PTR_ERR(key_ref);
-               goto error;
-       }
-
-       key = key_ref_to_ptr(key_ref);
-
-       down_write(&key->sem);
-
-       /* If we're not the sysadmin, we can only change a key that we own */
-       ret = -EACCES;
-       if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid()))
-               ret = key_change_acl(key, &new_ace);
-       up_write(&key->sem);
-       key_put(key);
-error:
-       return ret;
-}
index 8171c90d4c9a793abdc86f4bc3ff470582f5a2a9..97af230aa4b22b3667e7098558bdff933a7b5bb4 100644 (file)
 
 unsigned persistent_keyring_expiry = 3 * 24 * 3600; /* Expire after 3 days of non-use */
 
-static struct key_acl persistent_register_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 key_acl persistent_keyring_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .nr_ace = 2,
-       .possessor_viewable = true,
-       .aces = {
-               KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_WRITE |
-                                 KEY_ACE_SEARCH | KEY_ACE_LINK |
-                                 KEY_ACE_CLEAR | KEY_ACE_INVAL),
-               KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
-       }
-};
-
 /*
  * Create the persistent keyring register for the current user namespace.
  *
@@ -43,7 +22,8 @@ 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(),
-                                       &persistent_register_keyring_acl,
+                                       ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
+                                        KEY_USR_VIEW | KEY_USR_READ),
                                        KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
        if (IS_ERR(reg))
                return PTR_ERR(reg);
@@ -76,7 +56,8 @@ static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
 
        persistent = keyring_alloc(index_key->description,
                                   uid, INVALID_GID, current_cred(),
-                                  &persistent_keyring_acl,
+                                  ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
+                                   KEY_USR_VIEW | KEY_USR_READ),
                                   KEY_ALLOC_NOT_IN_QUOTA, NULL,
                                   ns->persistent_keyring_register);
        if (IS_ERR(persistent))
index b394ad1e874b4c4ffceae2a3eb6653ef2b075ae6..415f3f1c2da042f794608522aeddd772fc706011 100644 (file)
@@ -110,13 +110,11 @@ static struct key *find_ge_key(struct seq_file *p, key_serial_t id)
 }
 
 static void *proc_keys_start(struct seq_file *p, loff_t *_pos)
-       __acquires(rcu)
        __acquires(key_serial_lock)
 {
        key_serial_t pos = *_pos;
        struct key *key;
 
-       rcu_read_lock();
        spin_lock(&key_serial_lock);
 
        if (*_pos > INT_MAX)
@@ -146,15 +144,12 @@ static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos)
 
 static void proc_keys_stop(struct seq_file *p, void *v)
        __releases(key_serial_lock)
-       __releases(rcu)
 {
        spin_unlock(&key_serial_lock);
-       rcu_read_unlock();
 }
 
 static int proc_keys_show(struct seq_file *m, void *v)
 {
-       const struct key_acl *acl;
        struct rb_node *_p = v;
        struct key *key = rb_entry(_p, struct key, serial_node);
        unsigned long flags;
@@ -162,7 +157,6 @@ static int proc_keys_show(struct seq_file *m, void *v)
        time64_t now, expiry;
        char xbuf[16];
        short state;
-       bool check_pos;
        u64 timo;
        int rc;
 
@@ -176,15 +170,15 @@ static int proc_keys_show(struct seq_file *m, void *v)
                                           KEYRING_SEARCH_RECURSE),
        };
 
-       acl = rcu_dereference(key->acl);
-       check_pos = acl->possessor_viewable;
+       key_ref = make_key_ref(key, 0);
 
        /* determine if the key is possessed by this process (a test we can
         * skip if the key does not indicate the possessor can view it
         */
-       key_ref = make_key_ref(key, 0);
-       if (check_pos) {
+       if (key->perm & KEY_POS_VIEW) {
+               rcu_read_lock();
                skey_ref = search_cred_keyrings_rcu(&ctx);
+               rcu_read_unlock();
                if (!IS_ERR(skey_ref)) {
                        key_ref_put(skey_ref);
                        key_ref = make_key_ref(key, 1);
@@ -194,10 +188,12 @@ static int proc_keys_show(struct seq_file *m, void *v)
        /* check whether the current task is allowed to view the key */
        rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW);
        if (rc < 0)
-               goto out;
+               return 0;
 
        now = ktime_get_real_seconds();
 
+       rcu_read_lock();
+
        /* come up with a suitable timeout value */
        expiry = READ_ONCE(key->expiry);
        if (expiry == 0) {
@@ -236,7 +232,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
                   showflag(flags, 'i', KEY_FLAG_INVALIDATED),
                   refcount_read(&key->usage),
                   xbuf,
-                  key_acl_to_perm(acl),
+                  key->perm,
                   from_kuid_munged(seq_user_ns(m), key->uid),
                   from_kgid_munged(seq_user_ns(m), key->gid),
                   key->type->name);
@@ -247,7 +243,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
                key->type->describe(key, m);
        seq_putc(m, '\n');
 
-out:
+       rcu_read_unlock();
        return 0;
 }
 
index aa3bfcadbc6600c0a2a1eba14704aa0bcd726c19..09541de31f2f14def6209b939cd1f3e9b3447c18 100644 (file)
@@ -32,47 +32,6 @@ struct key_user root_key_user = {
        .uid            = GLOBAL_ROOT_UID,
 };
 
-static struct key_acl user_reg_keyring_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .possessor_viewable = true,
-       .nr_ace = 2,
-       .aces = {
-               KEY_POSSESSOR_ACE(KEY_ACE_WRITE | KEY_ACE_SEARCH),
-               KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
-       }
-};
-
-static struct key_acl user_keyring_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .possessor_viewable = true,
-       .nr_ace = 2,
-       .aces = {
-               KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_WRITE |
-                                 KEY_ACE_SEARCH | KEY_ACE_LINK),
-               KEY_OWNER_ACE(KEY_ACE__PERMS & ~(KEY_ACE_JOIN | KEY_ACE_SET_SECURITY)),
-       }
-};
-
-static struct key_acl session_keyring_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .possessor_viewable = true,
-       .nr_ace = 2,
-       .aces = {
-               KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~KEY_ACE_JOIN),
-               KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
-       }
-};
-
-static struct key_acl thread_and_process_keyring_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .possessor_viewable = true,
-       .nr_ace = 2,
-       .aces = {
-               KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~(KEY_ACE_JOIN | KEY_ACE_SET_SECURITY)),
-               KEY_OWNER_ACE(KEY_ACE_VIEW),
-       }
-};
-
 /*
  * Get or create a user register keyring.
  */
@@ -92,8 +51,11 @@ static struct key *get_user_register(struct user_namespace *user_ns)
        if (!reg_keyring) {
                reg_keyring = keyring_alloc(".user_reg",
                                            user_ns->owner, INVALID_GID,
-                                           &init_cred, &user_reg_keyring_acl,
-                                           0, NULL, NULL);
+                                           &init_cred,
+                                           KEY_POS_WRITE | KEY_POS_SEARCH |
+                                           KEY_USR_VIEW | KEY_USR_READ,
+                                           0,
+                                           NULL, NULL);
                if (!IS_ERR(reg_keyring))
                        smp_store_release(&user_ns->user_keyring_register,
                                          reg_keyring);
@@ -115,11 +77,14 @@ int look_up_user_keyrings(struct key **_user_keyring,
        const struct cred *cred = current_cred();
        struct user_namespace *user_ns = current_user_ns();
        struct key *reg_keyring, *uid_keyring, *session_keyring;
+       key_perm_t user_keyring_perm;
        key_ref_t uid_keyring_r, session_keyring_r;
        uid_t uid = from_kuid(user_ns, cred->user->uid);
        char buf[20];
        int ret;
 
+       user_keyring_perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL;
+
        kenter("%u", uid);
 
        reg_keyring = get_user_register(user_ns);
@@ -139,7 +104,7 @@ int look_up_user_keyrings(struct key **_user_keyring,
        kdebug("_uid %p", uid_keyring_r);
        if (uid_keyring_r == ERR_PTR(-EAGAIN)) {
                uid_keyring = keyring_alloc(buf, cred->user->uid, INVALID_GID,
-                                           cred, &user_keyring_acl,
+                                           cred, user_keyring_perm,
                                            KEY_ALLOC_UID_KEYRING |
                                            KEY_ALLOC_IN_QUOTA,
                                            NULL, reg_keyring);
@@ -161,7 +126,7 @@ int look_up_user_keyrings(struct key **_user_keyring,
        kdebug("_uid_ses %p", session_keyring_r);
        if (session_keyring_r == ERR_PTR(-EAGAIN)) {
                session_keyring = keyring_alloc(buf, cred->user->uid, INVALID_GID,
-                                               cred, &user_keyring_acl,
+                                               cred, user_keyring_perm,
                                                KEY_ALLOC_UID_KEYRING |
                                                KEY_ALLOC_IN_QUOTA,
                                                NULL, NULL);
@@ -261,7 +226,7 @@ int install_thread_keyring_to_cred(struct cred *new)
                return 0;
 
        keyring = keyring_alloc("_tid", new->uid, new->gid, new,
-                               &thread_and_process_keyring_acl,
+                               KEY_POS_ALL | KEY_USR_VIEW,
                                KEY_ALLOC_QUOTA_OVERRUN,
                                NULL, NULL);
        if (IS_ERR(keyring))
@@ -308,7 +273,7 @@ int install_process_keyring_to_cred(struct cred *new)
                return 0;
 
        keyring = keyring_alloc("_pid", new->uid, new->gid, new,
-                               &thread_and_process_keyring_acl,
+                               KEY_POS_ALL | KEY_USR_VIEW,
                                KEY_ALLOC_QUOTA_OVERRUN,
                                NULL, NULL);
        if (IS_ERR(keyring))
@@ -363,7 +328,8 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
                        flags = KEY_ALLOC_IN_QUOTA;
 
                keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred,
-                                       &session_keyring_acl, flags, NULL, NULL);
+                                       KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
+                                       flags, NULL, NULL);
                if (IS_ERR(keyring))
                        return PTR_ERR(keyring);
        } else {
@@ -643,7 +609,7 @@ bool lookup_user_key_possessed(const struct key *key,
  * returned key reference.
  */
 key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
-                         unsigned int desired_perm)
+                         key_perm_t perm)
 {
        struct keyring_search_context ctx = {
                .match_data.cmp         = lookup_user_key_possessed,
@@ -818,12 +784,12 @@ try_again:
                case -ERESTARTSYS:
                        goto invalid_key;
                default:
-                       if (desired_perm)
+                       if (perm)
                                goto invalid_key;
                case 0:
                        break;
                }
-       } else if (desired_perm) {
+       } else if (perm) {
                ret = key_validate(key);
                if (ret < 0)
                        goto invalid_key;
@@ -835,11 +801,9 @@ try_again:
                goto invalid_key;
 
        /* check the permissions */
-       if (desired_perm) {
-               ret = key_task_permission(key_ref, ctx.cred, desired_perm);
-               if (ret < 0)
-                       goto invalid_key;
-       }
+       ret = key_task_permission(key_ref, ctx.cred, perm);
+       if (ret < 0)
+               goto invalid_key;
 
        key->last_used_at = ktime_get_real_seconds();
 
@@ -904,13 +868,13 @@ long join_session_keyring(const char *name)
        if (PTR_ERR(keyring) == -ENOKEY) {
                /* not found - try and create a new one */
                keyring = keyring_alloc(
-                       name, old->uid, old->gid, old, &joinable_keyring_acl,
+                       name, old->uid, old->gid, old,
+                       KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK,
                        KEY_ALLOC_IN_QUOTA, NULL, NULL);
                if (IS_ERR(keyring)) {
                        ret = PTR_ERR(keyring);
                        goto error2;
                }
-               goto no_perm_test;
        } else if (IS_ERR(keyring)) {
                ret = PTR_ERR(keyring);
                goto error2;
@@ -919,12 +883,6 @@ long join_session_keyring(const char *name)
                goto error3;
        }
 
-       ret = key_task_permission(make_key_ref(keyring, false), old,
-                                 KEY_NEED_JOIN);
-       if (ret < 0)
-               goto error3;
-
-no_perm_test:
        /* we've got a keyring - now to install it */
        ret = install_session_keyring_to_cred(new, keyring);
        if (ret < 0)
index 46c5187ce03fa4483fbe6ea7cd67991be15b5a00..7325f382dbf43b5660d0f3938e0ce18b737bed6e 100644 (file)
@@ -135,7 +135,8 @@ static int call_sbin_request_key(struct key *authkey, void *aux)
 
        cred = get_current_cred();
        keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
-                               NULL, KEY_ALLOC_QUOTA_OVERRUN, NULL, NULL);
+                               KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
+                               KEY_ALLOC_QUOTA_OVERRUN, NULL, NULL);
        put_cred(cred);
        if (IS_ERR(keyring)) {
                ret = PTR_ERR(keyring);
@@ -366,11 +367,11 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
                               struct key *dest_keyring,
                               unsigned long flags,
                               struct key_user *user,
-                              struct key_acl *acl,
                               struct key **_key)
 {
        struct assoc_array_edit *edit = NULL;
        struct key *key;
+       key_perm_t perm;
        key_ref_t key_ref;
        int ret;
 
@@ -380,9 +381,17 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
        *_key = NULL;
        mutex_lock(&user->cons_lock);
 
+       perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
+       perm |= KEY_USR_VIEW;
+       if (ctx->index_key.type->read)
+               perm |= KEY_POS_READ;
+       if (ctx->index_key.type == &key_type_keyring ||
+           ctx->index_key.type->update)
+               perm |= KEY_POS_WRITE;
+
        key = key_alloc(ctx->index_key.type, ctx->index_key.description,
                        ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred,
-                       acl, flags, NULL);
+                       perm, flags, NULL);
        if (IS_ERR(key))
                goto alloc_failed;
 
@@ -465,7 +474,6 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx,
                                          const char *callout_info,
                                          size_t callout_len,
                                          void *aux,
-                                         struct key_acl *acl,
                                          struct key *dest_keyring,
                                          unsigned long flags)
 {
@@ -488,7 +496,7 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx,
                goto error_put_dest_keyring;
        }
 
-       ret = construct_alloc_key(ctx, dest_keyring, flags, user, acl, &key);
+       ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key);
        key_user_put(user);
 
        if (ret == 0) {
@@ -526,7 +534,6 @@ error:
  * @callout_info: The data to pass to the instantiation upcall (or NULL).
  * @callout_len: The length of callout_info.
  * @aux: Auxiliary data for the upcall.
- * @acl: The ACL to attach if a new key is created.
  * @dest_keyring: Where to cache the key.
  * @flags: Flags to key_alloc().
  *
@@ -554,7 +561,6 @@ struct key *request_key_and_link(struct key_type *type,
                                 const void *callout_info,
                                 size_t callout_len,
                                 void *aux,
-                                struct key_acl *acl,
                                 struct key *dest_keyring,
                                 unsigned long flags)
 {
@@ -629,7 +635,7 @@ struct key *request_key_and_link(struct key_type *type,
                        goto error_free;
 
                key = construct_key_and_link(&ctx, callout_info, callout_len,
-                                            aux, acl, dest_keyring, flags);
+                                            aux, dest_keyring, flags);
        }
 
 error_free:
@@ -672,7 +678,6 @@ EXPORT_SYMBOL(wait_for_key_construction);
  * @description: The searchable description of the key.
  * @domain_tag: The domain in which the key operates.
  * @callout_info: The data to pass to the instantiation upcall (or NULL).
- * @acl: The ACL to attach if a new key is created.
  *
  * As for request_key_and_link() except that it does not add the returned key
  * to a keyring if found, new keys are always allocated in the user's quota,
@@ -685,8 +690,7 @@ EXPORT_SYMBOL(wait_for_key_construction);
 struct key *request_key_tag(struct key_type *type,
                            const char *description,
                            struct key_tag *domain_tag,
-                           const char *callout_info,
-                           struct key_acl *acl)
+                           const char *callout_info)
 {
        struct key *key;
        size_t callout_len = 0;
@@ -696,7 +700,7 @@ struct key *request_key_tag(struct key_type *type,
                callout_len = strlen(callout_info);
        key = request_key_and_link(type, description, domain_tag,
                                   callout_info, callout_len,
-                                  NULL, acl, NULL, KEY_ALLOC_IN_QUOTA);
+                                  NULL, NULL, KEY_ALLOC_IN_QUOTA);
        if (!IS_ERR(key)) {
                ret = wait_for_key_construction(key, false);
                if (ret < 0) {
@@ -716,7 +720,6 @@ EXPORT_SYMBOL(request_key_tag);
  * @callout_info: The data to pass to the instantiation upcall (or NULL).
  * @callout_len: The length of callout_info.
  * @aux: Auxiliary data for the upcall.
- * @acl: The ACL to attach if a new key is created.
  *
  * As for request_key_and_link() except that it does not add the returned key
  * to a keyring if found and new keys are always allocated in the user's quota.
@@ -729,15 +732,14 @@ struct key *request_key_with_auxdata(struct key_type *type,
                                     struct key_tag *domain_tag,
                                     const void *callout_info,
                                     size_t callout_len,
-                                    void *aux,
-                                    struct key_acl *acl)
+                                    void *aux)
 {
        struct key *key;
        int ret;
 
        key = request_key_and_link(type, description, domain_tag,
                                   callout_info, callout_len,
-                                  aux, acl, NULL, KEY_ALLOC_IN_QUOTA);
+                                  aux, NULL, KEY_ALLOC_IN_QUOTA);
        if (!IS_ERR(key)) {
                ret = wait_for_key_construction(key, false);
                if (ret < 0) {
index 27e437d94b81c2d9b7505929b4ae90f22cf04d01..e73ec040e2509494d3d123ad8c47419b747a33f7 100644 (file)
@@ -24,17 +24,6 @@ static void request_key_auth_revoke(struct key *);
 static void request_key_auth_destroy(struct key *);
 static long request_key_auth_read(const struct key *, char __user *, size_t);
 
-static struct key_acl request_key_auth_acl = {
-       .usage  = REFCOUNT_INIT(1),
-       .nr_ace = 2,
-       .possessor_viewable = true,
-       .aces = {
-               KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_SEARCH |
-                                 KEY_ACE_LINK),
-               KEY_OWNER_ACE(KEY_ACE_VIEW),
-       }
-};
-
 /*
  * The request-key authorisation key type definition.
  */
@@ -221,8 +210,8 @@ struct key *request_key_auth_new(struct key *target, const char *op,
 
        authkey = key_alloc(&key_type_request_key_auth, desc,
                            cred->fsuid, cred->fsgid, cred,
-                           &request_key_auth_acl,
-                           KEY_ALLOC_NOT_IN_QUOTA, NULL);
+                           KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | KEY_POS_LINK |
+                           KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
        if (IS_ERR(authkey)) {
                ret = PTR_ERR(authkey);
                goto error_free_rka;
index 4bef86ed463b5c42b420dc105c6b7c4a3628aaae..74dd46de01b6a4a7dbde1b8d697b9888cbe85f21 100644 (file)
@@ -6502,7 +6502,6 @@ static int selinux_key_permission(key_ref_t key_ref,
 {
        struct key *key;
        struct key_security_struct *ksec;
-       unsigned oldstyle_perm;
        u32 sid;
 
        /* if no specific permissions are requested, we skip the
@@ -6511,26 +6510,13 @@ static int selinux_key_permission(key_ref_t key_ref,
        if (perm == 0)
                return 0;
 
-       oldstyle_perm = perm & (KEY_NEED_VIEW | KEY_NEED_READ | KEY_NEED_WRITE |
-                               KEY_NEED_SEARCH | KEY_NEED_LINK);
-       if (perm & KEY_NEED_SETSEC)
-               oldstyle_perm |= OLD_KEY_NEED_SETATTR;
-       if (perm & KEY_NEED_INVAL)
-               oldstyle_perm |= KEY_NEED_SEARCH;
-       if (perm & KEY_NEED_REVOKE && !(perm & OLD_KEY_NEED_SETATTR))
-               oldstyle_perm |= KEY_NEED_WRITE;
-       if (perm & KEY_NEED_JOIN)
-               oldstyle_perm |= KEY_NEED_SEARCH;
-       if (perm & KEY_NEED_CLEAR)
-               oldstyle_perm |= KEY_NEED_WRITE;
-
        sid = cred_sid(cred);
 
        key = key_ref_to_ptr(key_ref);
        ksec = key->security;
 
        return avc_has_perm(&selinux_state,
-                           sid, ksec->sid, SECCLASS_KEY, oldstyle_perm, NULL);
+                           sid, ksec->sid, SECCLASS_KEY, perm, NULL);
 }
 
 static int selinux_key_getsecurity(struct key *key, char **_buffer)
index 50c536cad85b31063e2f1ea7c10287bf88c0b9c2..4c5e5a438f8bdd77f88d4cdfdf8424c910c444ed 100644 (file)
@@ -4284,8 +4284,7 @@ static int smack_key_permission(key_ref_t key_ref,
 #endif
        if (perm & (KEY_NEED_READ | KEY_NEED_SEARCH | KEY_NEED_VIEW))
                request |= MAY_READ;
-       if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETSEC |
-                   KEY_NEED_INVAL | KEY_NEED_REVOKE | KEY_NEED_CLEAR))
+       if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR))
                request |= MAY_WRITE;
        rc = smk_access(tkp, keyp->security, request, &ad);
        rc = smk_bu_note("key access", tkp, keyp->security, request, rc);