aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/encrypted-keys/encrypted.c2
-rw-r--r--security/keys/keyctl.c18
-rw-r--r--security/keys/trusted.c5
-rw-r--r--security/keys/user_defined.c5
4 files changed, 19 insertions, 11 deletions
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 927db9f35ad6..696ccfa08d10 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -845,6 +845,8 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
845 size_t datalen = prep->datalen; 845 size_t datalen = prep->datalen;
846 int ret = 0; 846 int ret = 0;
847 847
848 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
849 return -ENOKEY;
848 if (datalen <= 0 || datalen > 32767 || !prep->data) 850 if (datalen <= 0 || datalen > 32767 || !prep->data)
849 return -EINVAL; 851 return -EINVAL;
850 852
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index fb111eafcb89..1c3872aeed14 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -751,16 +751,16 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
751 751
752 /* the key is probably readable - now try to read it */ 752 /* the key is probably readable - now try to read it */
753can_read_key: 753can_read_key:
754 ret = key_validate(key); 754 ret = -EOPNOTSUPP;
755 if (ret == 0) { 755 if (key->type->read) {
756 ret = -EOPNOTSUPP; 756 /* Read the data with the semaphore held (since we might sleep)
757 if (key->type->read) { 757 * to protect against the key being updated or revoked.
758 /* read the data with the semaphore held (since we 758 */
759 * might sleep) */ 759 down_read(&key->sem);
760 down_read(&key->sem); 760 ret = key_validate(key);
761 if (ret == 0)
761 ret = key->type->read(key, buffer, buflen); 762 ret = key->type->read(key, buffer, buflen);
762 up_read(&key->sem); 763 up_read(&key->sem);
763 }
764 } 764 }
765 765
766error2: 766error2:
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index 903dace648a1..16dec53184b6 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -1007,13 +1007,16 @@ static void trusted_rcu_free(struct rcu_head *rcu)
1007 */ 1007 */
1008static int trusted_update(struct key *key, struct key_preparsed_payload *prep) 1008static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
1009{ 1009{
1010 struct trusted_key_payload *p = key->payload.data[0]; 1010 struct trusted_key_payload *p;
1011 struct trusted_key_payload *new_p; 1011 struct trusted_key_payload *new_p;
1012 struct trusted_key_options *new_o; 1012 struct trusted_key_options *new_o;
1013 size_t datalen = prep->datalen; 1013 size_t datalen = prep->datalen;
1014 char *datablob; 1014 char *datablob;
1015 int ret = 0; 1015 int ret = 0;
1016 1016
1017 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
1018 return -ENOKEY;
1019 p = key->payload.data[0];
1017 if (!p->migratable) 1020 if (!p->migratable)
1018 return -EPERM; 1021 return -EPERM;
1019 if (datalen <= 0 || datalen > 32767 || !prep->data) 1022 if (datalen <= 0 || datalen > 32767 || !prep->data)
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 28cb30f80256..8705d79b2c6f 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -120,7 +120,10 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
120 120
121 if (ret == 0) { 121 if (ret == 0) {
122 /* attach the new data, displacing the old */ 122 /* attach the new data, displacing the old */
123 zap = key->payload.data[0]; 123 if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
124 zap = key->payload.data[0];
125 else
126 zap = NULL;
124 rcu_assign_keypointer(key, upayload); 127 rcu_assign_keypointer(key, upayload);
125 key->expiry = 0; 128 key->expiry = 0;
126 } 129 }