20
20
/*
21
21
* Layout of key payload words.
22
22
*/
23
- enum {
24
- big_key_data ,
25
- big_key_path ,
26
- big_key_path_2nd_part ,
27
- big_key_len ,
23
+ struct big_key_payload {
24
+ u8 * data ;
25
+ struct path path ;
26
+ size_t length ;
28
27
};
28
+ #define to_big_key_payload (payload ) \
29
+ (struct big_key_payload *)((payload).data)
29
30
30
31
/*
31
32
* If the data is under this limit, there's no point creating a shm file to
@@ -55,21 +56,23 @@ struct key_type key_type_big_key = {
55
56
*/
56
57
int big_key_preparse (struct key_preparsed_payload * prep )
57
58
{
58
- struct path * path = ( struct path * ) & prep -> payload . data [ big_key_path ] ;
59
+ struct big_key_payload * payload = to_big_key_payload ( prep -> payload ) ;
59
60
struct file * file ;
60
61
u8 * buf , * enckey ;
61
62
ssize_t written ;
62
63
size_t datalen = prep -> datalen ;
63
64
size_t enclen = datalen + CHACHA20POLY1305_AUTHTAG_SIZE ;
64
65
int ret ;
65
66
67
+ BUILD_BUG_ON (sizeof (* payload ) != sizeof (prep -> payload .data ));
68
+
66
69
if (datalen <= 0 || datalen > 1024 * 1024 || !prep -> data )
67
70
return - EINVAL ;
68
71
69
72
/* Set an arbitrary quota */
70
73
prep -> quotalen = 16 ;
71
74
72
- prep -> payload . data [ big_key_len ] = ( void * )( unsigned long ) datalen ;
75
+ payload -> length = datalen ;
73
76
74
77
if (datalen > BIG_KEY_FILE_THRESHOLD ) {
75
78
/* Create a shmem file to store the data in. This will permit the data
@@ -117,9 +120,9 @@ int big_key_preparse(struct key_preparsed_payload *prep)
117
120
/* Pin the mount and dentry to the key so that we can open it again
118
121
* later
119
122
*/
120
- prep -> payload . data [ big_key_data ] = enckey ;
121
- * path = file -> f_path ;
122
- path_get (path );
123
+ payload -> data = enckey ;
124
+ payload -> path = file -> f_path ;
125
+ path_get (& payload -> path );
123
126
fput (file );
124
127
kvfree_sensitive (buf , enclen );
125
128
} else {
@@ -129,7 +132,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
129
132
if (!data )
130
133
return - ENOMEM ;
131
134
132
- prep -> payload . data [ big_key_data ] = data ;
135
+ payload -> data = data ;
133
136
memcpy (data , prep -> data , prep -> datalen );
134
137
}
135
138
return 0 ;
@@ -148,12 +151,11 @@ int big_key_preparse(struct key_preparsed_payload *prep)
148
151
*/
149
152
void big_key_free_preparse (struct key_preparsed_payload * prep )
150
153
{
151
- if (prep -> datalen > BIG_KEY_FILE_THRESHOLD ) {
152
- struct path * path = (struct path * )& prep -> payload .data [big_key_path ];
154
+ struct big_key_payload * payload = to_big_key_payload (prep -> payload );
153
155
154
- path_put ( path );
155
- }
156
- kfree_sensitive (prep -> payload . data [ big_key_data ] );
156
+ if ( prep -> datalen > BIG_KEY_FILE_THRESHOLD )
157
+ path_put ( & payload -> path );
158
+ kfree_sensitive (payload -> data );
157
159
}
158
160
159
161
/*
@@ -162,31 +164,28 @@ void big_key_free_preparse(struct key_preparsed_payload *prep)
162
164
*/
163
165
void big_key_revoke (struct key * key )
164
166
{
165
- struct path * path = ( struct path * ) & key -> payload . data [ big_key_path ] ;
167
+ struct big_key_payload * payload = to_big_key_payload ( key -> payload ) ;
166
168
167
169
/* clear the quota */
168
170
key_payload_reserve (key , 0 );
169
- if (key_is_positive (key ) &&
170
- (size_t )key -> payload .data [big_key_len ] > BIG_KEY_FILE_THRESHOLD )
171
- vfs_truncate (path , 0 );
171
+ if (key_is_positive (key ) && payload -> length > BIG_KEY_FILE_THRESHOLD )
172
+ vfs_truncate (& payload -> path , 0 );
172
173
}
173
174
174
175
/*
175
176
* dispose of the data dangling from the corpse of a big_key key
176
177
*/
177
178
void big_key_destroy (struct key * key )
178
179
{
179
- size_t datalen = (size_t )key -> payload .data [big_key_len ];
180
-
181
- if (datalen > BIG_KEY_FILE_THRESHOLD ) {
182
- struct path * path = (struct path * )& key -> payload .data [big_key_path ];
180
+ struct big_key_payload * payload = to_big_key_payload (key -> payload );
183
181
184
- path_put (path );
185
- path -> mnt = NULL ;
186
- path -> dentry = NULL ;
182
+ if (payload -> length > BIG_KEY_FILE_THRESHOLD ) {
183
+ path_put (& payload -> path );
184
+ payload -> path .mnt = NULL ;
185
+ payload -> path .dentry = NULL ;
187
186
}
188
- kfree_sensitive (key -> payload . data [ big_key_data ] );
189
- key -> payload . data [ big_key_data ] = NULL ;
187
+ kfree_sensitive (payload -> data );
188
+ payload -> data = NULL ;
190
189
}
191
190
192
191
/*
@@ -211,14 +210,14 @@ int big_key_update(struct key *key, struct key_preparsed_payload *prep)
211
210
*/
212
211
void big_key_describe (const struct key * key , struct seq_file * m )
213
212
{
214
- size_t datalen = ( size_t ) key -> payload . data [ big_key_len ] ;
213
+ struct big_key_payload * payload = to_big_key_payload ( key -> payload ) ;
215
214
216
215
seq_puts (m , key -> description );
217
216
218
217
if (key_is_positive (key ))
219
218
seq_printf (m , ": %zu [%s]" ,
220
- datalen ,
221
- datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff" );
219
+ payload -> length ,
220
+ payload -> length > BIG_KEY_FILE_THRESHOLD ? "file" : "buff" );
222
221
}
223
222
224
223
/*
@@ -227,24 +226,24 @@ void big_key_describe(const struct key *key, struct seq_file *m)
227
226
*/
228
227
long big_key_read (const struct key * key , char * buffer , size_t buflen )
229
228
{
230
- size_t datalen = (size_t )key -> payload .data [big_key_len ];
229
+ struct big_key_payload * payload = to_big_key_payload (key -> payload );
230
+ size_t datalen = payload -> length ;
231
231
long ret ;
232
232
233
233
if (!buffer || buflen < datalen )
234
234
return datalen ;
235
235
236
236
if (datalen > BIG_KEY_FILE_THRESHOLD ) {
237
- struct path * path = (struct path * )& key -> payload .data [big_key_path ];
238
237
struct file * file ;
239
- u8 * buf , * enckey = ( u8 * ) key -> payload . data [ big_key_data ] ;
238
+ u8 * buf , * enckey = payload -> data ;
240
239
size_t enclen = datalen + CHACHA20POLY1305_AUTHTAG_SIZE ;
241
240
loff_t pos = 0 ;
242
241
243
242
buf = kvmalloc (enclen , GFP_KERNEL );
244
243
if (!buf )
245
244
return - ENOMEM ;
246
245
247
- file = dentry_open (path , O_RDONLY , current_cred ());
246
+ file = dentry_open (& payload -> path , O_RDONLY , current_cred ());
248
247
if (IS_ERR (file )) {
249
248
ret = PTR_ERR (file );
250
249
goto error ;
@@ -274,7 +273,7 @@ long big_key_read(const struct key *key, char *buffer, size_t buflen)
274
273
kvfree_sensitive (buf , enclen );
275
274
} else {
276
275
ret = datalen ;
277
- memcpy (buffer , key -> payload . data [ big_key_data ] , datalen );
276
+ memcpy (buffer , payload -> data , datalen );
278
277
}
279
278
280
279
return ret ;
0 commit comments