diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/keys/keyring.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 88292e3dee96..70f0c313c888 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -292,7 +292,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, | |||
292 | 292 | ||
293 | struct keyring_list *keylist; | 293 | struct keyring_list *keylist; |
294 | struct timespec now; | 294 | struct timespec now; |
295 | unsigned long possessed; | 295 | unsigned long possessed, kflags; |
296 | struct key *keyring, *key; | 296 | struct key *keyring, *key; |
297 | key_ref_t key_ref; | 297 | key_ref_t key_ref; |
298 | long err; | 298 | long err; |
@@ -319,6 +319,32 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, | |||
319 | err = -EAGAIN; | 319 | err = -EAGAIN; |
320 | sp = 0; | 320 | sp = 0; |
321 | 321 | ||
322 | /* firstly we should check to see if this top-level keyring is what we | ||
323 | * are looking for */ | ||
324 | key_ref = ERR_PTR(-EAGAIN); | ||
325 | kflags = keyring->flags; | ||
326 | if (keyring->type == type && match(keyring, description)) { | ||
327 | key = keyring; | ||
328 | |||
329 | /* check it isn't negative and hasn't expired or been | ||
330 | * revoked */ | ||
331 | if (kflags & (1 << KEY_FLAG_REVOKED)) | ||
332 | goto error_2; | ||
333 | if (key->expiry && now.tv_sec >= key->expiry) | ||
334 | goto error_2; | ||
335 | key_ref = ERR_PTR(-ENOKEY); | ||
336 | if (kflags & (1 << KEY_FLAG_NEGATIVE)) | ||
337 | goto error_2; | ||
338 | goto found; | ||
339 | } | ||
340 | |||
341 | /* otherwise, the top keyring must not be revoked, expired, or | ||
342 | * negatively instantiated if we are to search it */ | ||
343 | key_ref = ERR_PTR(-EAGAIN); | ||
344 | if (kflags & ((1 << KEY_FLAG_REVOKED) | (1 << KEY_FLAG_NEGATIVE)) || | ||
345 | (keyring->expiry && now.tv_sec >= keyring->expiry)) | ||
346 | goto error_2; | ||
347 | |||
322 | /* start processing a new keyring */ | 348 | /* start processing a new keyring */ |
323 | descend: | 349 | descend: |
324 | if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) | 350 | if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) |
@@ -331,13 +357,14 @@ descend: | |||
331 | /* iterate through the keys in this keyring first */ | 357 | /* iterate through the keys in this keyring first */ |
332 | for (kix = 0; kix < keylist->nkeys; kix++) { | 358 | for (kix = 0; kix < keylist->nkeys; kix++) { |
333 | key = keylist->keys[kix]; | 359 | key = keylist->keys[kix]; |
360 | kflags = key->flags; | ||
334 | 361 | ||
335 | /* ignore keys not of this type */ | 362 | /* ignore keys not of this type */ |
336 | if (key->type != type) | 363 | if (key->type != type) |
337 | continue; | 364 | continue; |
338 | 365 | ||
339 | /* skip revoked keys and expired keys */ | 366 | /* skip revoked keys and expired keys */ |
340 | if (test_bit(KEY_FLAG_REVOKED, &key->flags)) | 367 | if (kflags & (1 << KEY_FLAG_REVOKED)) |
341 | continue; | 368 | continue; |
342 | 369 | ||
343 | if (key->expiry && now.tv_sec >= key->expiry) | 370 | if (key->expiry && now.tv_sec >= key->expiry) |
@@ -352,8 +379,8 @@ descend: | |||
352 | context, KEY_SEARCH) < 0) | 379 | context, KEY_SEARCH) < 0) |
353 | continue; | 380 | continue; |
354 | 381 | ||
355 | /* we set a different error code if we find a negative key */ | 382 | /* we set a different error code if we pass a negative key */ |
356 | if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { | 383 | if (kflags & (1 << KEY_FLAG_NEGATIVE)) { |
357 | err = -ENOKEY; | 384 | err = -ENOKEY; |
358 | continue; | 385 | continue; |
359 | } | 386 | } |