3
3
#include <linux/keyctl.h>
4
4
#include <keys/user-type.h>
5
5
#include <linux/crash_dump.h>
6
+ #include <linux/cc_platform.h>
6
7
#include <linux/configfs.h>
7
8
#include <linux/module.h>
8
9
@@ -28,6 +29,61 @@ static size_t get_keys_header_size(size_t total_keys)
28
29
return struct_size (keys_header , keys , total_keys );
29
30
}
30
31
32
+ unsigned long long dm_crypt_keys_addr ;
33
+ EXPORT_SYMBOL_GPL (dm_crypt_keys_addr );
34
+
35
+ static int __init setup_dmcryptkeys (char * arg )
36
+ {
37
+ char * end ;
38
+
39
+ if (!arg )
40
+ return - EINVAL ;
41
+ dm_crypt_keys_addr = memparse (arg , & end );
42
+ if (end > arg )
43
+ return 0 ;
44
+
45
+ dm_crypt_keys_addr = 0 ;
46
+ return - EINVAL ;
47
+ }
48
+
49
+ early_param ("dmcryptkeys" , setup_dmcryptkeys );
50
+
51
+ /*
52
+ * Architectures may override this function to read dm crypt keys
53
+ */
54
+ ssize_t __weak dm_crypt_keys_read (char * buf , size_t count , u64 * ppos )
55
+ {
56
+ struct kvec kvec = { .iov_base = buf , .iov_len = count };
57
+ struct iov_iter iter ;
58
+
59
+ iov_iter_kvec (& iter , READ , & kvec , 1 , count );
60
+ return read_from_oldmem (& iter , count , ppos , cc_platform_has (CC_ATTR_MEM_ENCRYPT ));
61
+ }
62
+
63
+ static int add_key_to_keyring (struct dm_crypt_key * dm_key ,
64
+ key_ref_t keyring_ref )
65
+ {
66
+ key_ref_t key_ref ;
67
+ int r ;
68
+
69
+ /* create or update the requested key and add it to the target keyring */
70
+ key_ref = key_create_or_update (keyring_ref , "user" , dm_key -> key_desc ,
71
+ dm_key -> data , dm_key -> key_size ,
72
+ KEY_USR_ALL , KEY_ALLOC_IN_QUOTA );
73
+
74
+ if (!IS_ERR (key_ref )) {
75
+ r = key_ref_to_ptr (key_ref )-> serial ;
76
+ key_ref_put (key_ref );
77
+ kexec_dprintk ("Success adding key %s" , dm_key -> key_desc );
78
+ } else {
79
+ r = PTR_ERR (key_ref );
80
+ kexec_dprintk ("Error when adding key" );
81
+ }
82
+
83
+ key_ref_put (keyring_ref );
84
+ return r ;
85
+ }
86
+
31
87
static void get_keys_from_kdump_reserved_memory (void )
32
88
{
33
89
struct keys_header * keys_header_loaded ;
@@ -42,6 +98,47 @@ static void get_keys_from_kdump_reserved_memory(void)
42
98
arch_kexec_protect_crashkres ();
43
99
}
44
100
101
+ static int restore_dm_crypt_keys_to_thread_keyring (void )
102
+ {
103
+ struct dm_crypt_key * key ;
104
+ size_t keys_header_size ;
105
+ key_ref_t keyring_ref ;
106
+ u64 addr ;
107
+
108
+ /* find the target keyring (which must be writable) */
109
+ keyring_ref =
110
+ lookup_user_key (KEY_SPEC_USER_KEYRING , 0x01 , KEY_NEED_WRITE );
111
+ if (IS_ERR (keyring_ref )) {
112
+ kexec_dprintk ("Failed to get the user keyring\n" );
113
+ return PTR_ERR (keyring_ref );
114
+ }
115
+
116
+ addr = dm_crypt_keys_addr ;
117
+ dm_crypt_keys_read ((char * )& key_count , sizeof (key_count ), & addr );
118
+ if (key_count < 0 || key_count > KEY_NUM_MAX ) {
119
+ kexec_dprintk ("Failed to read the number of dm-crypt keys\n" );
120
+ return -1 ;
121
+ }
122
+
123
+ kexec_dprintk ("There are %u keys\n" , key_count );
124
+ addr = dm_crypt_keys_addr ;
125
+
126
+ keys_header_size = get_keys_header_size (key_count );
127
+ keys_header = kzalloc (keys_header_size , GFP_KERNEL );
128
+ if (!keys_header )
129
+ return - ENOMEM ;
130
+
131
+ dm_crypt_keys_read ((char * )keys_header , keys_header_size , & addr );
132
+
133
+ for (int i = 0 ; i < keys_header -> total_keys ; i ++ ) {
134
+ key = & keys_header -> keys [i ];
135
+ kexec_dprintk ("Get key (size=%u)\n" , key -> key_size );
136
+ add_key_to_keyring (key , keyring_ref );
137
+ }
138
+
139
+ return 0 ;
140
+ }
141
+
45
142
static int read_key_from_user_keying (struct dm_crypt_key * dm_key )
46
143
{
47
144
const struct user_key_payload * ukp ;
@@ -211,6 +308,37 @@ static const struct config_item_type config_keys_type = {
211
308
.ct_owner = THIS_MODULE ,
212
309
};
213
310
311
+ static bool restore ;
312
+
313
+ static ssize_t config_keys_restore_show (struct config_item * item , char * page )
314
+ {
315
+ return sprintf (page , "%d\n" , restore );
316
+ }
317
+
318
+ static ssize_t config_keys_restore_store (struct config_item * item ,
319
+ const char * page , size_t count )
320
+ {
321
+ if (!restore )
322
+ restore_dm_crypt_keys_to_thread_keyring ();
323
+
324
+ if (kstrtobool (page , & restore ))
325
+ return - EINVAL ;
326
+
327
+ return count ;
328
+ }
329
+
330
+ CONFIGFS_ATTR (config_keys_ , restore );
331
+
332
+ static struct configfs_attribute * kdump_config_keys_attrs [] = {
333
+ & config_keys_attr_restore ,
334
+ NULL ,
335
+ };
336
+
337
+ static const struct config_item_type kdump_config_keys_type = {
338
+ .ct_attrs = kdump_config_keys_attrs ,
339
+ .ct_owner = THIS_MODULE ,
340
+ };
341
+
214
342
static struct configfs_subsystem config_keys_subsys = {
215
343
.su_group = {
216
344
.cg_item = {
@@ -311,6 +439,11 @@ static int __init configfs_dmcrypt_keys_init(void)
311
439
{
312
440
int ret ;
313
441
442
+ if (is_kdump_kernel ()) {
443
+ config_keys_subsys .su_group .cg_item .ci_type =
444
+ & kdump_config_keys_type ;
445
+ }
446
+
314
447
config_group_init (& config_keys_subsys .su_group );
315
448
mutex_init (& config_keys_subsys .su_mutex );
316
449
ret = configfs_register_subsystem (& config_keys_subsys );
0 commit comments