2020/*
2121 * Layout of key payload words.
2222 */
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 ;
2827};
28+ #define to_big_key_payload (payload ) \
29+ (struct big_key_payload *)((payload).data)
2930
3031/*
3132 * 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 = {
5556 */
5657int big_key_preparse (struct key_preparsed_payload * prep )
5758{
58- struct path * path = ( struct path * ) & prep -> payload . data [ big_key_path ] ;
59+ struct big_key_payload * payload = to_big_key_payload ( prep -> payload ) ;
5960 struct file * file ;
6061 u8 * buf , * enckey ;
6162 ssize_t written ;
6263 size_t datalen = prep -> datalen ;
6364 size_t enclen = datalen + CHACHA20POLY1305_AUTHTAG_SIZE ;
6465 int ret ;
6566
67+ BUILD_BUG_ON (sizeof (* payload ) != sizeof (prep -> payload .data ));
68+
6669 if (datalen <= 0 || datalen > 1024 * 1024 || !prep -> data )
6770 return - EINVAL ;
6871
6972 /* Set an arbitrary quota */
7073 prep -> quotalen = 16 ;
7174
72- prep -> payload . data [ big_key_len ] = ( void * )( unsigned long ) datalen ;
75+ payload -> length = datalen ;
7376
7477 if (datalen > BIG_KEY_FILE_THRESHOLD ) {
7578 /* 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)
117120 /* Pin the mount and dentry to the key so that we can open it again
118121 * later
119122 */
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 );
123126 fput (file );
124127 kvfree_sensitive (buf , enclen );
125128 } else {
@@ -129,7 +132,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
129132 if (!data )
130133 return - ENOMEM ;
131134
132- prep -> payload . data [ big_key_data ] = data ;
135+ payload -> data = data ;
133136 memcpy (data , prep -> data , prep -> datalen );
134137 }
135138 return 0 ;
@@ -148,12 +151,11 @@ int big_key_preparse(struct key_preparsed_payload *prep)
148151 */
149152void big_key_free_preparse (struct key_preparsed_payload * prep )
150153{
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 );
153155
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 );
157159}
158160
159161/*
@@ -162,31 +164,28 @@ void big_key_free_preparse(struct key_preparsed_payload *prep)
162164 */
163165void big_key_revoke (struct key * key )
164166{
165- struct path * path = ( struct path * ) & key -> payload . data [ big_key_path ] ;
167+ struct big_key_payload * payload = to_big_key_payload ( key -> payload ) ;
166168
167169 /* clear the quota */
168170 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 );
172173}
173174
174175/*
175176 * dispose of the data dangling from the corpse of a big_key key
176177 */
177178void big_key_destroy (struct key * key )
178179{
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 );
183181
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 ;
187186 }
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 ;
190189}
191190
192191/*
@@ -211,14 +210,14 @@ int big_key_update(struct key *key, struct key_preparsed_payload *prep)
211210 */
212211void big_key_describe (const struct key * key , struct seq_file * m )
213212{
214- size_t datalen = ( size_t ) key -> payload . data [ big_key_len ] ;
213+ struct big_key_payload * payload = to_big_key_payload ( key -> payload ) ;
215214
216215 seq_puts (m , key -> description );
217216
218217 if (key_is_positive (key ))
219218 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" );
222221}
223222
224223/*
@@ -227,24 +226,24 @@ void big_key_describe(const struct key *key, struct seq_file *m)
227226 */
228227long big_key_read (const struct key * key , char * buffer , size_t buflen )
229228{
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 ;
231231 long ret ;
232232
233233 if (!buffer || buflen < datalen )
234234 return datalen ;
235235
236236 if (datalen > BIG_KEY_FILE_THRESHOLD ) {
237- struct path * path = (struct path * )& key -> payload .data [big_key_path ];
238237 struct file * file ;
239- u8 * buf , * enckey = ( u8 * ) key -> payload . data [ big_key_data ] ;
238+ u8 * buf , * enckey = payload -> data ;
240239 size_t enclen = datalen + CHACHA20POLY1305_AUTHTAG_SIZE ;
241240 loff_t pos = 0 ;
242241
243242 buf = kvmalloc (enclen , GFP_KERNEL );
244243 if (!buf )
245244 return - ENOMEM ;
246245
247- file = dentry_open (path , O_RDONLY , current_cred ());
246+ file = dentry_open (& payload -> path , O_RDONLY , current_cred ());
248247 if (IS_ERR (file )) {
249248 ret = PTR_ERR (file );
250249 goto error ;
@@ -274,7 +273,7 @@ long big_key_read(const struct key *key, char *buffer, size_t buflen)
274273 kvfree_sensitive (buf , enclen );
275274 } else {
276275 ret = datalen ;
277- memcpy (buffer , key -> payload . data [ big_key_data ] , datalen );
276+ memcpy (buffer , payload -> data , datalen );
278277 }
279278
280279 return ret ;
0 commit comments