Skip to content

Commit 1f5a018

Browse files
committed
Merge branch 'fixes-v5.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull keys fixes from James Morris: - Handle quotas better, allowing full quota to be reached. - Fix the creation of shortcuts in the assoc_array internal representation when the index key needs to be an exact multiple of the machine word size. - Fix a dependency loop between the request_key contruction record and the request_key authentication key. The construction record isn't really necessary and can be dispensed with. - Set the timestamp on a new key rather than leaving it as 0. This would ordinarily be fine - provided the system clock is never set to a time before 1970 * 'fixes-v5.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: keys: Timestamp new keys keys: Fix dependency loop between construction record and auth key assoc_array: Fix shortcut creation KEYS: allow reaching the keys quotas exactly
2 parents 40e196a + 7c1857b commit 1f5a018

File tree

10 files changed

+108
-97
lines changed

10 files changed

+108
-97
lines changed

fs/nfs/nfs4idmap.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include <linux/keyctl.h>
4545
#include <linux/key-type.h>
4646
#include <keys/user-type.h>
47+
#include <keys/request_key_auth-type.h>
4748
#include <linux/module.h>
4849

4950
#include "internal.h"
@@ -59,7 +60,7 @@ static struct key_type key_type_id_resolver_legacy;
5960
struct idmap_legacy_upcalldata {
6061
struct rpc_pipe_msg pipe_msg;
6162
struct idmap_msg idmap_msg;
62-
struct key_construction *key_cons;
63+
struct key *authkey;
6364
struct idmap *idmap;
6465
};
6566

@@ -384,7 +385,7 @@ static const match_table_t nfs_idmap_tokens = {
384385
{ Opt_find_err, NULL }
385386
};
386387

387-
static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *);
388+
static int nfs_idmap_legacy_upcall(struct key *, void *);
388389
static ssize_t idmap_pipe_downcall(struct file *, const char __user *,
389390
size_t);
390391
static void idmap_release_pipe(struct inode *);
@@ -549,11 +550,12 @@ nfs_idmap_prepare_pipe_upcall(struct idmap *idmap,
549550
static void
550551
nfs_idmap_complete_pipe_upcall_locked(struct idmap *idmap, int ret)
551552
{
552-
struct key_construction *cons = idmap->idmap_upcall_data->key_cons;
553+
struct key *authkey = idmap->idmap_upcall_data->authkey;
553554

554555
kfree(idmap->idmap_upcall_data);
555556
idmap->idmap_upcall_data = NULL;
556-
complete_request_key(cons, ret);
557+
complete_request_key(authkey, ret);
558+
key_put(authkey);
557559
}
558560

559561
static void
@@ -563,15 +565,14 @@ nfs_idmap_abort_pipe_upcall(struct idmap *idmap, int ret)
563565
nfs_idmap_complete_pipe_upcall_locked(idmap, ret);
564566
}
565567

566-
static int nfs_idmap_legacy_upcall(struct key_construction *cons,
567-
const char *op,
568-
void *aux)
568+
static int nfs_idmap_legacy_upcall(struct key *authkey, void *aux)
569569
{
570570
struct idmap_legacy_upcalldata *data;
571+
struct request_key_auth *rka = get_request_key_auth(authkey);
571572
struct rpc_pipe_msg *msg;
572573
struct idmap_msg *im;
573574
struct idmap *idmap = (struct idmap *)aux;
574-
struct key *key = cons->key;
575+
struct key *key = rka->target_key;
575576
int ret = -ENOKEY;
576577

577578
if (!aux)
@@ -586,7 +587,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
586587
msg = &data->pipe_msg;
587588
im = &data->idmap_msg;
588589
data->idmap = idmap;
589-
data->key_cons = cons;
590+
data->authkey = key_get(authkey);
590591

591592
ret = nfs_idmap_prepare_message(key->description, idmap, im, msg);
592593
if (ret < 0)
@@ -604,7 +605,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
604605
out2:
605606
kfree(data);
606607
out1:
607-
complete_request_key(cons, ret);
608+
complete_request_key(authkey, ret);
608609
return ret;
609610
}
610611

@@ -651,9 +652,10 @@ static int nfs_idmap_read_and_verify_message(struct idmap_msg *im,
651652
static ssize_t
652653
idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
653654
{
655+
struct request_key_auth *rka;
654656
struct rpc_inode *rpci = RPC_I(file_inode(filp));
655657
struct idmap *idmap = (struct idmap *)rpci->private;
656-
struct key_construction *cons;
658+
struct key *authkey;
657659
struct idmap_msg im;
658660
size_t namelen_in;
659661
int ret = -ENOKEY;
@@ -665,7 +667,8 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
665667
if (idmap->idmap_upcall_data == NULL)
666668
goto out_noupcall;
667669

668-
cons = idmap->idmap_upcall_data->key_cons;
670+
authkey = idmap->idmap_upcall_data->authkey;
671+
rka = get_request_key_auth(authkey);
669672

670673
if (mlen != sizeof(im)) {
671674
ret = -ENOSPC;
@@ -690,9 +693,9 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
690693

691694
ret = nfs_idmap_read_and_verify_message(&im,
692695
&idmap->idmap_upcall_data->idmap_msg,
693-
cons->key, cons->authkey);
696+
rka->target_key, authkey);
694697
if (ret >= 0) {
695-
key_set_timeout(cons->key, nfs_idmap_cache_timeout);
698+
key_set_timeout(rka->target_key, nfs_idmap_cache_timeout);
696699
ret = mlen;
697700
}
698701

include/keys/request_key_auth-type.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* request_key authorisation token key type
2+
*
3+
* Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4+
* Written by David Howells (dhowells@redhat.com)
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU General Public Licence
8+
* as published by the Free Software Foundation; either version
9+
* 2 of the Licence, or (at your option) any later version.
10+
*/
11+
12+
#ifndef _KEYS_REQUEST_KEY_AUTH_TYPE_H
13+
#define _KEYS_REQUEST_KEY_AUTH_TYPE_H
14+
15+
#include <linux/key.h>
16+
17+
/*
18+
* Authorisation record for request_key().
19+
*/
20+
struct request_key_auth {
21+
struct key *target_key;
22+
struct key *dest_keyring;
23+
const struct cred *cred;
24+
void *callout_info;
25+
size_t callout_len;
26+
pid_t pid;
27+
char op[8];
28+
} __randomize_layout;
29+
30+
static inline struct request_key_auth *get_request_key_auth(const struct key *key)
31+
{
32+
return key->payload.data[0];
33+
}
34+
35+
36+
#endif /* _KEYS_REQUEST_KEY_AUTH_TYPE_H */

include/linux/key-type.h

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,6 @@
2020
struct kernel_pkey_query;
2121
struct kernel_pkey_params;
2222

23-
/*
24-
* key under-construction record
25-
* - passed to the request_key actor if supplied
26-
*/
27-
struct key_construction {
28-
struct key *key; /* key being constructed */
29-
struct key *authkey;/* authorisation for key being constructed */
30-
};
31-
3223
/*
3324
* Pre-parsed payload, used by key add, update and instantiate.
3425
*
@@ -50,8 +41,7 @@ struct key_preparsed_payload {
5041
time64_t expiry; /* Expiry time of key */
5142
} __randomize_layout;
5243

53-
typedef int (*request_key_actor_t)(struct key_construction *key,
54-
const char *op, void *aux);
44+
typedef int (*request_key_actor_t)(struct key *auth_key, void *aux);
5545

5646
/*
5747
* Preparsed matching criterion.
@@ -181,20 +171,20 @@ extern int key_instantiate_and_link(struct key *key,
181171
const void *data,
182172
size_t datalen,
183173
struct key *keyring,
184-
struct key *instkey);
174+
struct key *authkey);
185175
extern int key_reject_and_link(struct key *key,
186176
unsigned timeout,
187177
unsigned error,
188178
struct key *keyring,
189-
struct key *instkey);
190-
extern void complete_request_key(struct key_construction *cons, int error);
179+
struct key *authkey);
180+
extern void complete_request_key(struct key *authkey, int error);
191181

192182
static inline int key_negate_and_link(struct key *key,
193183
unsigned timeout,
194184
struct key *keyring,
195-
struct key *instkey)
185+
struct key *authkey)
196186
{
197-
return key_reject_and_link(key, timeout, ENOKEY, keyring, instkey);
187+
return key_reject_and_link(key, timeout, ENOKEY, keyring, authkey);
198188
}
199189

200190
extern int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep);

lib/assoc_array.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -768,9 +768,11 @@ static bool assoc_array_insert_into_terminal_node(struct assoc_array_edit *edit,
768768
new_s0->index_key[i] =
769769
ops->get_key_chunk(index_key, i * ASSOC_ARRAY_KEY_CHUNK_SIZE);
770770

771-
blank = ULONG_MAX << (level & ASSOC_ARRAY_KEY_CHUNK_MASK);
772-
pr_devel("blank off [%zu] %d: %lx\n", keylen - 1, level, blank);
773-
new_s0->index_key[keylen - 1] &= ~blank;
771+
if (level & ASSOC_ARRAY_KEY_CHUNK_MASK) {
772+
blank = ULONG_MAX << (level & ASSOC_ARRAY_KEY_CHUNK_MASK);
773+
pr_devel("blank off [%zu] %d: %lx\n", keylen - 1, level, blank);
774+
new_s0->index_key[keylen - 1] &= ~blank;
775+
}
774776

775777
/* This now reduces to a node splitting exercise for which we'll need
776778
* to regenerate the disparity table.

security/keys/internal.h

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -186,20 +186,9 @@ static inline int key_permission(const key_ref_t key_ref, unsigned perm)
186186
return key_task_permission(key_ref, current_cred(), perm);
187187
}
188188

189-
/*
190-
* Authorisation record for request_key().
191-
*/
192-
struct request_key_auth {
193-
struct key *target_key;
194-
struct key *dest_keyring;
195-
const struct cred *cred;
196-
void *callout_info;
197-
size_t callout_len;
198-
pid_t pid;
199-
} __randomize_layout;
200-
201189
extern struct key_type key_type_request_key_auth;
202190
extern struct key *request_key_auth_new(struct key *target,
191+
const char *op,
203192
const void *callout_info,
204193
size_t callout_len,
205194
struct key *dest_keyring);

security/keys/key.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
265265

266266
spin_lock(&user->lock);
267267
if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) {
268-
if (user->qnkeys + 1 >= maxkeys ||
269-
user->qnbytes + quotalen >= maxbytes ||
268+
if (user->qnkeys + 1 > maxkeys ||
269+
user->qnbytes + quotalen > maxbytes ||
270270
user->qnbytes + quotalen < user->qnbytes)
271271
goto no_quota;
272272
}
@@ -297,6 +297,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
297297
key->gid = gid;
298298
key->perm = perm;
299299
key->restrict_link = restrict_link;
300+
key->last_used_at = ktime_get_real_seconds();
300301

301302
if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
302303
key->flags |= 1 << KEY_FLAG_IN_QUOTA;

security/keys/keyctl.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/security.h>
2626
#include <linux/uio.h>
2727
#include <linux/uaccess.h>
28+
#include <keys/request_key_auth-type.h>
2829
#include "internal.h"
2930

3031
#define KEY_MAX_DESC_SIZE 4096

security/keys/process_keys.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/security.h>
2020
#include <linux/user_namespace.h>
2121
#include <linux/uaccess.h>
22+
#include <keys/request_key_auth-type.h>
2223
#include "internal.h"
2324

2425
/* Session keyring create vs join semaphore */

0 commit comments

Comments
 (0)