diff options
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r-- | fs/ecryptfs/Makefile | 2 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 7 | ||||
-rw-r--r-- | fs/ecryptfs/keystore.c | 784 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 49 | ||||
-rw-r--r-- | fs/ecryptfs/messaging.c | 10 | ||||
-rw-r--r-- | fs/ecryptfs/mmap.c | 91 | ||||
-rw-r--r-- | fs/ecryptfs/netlink.c | 4 |
7 files changed, 777 insertions, 170 deletions
diff --git a/fs/ecryptfs/Makefile b/fs/ecryptfs/Makefile index ca6562451eeb..1f1107237eab 100644 --- a/fs/ecryptfs/Makefile +++ b/fs/ecryptfs/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o | 5 | obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o |
6 | 6 | ||
7 | ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o crypto.o keystore.o debug.o | 7 | ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o crypto.o keystore.o messaging.o netlink.o debug.o |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 508648efa447..f21385f97da5 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/fs_stack.h> | 33 | #include <linux/fs_stack.h> |
34 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
35 | #include <linux/scatterlist.h> | 35 | #include <linux/scatterlist.h> |
36 | #include <linux/hash.h> | ||
36 | 37 | ||
37 | /* Version verification for shared data structures w/ userspace */ | 38 | /* Version verification for shared data structures w/ userspace */ |
38 | #define ECRYPTFS_VERSION_MAJOR 0x00 | 39 | #define ECRYPTFS_VERSION_MAJOR 0x00 |
@@ -47,7 +48,8 @@ | |||
47 | #define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004 | 48 | #define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004 |
48 | #define ECRYPTFS_VERSIONING_POLICY 0x00000008 | 49 | #define ECRYPTFS_VERSIONING_POLICY 0x00000008 |
49 | #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ | 50 | #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ |
50 | | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH) | 51 | | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ |
52 | | ECRYPTFS_VERSIONING_PUBKEY) | ||
51 | 53 | ||
52 | #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 | 54 | #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 |
53 | #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH | 55 | #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH |
@@ -558,7 +560,8 @@ int ecryptfs_close_lower_file(struct file *lower_file); | |||
558 | 560 | ||
559 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid); | 561 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid); |
560 | int ecryptfs_process_quit(uid_t uid, pid_t pid); | 562 | int ecryptfs_process_quit(uid_t uid, pid_t pid); |
561 | int ecryptfs_process_response(struct ecryptfs_message *msg, pid_t pid, u32 seq); | 563 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, |
564 | pid_t pid, u32 seq); | ||
562 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, | 565 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, |
563 | struct ecryptfs_msg_ctx **msg_ctx); | 566 | struct ecryptfs_msg_ctx **msg_ctx); |
564 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, | 567 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 80bccd5ff8e6..558d538e2b1f 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * Copyright (C) 2004-2006 International Business Machines Corp. | 7 | * Copyright (C) 2004-2006 International Business Machines Corp. |
8 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> | 8 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> |
9 | * Michael C. Thompson <mcthomps@us.ibm.com> | 9 | * Michael C. Thompson <mcthomps@us.ibm.com> |
10 | * Trevor S. Highland <trevor.highland@gmail.com> | ||
10 | * | 11 | * |
11 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License as | 13 | * modify it under the terms of the GNU General Public License as |
@@ -64,26 +65,6 @@ int process_request_key_err(long err_code) | |||
64 | return rc; | 65 | return rc; |
65 | } | 66 | } |
66 | 67 | ||
67 | static void wipe_auth_tok_list(struct list_head *auth_tok_list_head) | ||
68 | { | ||
69 | struct list_head *walker; | ||
70 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
71 | |||
72 | walker = auth_tok_list_head->next; | ||
73 | while (walker != auth_tok_list_head) { | ||
74 | auth_tok_list_item = | ||
75 | list_entry(walker, struct ecryptfs_auth_tok_list_item, | ||
76 | list); | ||
77 | walker = auth_tok_list_item->list.next; | ||
78 | memset(auth_tok_list_item, 0, | ||
79 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
80 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | ||
81 | auth_tok_list_item); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | struct kmem_cache *ecryptfs_auth_tok_list_item_cache; | ||
86 | |||
87 | /** | 68 | /** |
88 | * parse_packet_length | 69 | * parse_packet_length |
89 | * @data: Pointer to memory containing length at offset | 70 | * @data: Pointer to memory containing length at offset |
@@ -102,12 +83,12 @@ static int parse_packet_length(unsigned char *data, size_t *size, | |||
102 | (*size) = 0; | 83 | (*size) = 0; |
103 | if (data[0] < 192) { | 84 | if (data[0] < 192) { |
104 | /* One-byte length */ | 85 | /* One-byte length */ |
105 | (*size) = data[0]; | 86 | (*size) = (unsigned char)data[0]; |
106 | (*length_size) = 1; | 87 | (*length_size) = 1; |
107 | } else if (data[0] < 224) { | 88 | } else if (data[0] < 224) { |
108 | /* Two-byte length */ | 89 | /* Two-byte length */ |
109 | (*size) = ((data[0] - 192) * 256); | 90 | (*size) = (((unsigned char)(data[0]) - 192) * 256); |
110 | (*size) += (data[1] + 192); | 91 | (*size) += ((unsigned char)(data[1]) + 192); |
111 | (*length_size) = 2; | 92 | (*length_size) = 2; |
112 | } else if (data[0] == 255) { | 93 | } else if (data[0] == 255) { |
113 | /* Five-byte length; we're not supposed to see this */ | 94 | /* Five-byte length; we're not supposed to see this */ |
@@ -154,6 +135,499 @@ static int write_packet_length(char *dest, size_t size, | |||
154 | return rc; | 135 | return rc; |
155 | } | 136 | } |
156 | 137 | ||
138 | static int | ||
139 | write_tag_64_packet(char *signature, struct ecryptfs_session_key *session_key, | ||
140 | char **packet, size_t *packet_len) | ||
141 | { | ||
142 | size_t i = 0; | ||
143 | size_t data_len; | ||
144 | size_t packet_size_len; | ||
145 | char *message; | ||
146 | int rc; | ||
147 | |||
148 | /* | ||
149 | * ***** TAG 64 Packet Format ***** | ||
150 | * | Content Type | 1 byte | | ||
151 | * | Key Identifier Size | 1 or 2 bytes | | ||
152 | * | Key Identifier | arbitrary | | ||
153 | * | Encrypted File Encryption Key Size | 1 or 2 bytes | | ||
154 | * | Encrypted File Encryption Key | arbitrary | | ||
155 | */ | ||
156 | data_len = (5 + ECRYPTFS_SIG_SIZE_HEX | ||
157 | + session_key->encrypted_key_size); | ||
158 | *packet = kmalloc(data_len, GFP_KERNEL); | ||
159 | message = *packet; | ||
160 | if (!message) { | ||
161 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | ||
162 | rc = -ENOMEM; | ||
163 | goto out; | ||
164 | } | ||
165 | message[i++] = ECRYPTFS_TAG_64_PACKET_TYPE; | ||
166 | rc = write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, | ||
167 | &packet_size_len); | ||
168 | if (rc) { | ||
169 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " | ||
170 | "header; cannot generate packet length\n"); | ||
171 | goto out; | ||
172 | } | ||
173 | i += packet_size_len; | ||
174 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); | ||
175 | i += ECRYPTFS_SIG_SIZE_HEX; | ||
176 | rc = write_packet_length(&message[i], session_key->encrypted_key_size, | ||
177 | &packet_size_len); | ||
178 | if (rc) { | ||
179 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " | ||
180 | "header; cannot generate packet length\n"); | ||
181 | goto out; | ||
182 | } | ||
183 | i += packet_size_len; | ||
184 | memcpy(&message[i], session_key->encrypted_key, | ||
185 | session_key->encrypted_key_size); | ||
186 | i += session_key->encrypted_key_size; | ||
187 | *packet_len = i; | ||
188 | out: | ||
189 | return rc; | ||
190 | } | ||
191 | |||
192 | static int | ||
193 | parse_tag_65_packet(struct ecryptfs_session_key *session_key, u16 *cipher_code, | ||
194 | struct ecryptfs_message *msg) | ||
195 | { | ||
196 | size_t i = 0; | ||
197 | char *data; | ||
198 | size_t data_len; | ||
199 | size_t m_size; | ||
200 | size_t message_len; | ||
201 | u16 checksum = 0; | ||
202 | u16 expected_checksum = 0; | ||
203 | int rc; | ||
204 | |||
205 | /* | ||
206 | * ***** TAG 65 Packet Format ***** | ||
207 | * | Content Type | 1 byte | | ||
208 | * | Status Indicator | 1 byte | | ||
209 | * | File Encryption Key Size | 1 or 2 bytes | | ||
210 | * | File Encryption Key | arbitrary | | ||
211 | */ | ||
212 | message_len = msg->data_len; | ||
213 | data = msg->data; | ||
214 | if (message_len < 4) { | ||
215 | rc = -EIO; | ||
216 | goto out; | ||
217 | } | ||
218 | if (data[i++] != ECRYPTFS_TAG_65_PACKET_TYPE) { | ||
219 | ecryptfs_printk(KERN_ERR, "Type should be ECRYPTFS_TAG_65\n"); | ||
220 | rc = -EIO; | ||
221 | goto out; | ||
222 | } | ||
223 | if (data[i++]) { | ||
224 | ecryptfs_printk(KERN_ERR, "Status indicator has non-zero value " | ||
225 | "[%d]\n", data[i-1]); | ||
226 | rc = -EIO; | ||
227 | goto out; | ||
228 | } | ||
229 | rc = parse_packet_length(&data[i], &m_size, &data_len); | ||
230 | if (rc) { | ||
231 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | ||
232 | "rc = [%d]\n", rc); | ||
233 | goto out; | ||
234 | } | ||
235 | i += data_len; | ||
236 | if (message_len < (i + m_size)) { | ||
237 | ecryptfs_printk(KERN_ERR, "The received netlink message is " | ||
238 | "shorter than expected\n"); | ||
239 | rc = -EIO; | ||
240 | goto out; | ||
241 | } | ||
242 | if (m_size < 3) { | ||
243 | ecryptfs_printk(KERN_ERR, | ||
244 | "The decrypted key is not long enough to " | ||
245 | "include a cipher code and checksum\n"); | ||
246 | rc = -EIO; | ||
247 | goto out; | ||
248 | } | ||
249 | *cipher_code = data[i++]; | ||
250 | /* The decrypted key includes 1 byte cipher code and 2 byte checksum */ | ||
251 | session_key->decrypted_key_size = m_size - 3; | ||
252 | if (session_key->decrypted_key_size > ECRYPTFS_MAX_KEY_BYTES) { | ||
253 | ecryptfs_printk(KERN_ERR, "key_size [%d] larger than " | ||
254 | "the maximum key size [%d]\n", | ||
255 | session_key->decrypted_key_size, | ||
256 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); | ||
257 | rc = -EIO; | ||
258 | goto out; | ||
259 | } | ||
260 | memcpy(session_key->decrypted_key, &data[i], | ||
261 | session_key->decrypted_key_size); | ||
262 | i += session_key->decrypted_key_size; | ||
263 | expected_checksum += (unsigned char)(data[i++]) << 8; | ||
264 | expected_checksum += (unsigned char)(data[i++]); | ||
265 | for (i = 0; i < session_key->decrypted_key_size; i++) | ||
266 | checksum += session_key->decrypted_key[i]; | ||
267 | if (expected_checksum != checksum) { | ||
268 | ecryptfs_printk(KERN_ERR, "Invalid checksum for file " | ||
269 | "encryption key; expected [%x]; calculated " | ||
270 | "[%x]\n", expected_checksum, checksum); | ||
271 | rc = -EIO; | ||
272 | } | ||
273 | out: | ||
274 | return rc; | ||
275 | } | ||
276 | |||
277 | |||
278 | static int | ||
279 | write_tag_66_packet(char *signature, size_t cipher_code, | ||
280 | struct ecryptfs_crypt_stat *crypt_stat, char **packet, | ||
281 | size_t *packet_len) | ||
282 | { | ||
283 | size_t i = 0; | ||
284 | size_t j; | ||
285 | size_t data_len; | ||
286 | size_t checksum = 0; | ||
287 | size_t packet_size_len; | ||
288 | char *message; | ||
289 | int rc; | ||
290 | |||
291 | /* | ||
292 | * ***** TAG 66 Packet Format ***** | ||
293 | * | Content Type | 1 byte | | ||
294 | * | Key Identifier Size | 1 or 2 bytes | | ||
295 | * | Key Identifier | arbitrary | | ||
296 | * | File Encryption Key Size | 1 or 2 bytes | | ||
297 | * | File Encryption Key | arbitrary | | ||
298 | */ | ||
299 | data_len = (5 + ECRYPTFS_SIG_SIZE_HEX + crypt_stat->key_size); | ||
300 | *packet = kmalloc(data_len, GFP_KERNEL); | ||
301 | message = *packet; | ||
302 | if (!message) { | ||
303 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | ||
304 | rc = -ENOMEM; | ||
305 | goto out; | ||
306 | } | ||
307 | message[i++] = ECRYPTFS_TAG_66_PACKET_TYPE; | ||
308 | rc = write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, | ||
309 | &packet_size_len); | ||
310 | if (rc) { | ||
311 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " | ||
312 | "header; cannot generate packet length\n"); | ||
313 | goto out; | ||
314 | } | ||
315 | i += packet_size_len; | ||
316 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); | ||
317 | i += ECRYPTFS_SIG_SIZE_HEX; | ||
318 | /* The encrypted key includes 1 byte cipher code and 2 byte checksum */ | ||
319 | rc = write_packet_length(&message[i], crypt_stat->key_size + 3, | ||
320 | &packet_size_len); | ||
321 | if (rc) { | ||
322 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " | ||
323 | "header; cannot generate packet length\n"); | ||
324 | goto out; | ||
325 | } | ||
326 | i += packet_size_len; | ||
327 | message[i++] = cipher_code; | ||
328 | memcpy(&message[i], crypt_stat->key, crypt_stat->key_size); | ||
329 | i += crypt_stat->key_size; | ||
330 | for (j = 0; j < crypt_stat->key_size; j++) | ||
331 | checksum += crypt_stat->key[j]; | ||
332 | message[i++] = (checksum / 256) % 256; | ||
333 | message[i++] = (checksum % 256); | ||
334 | *packet_len = i; | ||
335 | out: | ||
336 | return rc; | ||
337 | } | ||
338 | |||
339 | static int | ||
340 | parse_tag_67_packet(struct ecryptfs_key_record *key_rec, | ||
341 | struct ecryptfs_message *msg) | ||
342 | { | ||
343 | size_t i = 0; | ||
344 | char *data; | ||
345 | size_t data_len; | ||
346 | size_t message_len; | ||
347 | int rc; | ||
348 | |||
349 | /* | ||
350 | * ***** TAG 65 Packet Format ***** | ||
351 | * | Content Type | 1 byte | | ||
352 | * | Status Indicator | 1 byte | | ||
353 | * | Encrypted File Encryption Key Size | 1 or 2 bytes | | ||
354 | * | Encrypted File Encryption Key | arbitrary | | ||
355 | */ | ||
356 | message_len = msg->data_len; | ||
357 | data = msg->data; | ||
358 | /* verify that everything through the encrypted FEK size is present */ | ||
359 | if (message_len < 4) { | ||
360 | rc = -EIO; | ||
361 | goto out; | ||
362 | } | ||
363 | if (data[i++] != ECRYPTFS_TAG_67_PACKET_TYPE) { | ||
364 | ecryptfs_printk(KERN_ERR, "Type should be ECRYPTFS_TAG_67\n"); | ||
365 | rc = -EIO; | ||
366 | goto out; | ||
367 | } | ||
368 | if (data[i++]) { | ||
369 | ecryptfs_printk(KERN_ERR, "Status indicator has non zero value" | ||
370 | " [%d]\n", data[i-1]); | ||
371 | rc = -EIO; | ||
372 | goto out; | ||
373 | } | ||
374 | rc = parse_packet_length(&data[i], &key_rec->enc_key_size, &data_len); | ||
375 | if (rc) { | ||
376 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | ||
377 | "rc = [%d]\n", rc); | ||
378 | goto out; | ||
379 | } | ||
380 | i += data_len; | ||
381 | if (message_len < (i + key_rec->enc_key_size)) { | ||
382 | ecryptfs_printk(KERN_ERR, "message_len [%d]; max len is [%d]\n", | ||
383 | message_len, (i + key_rec->enc_key_size)); | ||
384 | rc = -EIO; | ||
385 | goto out; | ||
386 | } | ||
387 | if (key_rec->enc_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | ||
388 | ecryptfs_printk(KERN_ERR, "Encrypted key_size [%d] larger than " | ||
389 | "the maximum key size [%d]\n", | ||
390 | key_rec->enc_key_size, | ||
391 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); | ||
392 | rc = -EIO; | ||
393 | goto out; | ||
394 | } | ||
395 | memcpy(key_rec->enc_key, &data[i], key_rec->enc_key_size); | ||
396 | out: | ||
397 | return rc; | ||
398 | } | ||
399 | |||
400 | /** | ||
401 | * decrypt_pki_encrypted_session_key - Decrypt the session key with | ||
402 | * the given auth_tok. | ||
403 | * | ||
404 | * Returns Zero on success; non-zero error otherwise. | ||
405 | */ | ||
406 | static int decrypt_pki_encrypted_session_key( | ||
407 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
408 | struct ecryptfs_auth_tok *auth_tok, | ||
409 | struct ecryptfs_crypt_stat *crypt_stat) | ||
410 | { | ||
411 | u16 cipher_code = 0; | ||
412 | struct ecryptfs_msg_ctx *msg_ctx; | ||
413 | struct ecryptfs_message *msg = NULL; | ||
414 | char *netlink_message; | ||
415 | size_t netlink_message_length; | ||
416 | int rc; | ||
417 | |||
418 | rc = write_tag_64_packet(mount_crypt_stat->global_auth_tok_sig, | ||
419 | &(auth_tok->session_key), | ||
420 | &netlink_message, &netlink_message_length); | ||
421 | if (rc) { | ||
422 | ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet"); | ||
423 | goto out; | ||
424 | } | ||
425 | rc = ecryptfs_send_message(ecryptfs_transport, netlink_message, | ||
426 | netlink_message_length, &msg_ctx); | ||
427 | if (rc) { | ||
428 | ecryptfs_printk(KERN_ERR, "Error sending netlink message\n"); | ||
429 | goto out; | ||
430 | } | ||
431 | rc = ecryptfs_wait_for_response(msg_ctx, &msg); | ||
432 | if (rc) { | ||
433 | ecryptfs_printk(KERN_ERR, "Failed to receive tag 65 packet " | ||
434 | "from the user space daemon\n"); | ||
435 | rc = -EIO; | ||
436 | goto out; | ||
437 | } | ||
438 | rc = parse_tag_65_packet(&(auth_tok->session_key), | ||
439 | &cipher_code, msg); | ||
440 | if (rc) { | ||
441 | printk(KERN_ERR "Failed to parse tag 65 packet; rc = [%d]\n", | ||
442 | rc); | ||
443 | goto out; | ||
444 | } | ||
445 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; | ||
446 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, | ||
447 | auth_tok->session_key.decrypted_key_size); | ||
448 | crypt_stat->key_size = auth_tok->session_key.decrypted_key_size; | ||
449 | rc = ecryptfs_cipher_code_to_string(crypt_stat->cipher, cipher_code); | ||
450 | if (rc) { | ||
451 | ecryptfs_printk(KERN_ERR, "Cipher code [%d] is invalid\n", | ||
452 | cipher_code) | ||
453 | goto out; | ||
454 | } | ||
455 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; | ||
456 | if (ecryptfs_verbosity > 0) { | ||
457 | ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); | ||
458 | ecryptfs_dump_hex(crypt_stat->key, | ||
459 | crypt_stat->key_size); | ||
460 | } | ||
461 | out: | ||
462 | if (msg) | ||
463 | kfree(msg); | ||
464 | return rc; | ||
465 | } | ||
466 | |||
467 | static void wipe_auth_tok_list(struct list_head *auth_tok_list_head) | ||
468 | { | ||
469 | struct list_head *walker; | ||
470 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
471 | |||
472 | walker = auth_tok_list_head->next; | ||
473 | while (walker != auth_tok_list_head) { | ||
474 | auth_tok_list_item = | ||
475 | list_entry(walker, struct ecryptfs_auth_tok_list_item, | ||
476 | list); | ||
477 | walker = auth_tok_list_item->list.next; | ||
478 | memset(auth_tok_list_item, 0, | ||
479 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
480 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | ||
481 | auth_tok_list_item); | ||
482 | } | ||
483 | auth_tok_list_head->next = NULL; | ||
484 | } | ||
485 | |||
486 | struct kmem_cache *ecryptfs_auth_tok_list_item_cache; | ||
487 | |||
488 | |||
489 | /** | ||
490 | * parse_tag_1_packet | ||
491 | * @crypt_stat: The cryptographic context to modify based on packet | ||
492 | * contents. | ||
493 | * @data: The raw bytes of the packet. | ||
494 | * @auth_tok_list: eCryptfs parses packets into authentication tokens; | ||
495 | * a new authentication token will be placed at the end | ||
496 | * of this list for this packet. | ||
497 | * @new_auth_tok: Pointer to a pointer to memory that this function | ||
498 | * allocates; sets the memory address of the pointer to | ||
499 | * NULL on error. This object is added to the | ||
500 | * auth_tok_list. | ||
501 | * @packet_size: This function writes the size of the parsed packet | ||
502 | * into this memory location; zero on error. | ||
503 | * | ||
504 | * Returns zero on success; non-zero on error. | ||
505 | */ | ||
506 | static int | ||
507 | parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat, | ||
508 | unsigned char *data, struct list_head *auth_tok_list, | ||
509 | struct ecryptfs_auth_tok **new_auth_tok, | ||
510 | size_t *packet_size, size_t max_packet_size) | ||
511 | { | ||
512 | size_t body_size; | ||
513 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
514 | size_t length_size; | ||
515 | int rc = 0; | ||
516 | |||
517 | (*packet_size) = 0; | ||
518 | (*new_auth_tok) = NULL; | ||
519 | |||
520 | /* we check that: | ||
521 | * one byte for the Tag 1 ID flag | ||
522 | * two bytes for the body size | ||
523 | * do not exceed the maximum_packet_size | ||
524 | */ | ||
525 | if (unlikely((*packet_size) + 3 > max_packet_size)) { | ||
526 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | ||
527 | rc = -EINVAL; | ||
528 | goto out; | ||
529 | } | ||
530 | /* check for Tag 1 identifier - one byte */ | ||
531 | if (data[(*packet_size)++] != ECRYPTFS_TAG_1_PACKET_TYPE) { | ||
532 | ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n", | ||
533 | ECRYPTFS_TAG_1_PACKET_TYPE); | ||
534 | rc = -EINVAL; | ||
535 | goto out; | ||
536 | } | ||
537 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or | ||
538 | * at end of function upon failure */ | ||
539 | auth_tok_list_item = | ||
540 | kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, | ||
541 | GFP_KERNEL); | ||
542 | if (!auth_tok_list_item) { | ||
543 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | ||
544 | rc = -ENOMEM; | ||
545 | goto out; | ||
546 | } | ||
547 | memset(auth_tok_list_item, 0, | ||
548 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
549 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; | ||
550 | /* check for body size - one to two bytes | ||
551 | * | ||
552 | * ***** TAG 1 Packet Format ***** | ||
553 | * | version number | 1 byte | | ||
554 | * | key ID | 8 bytes | | ||
555 | * | public key algorithm | 1 byte | | ||
556 | * | encrypted session key | arbitrary | | ||
557 | */ | ||
558 | rc = parse_packet_length(&data[(*packet_size)], &body_size, | ||
559 | &length_size); | ||
560 | if (rc) { | ||
561 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | ||
562 | "rc = [%d]\n", rc); | ||
563 | goto out_free; | ||
564 | } | ||
565 | if (unlikely(body_size < (0x02 + ECRYPTFS_SIG_SIZE))) { | ||
566 | ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n", | ||
567 | body_size); | ||
568 | rc = -EINVAL; | ||
569 | goto out_free; | ||
570 | } | ||
571 | (*packet_size) += length_size; | ||
572 | if (unlikely((*packet_size) + body_size > max_packet_size)) { | ||
573 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | ||
574 | rc = -EINVAL; | ||
575 | goto out_free; | ||
576 | } | ||
577 | /* Version 3 (from RFC2440) - one byte */ | ||
578 | if (unlikely(data[(*packet_size)++] != 0x03)) { | ||
579 | ecryptfs_printk(KERN_DEBUG, "Unknown version number " | ||
580 | "[%d]\n", data[(*packet_size) - 1]); | ||
581 | rc = -EINVAL; | ||
582 | goto out_free; | ||
583 | } | ||
584 | /* Read Signature */ | ||
585 | ecryptfs_to_hex((*new_auth_tok)->token.private_key.signature, | ||
586 | &data[(*packet_size)], ECRYPTFS_SIG_SIZE); | ||
587 | *packet_size += ECRYPTFS_SIG_SIZE; | ||
588 | /* This byte is skipped because the kernel does not need to | ||
589 | * know which public key encryption algorithm was used */ | ||
590 | (*packet_size)++; | ||
591 | (*new_auth_tok)->session_key.encrypted_key_size = | ||
592 | body_size - (0x02 + ECRYPTFS_SIG_SIZE); | ||
593 | if ((*new_auth_tok)->session_key.encrypted_key_size | ||
594 | > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | ||
595 | ecryptfs_printk(KERN_ERR, "Tag 1 packet contains key larger " | ||
596 | "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES"); | ||
597 | rc = -EINVAL; | ||
598 | goto out; | ||
599 | } | ||
600 | ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n", | ||
601 | (*new_auth_tok)->session_key.encrypted_key_size); | ||
602 | memcpy((*new_auth_tok)->session_key.encrypted_key, | ||
603 | &data[(*packet_size)], (body_size - 0x02 - ECRYPTFS_SIG_SIZE)); | ||
604 | (*packet_size) += (*new_auth_tok)->session_key.encrypted_key_size; | ||
605 | (*new_auth_tok)->session_key.flags &= | ||
606 | ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; | ||
607 | (*new_auth_tok)->session_key.flags |= | ||
608 | ECRYPTFS_CONTAINS_ENCRYPTED_KEY; | ||
609 | (*new_auth_tok)->token_type = ECRYPTFS_PRIVATE_KEY; | ||
610 | ECRYPTFS_SET_FLAG((*new_auth_tok)->flags, ECRYPTFS_PRIVATE_KEY); | ||
611 | /* TODO: Why are we setting this flag here? Don't we want the | ||
612 | * userspace to decrypt the session key? */ | ||
613 | ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags, | ||
614 | ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); | ||
615 | ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags, | ||
616 | ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); | ||
617 | list_add(&auth_tok_list_item->list, auth_tok_list); | ||
618 | goto out; | ||
619 | out_free: | ||
620 | (*new_auth_tok) = NULL; | ||
621 | memset(auth_tok_list_item, 0, | ||
622 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
623 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | ||
624 | auth_tok_list_item); | ||
625 | out: | ||
626 | if (rc) | ||
627 | (*packet_size) = 0; | ||
628 | return rc; | ||
629 | } | ||
630 | |||
157 | /** | 631 | /** |
158 | * parse_tag_3_packet | 632 | * parse_tag_3_packet |
159 | * @crypt_stat: The cryptographic context to modify based on packet | 633 | * @crypt_stat: The cryptographic context to modify based on packet |
@@ -178,10 +652,10 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
178 | struct ecryptfs_auth_tok **new_auth_tok, | 652 | struct ecryptfs_auth_tok **new_auth_tok, |
179 | size_t *packet_size, size_t max_packet_size) | 653 | size_t *packet_size, size_t max_packet_size) |
180 | { | 654 | { |
181 | int rc = 0; | ||
182 | size_t body_size; | 655 | size_t body_size; |
183 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | 656 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; |
184 | size_t length_size; | 657 | size_t length_size; |
658 | int rc = 0; | ||
185 | 659 | ||
186 | (*packet_size) = 0; | 660 | (*packet_size) = 0; |
187 | (*new_auth_tok) = NULL; | 661 | (*new_auth_tok) = NULL; |
@@ -358,9 +832,9 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents, | |||
358 | size_t max_contents_bytes, size_t *tag_11_contents_size, | 832 | size_t max_contents_bytes, size_t *tag_11_contents_size, |
359 | size_t *packet_size, size_t max_packet_size) | 833 | size_t *packet_size, size_t max_packet_size) |
360 | { | 834 | { |
361 | int rc = 0; | ||
362 | size_t body_size; | 835 | size_t body_size; |
363 | size_t length_size; | 836 | size_t length_size; |
837 | int rc = 0; | ||
364 | 838 | ||
365 | (*packet_size) = 0; | 839 | (*packet_size) = 0; |
366 | (*tag_11_contents_size) = 0; | 840 | (*tag_11_contents_size) = 0; |
@@ -459,7 +933,6 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
459 | struct ecryptfs_password *password_s_ptr; | 933 | struct ecryptfs_password *password_s_ptr; |
460 | struct scatterlist src_sg[2], dst_sg[2]; | 934 | struct scatterlist src_sg[2], dst_sg[2]; |
461 | struct mutex *tfm_mutex = NULL; | 935 | struct mutex *tfm_mutex = NULL; |
462 | /* TODO: Use virt_to_scatterlist for these */ | ||
463 | char *encrypted_session_key; | 936 | char *encrypted_session_key; |
464 | char *session_key; | 937 | char *session_key; |
465 | struct blkcipher_desc desc = { | 938 | struct blkcipher_desc desc = { |
@@ -587,7 +1060,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
587 | struct dentry *ecryptfs_dentry) | 1060 | struct dentry *ecryptfs_dentry) |
588 | { | 1061 | { |
589 | size_t i = 0; | 1062 | size_t i = 0; |
590 | int rc = 0; | ||
591 | size_t found_auth_tok = 0; | 1063 | size_t found_auth_tok = 0; |
592 | size_t next_packet_is_auth_tok_packet; | 1064 | size_t next_packet_is_auth_tok_packet; |
593 | char sig[ECRYPTFS_SIG_SIZE_HEX]; | 1065 | char sig[ECRYPTFS_SIG_SIZE_HEX]; |
@@ -603,6 +1075,7 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
603 | unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; | 1075 | unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; |
604 | size_t tag_11_contents_size; | 1076 | size_t tag_11_contents_size; |
605 | size_t tag_11_packet_size; | 1077 | size_t tag_11_packet_size; |
1078 | int rc = 0; | ||
606 | 1079 | ||
607 | INIT_LIST_HEAD(&auth_tok_list); | 1080 | INIT_LIST_HEAD(&auth_tok_list); |
608 | /* Parse the header to find as many packets as we can, these will be | 1081 | /* Parse the header to find as many packets as we can, these will be |
@@ -657,6 +1130,21 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
657 | ECRYPTFS_SET_FLAG(crypt_stat->flags, | 1130 | ECRYPTFS_SET_FLAG(crypt_stat->flags, |
658 | ECRYPTFS_ENCRYPTED); | 1131 | ECRYPTFS_ENCRYPTED); |
659 | break; | 1132 | break; |
1133 | case ECRYPTFS_TAG_1_PACKET_TYPE: | ||
1134 | rc = parse_tag_1_packet(crypt_stat, | ||
1135 | (unsigned char *)&src[i], | ||
1136 | &auth_tok_list, &new_auth_tok, | ||
1137 | &packet_size, max_packet_size); | ||
1138 | if (rc) { | ||
1139 | ecryptfs_printk(KERN_ERR, "Error parsing " | ||
1140 | "tag 1 packet\n"); | ||
1141 | rc = -EIO; | ||
1142 | goto out_wipe_list; | ||
1143 | } | ||
1144 | i += packet_size; | ||
1145 | ECRYPTFS_SET_FLAG(crypt_stat->flags, | ||
1146 | ECRYPTFS_ENCRYPTED); | ||
1147 | break; | ||
660 | case ECRYPTFS_TAG_11_PACKET_TYPE: | 1148 | case ECRYPTFS_TAG_11_PACKET_TYPE: |
661 | ecryptfs_printk(KERN_WARNING, "Invalid packet set " | 1149 | ecryptfs_printk(KERN_WARNING, "Invalid packet set " |
662 | "(Tag 11 not allowed by itself)\n"); | 1150 | "(Tag 11 not allowed by itself)\n"); |
@@ -704,31 +1192,47 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
704 | goto leave_list; | 1192 | goto leave_list; |
705 | /* TODO: Transfer the common salt into the | 1193 | /* TODO: Transfer the common salt into the |
706 | * crypt_stat salt */ | 1194 | * crypt_stat salt */ |
1195 | } else if ((candidate_auth_tok->token_type | ||
1196 | == ECRYPTFS_PRIVATE_KEY) | ||
1197 | && !strncmp(candidate_auth_tok->token.private_key.signature, | ||
1198 | sig, ECRYPTFS_SIG_SIZE_HEX)) { | ||
1199 | found_auth_tok = 1; | ||
1200 | goto leave_list; | ||
707 | } | 1201 | } |
708 | } | 1202 | } |
709 | leave_list: | ||
710 | if (!found_auth_tok) { | 1203 | if (!found_auth_tok) { |
711 | ecryptfs_printk(KERN_ERR, "Could not find authentication " | 1204 | ecryptfs_printk(KERN_ERR, "Could not find authentication " |
712 | "token on temporary list for sig [%.*s]\n", | 1205 | "token on temporary list for sig [%.*s]\n", |
713 | ECRYPTFS_SIG_SIZE_HEX, sig); | 1206 | ECRYPTFS_SIG_SIZE_HEX, sig); |
714 | rc = -EIO; | 1207 | rc = -EIO; |
715 | goto out_wipe_list; | 1208 | goto out_wipe_list; |
716 | } else { | 1209 | } |
1210 | leave_list: | ||
1211 | rc = -ENOTSUPP; | ||
1212 | if ((ECRYPTFS_CHECK_FLAG(candidate_auth_tok->flags, | ||
1213 | ECRYPTFS_PRIVATE_KEY))) { | ||
1214 | memcpy(&(candidate_auth_tok->token.private_key), | ||
1215 | &(chosen_auth_tok->token.private_key), | ||
1216 | sizeof(struct ecryptfs_private_key)); | ||
1217 | rc = decrypt_pki_encrypted_session_key(mount_crypt_stat, | ||
1218 | candidate_auth_tok, | ||
1219 | crypt_stat); | ||
1220 | } else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) { | ||
717 | memcpy(&(candidate_auth_tok->token.password), | 1221 | memcpy(&(candidate_auth_tok->token.password), |
718 | &(chosen_auth_tok->token.password), | 1222 | &(chosen_auth_tok->token.password), |
719 | sizeof(struct ecryptfs_password)); | 1223 | sizeof(struct ecryptfs_password)); |
720 | rc = decrypt_session_key(candidate_auth_tok, crypt_stat); | 1224 | rc = decrypt_session_key(candidate_auth_tok, crypt_stat); |
721 | if (rc) { | 1225 | } |
722 | ecryptfs_printk(KERN_ERR, "Error decrypting the " | 1226 | if (rc) { |
723 | "session key\n"); | 1227 | ecryptfs_printk(KERN_ERR, "Error decrypting the " |
724 | goto out_wipe_list; | 1228 | "session key; rc = [%d]\n", rc); |
725 | } | 1229 | goto out_wipe_list; |
726 | rc = ecryptfs_compute_root_iv(crypt_stat); | 1230 | } |
727 | if (rc) { | 1231 | rc = ecryptfs_compute_root_iv(crypt_stat); |
728 | ecryptfs_printk(KERN_ERR, "Error computing " | 1232 | if (rc) { |
729 | "the root IV\n"); | 1233 | ecryptfs_printk(KERN_ERR, "Error computing " |
730 | goto out_wipe_list; | 1234 | "the root IV\n"); |
731 | } | 1235 | goto out_wipe_list; |
732 | } | 1236 | } |
733 | rc = ecryptfs_init_crypt_ctx(crypt_stat); | 1237 | rc = ecryptfs_init_crypt_ctx(crypt_stat); |
734 | if (rc) { | 1238 | if (rc) { |
@@ -741,6 +1245,145 @@ out_wipe_list: | |||
741 | out: | 1245 | out: |
742 | return rc; | 1246 | return rc; |
743 | } | 1247 | } |
1248 | static int | ||
1249 | pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | ||
1250 | struct ecryptfs_crypt_stat *crypt_stat, | ||
1251 | struct ecryptfs_key_record *key_rec) | ||
1252 | { | ||
1253 | struct ecryptfs_msg_ctx *msg_ctx = NULL; | ||
1254 | char *netlink_payload; | ||
1255 | size_t netlink_payload_length; | ||
1256 | struct ecryptfs_message *msg; | ||
1257 | int rc; | ||
1258 | |||
1259 | rc = write_tag_66_packet(auth_tok->token.private_key.signature, | ||
1260 | ecryptfs_code_for_cipher_string(crypt_stat), | ||
1261 | crypt_stat, &netlink_payload, | ||
1262 | &netlink_payload_length); | ||
1263 | if (rc) { | ||
1264 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); | ||
1265 | goto out; | ||
1266 | } | ||
1267 | rc = ecryptfs_send_message(ecryptfs_transport, netlink_payload, | ||
1268 | netlink_payload_length, &msg_ctx); | ||
1269 | if (rc) { | ||
1270 | ecryptfs_printk(KERN_ERR, "Error sending netlink message\n"); | ||
1271 | goto out; | ||
1272 | } | ||
1273 | rc = ecryptfs_wait_for_response(msg_ctx, &msg); | ||
1274 | if (rc) { | ||
1275 | ecryptfs_printk(KERN_ERR, "Failed to receive tag 67 packet " | ||
1276 | "from the user space daemon\n"); | ||
1277 | rc = -EIO; | ||
1278 | goto out; | ||
1279 | } | ||
1280 | rc = parse_tag_67_packet(key_rec, msg); | ||
1281 | if (rc) | ||
1282 | ecryptfs_printk(KERN_ERR, "Error parsing tag 67 packet\n"); | ||
1283 | kfree(msg); | ||
1284 | out: | ||
1285 | if (netlink_payload) | ||
1286 | kfree(netlink_payload); | ||
1287 | return rc; | ||
1288 | } | ||
1289 | /** | ||
1290 | * write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet | ||
1291 | * @dest: Buffer into which to write the packet | ||
1292 | * @max: Maximum number of bytes that can be writtn | ||
1293 | * @packet_size: This function will write the number of bytes that end | ||
1294 | * up constituting the packet; set to zero on error | ||
1295 | * | ||
1296 | * Returns zero on success; non-zero on error. | ||
1297 | */ | ||
1298 | static int | ||
1299 | write_tag_1_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | ||
1300 | struct ecryptfs_crypt_stat *crypt_stat, | ||
1301 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
1302 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | ||
1303 | { | ||
1304 | size_t i; | ||
1305 | size_t encrypted_session_key_valid = 0; | ||
1306 | size_t key_rec_size; | ||
1307 | size_t packet_size_length; | ||
1308 | int rc = 0; | ||
1309 | |||
1310 | (*packet_size) = 0; | ||
1311 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.private_key.signature, | ||
1312 | ECRYPTFS_SIG_SIZE); | ||
1313 | encrypted_session_key_valid = 0; | ||
1314 | for (i = 0; i < crypt_stat->key_size; i++) | ||
1315 | encrypted_session_key_valid |= | ||
1316 | auth_tok->session_key.encrypted_key[i]; | ||
1317 | if (encrypted_session_key_valid) { | ||
1318 | memcpy(key_rec->enc_key, | ||
1319 | auth_tok->session_key.encrypted_key, | ||
1320 | auth_tok->session_key.encrypted_key_size); | ||
1321 | goto encrypted_session_key_set; | ||
1322 | } | ||
1323 | if (auth_tok->session_key.encrypted_key_size == 0) | ||
1324 | auth_tok->session_key.encrypted_key_size = | ||
1325 | auth_tok->token.private_key.key_size; | ||
1326 | rc = pki_encrypt_session_key(auth_tok, crypt_stat, key_rec); | ||
1327 | if (rc) { | ||
1328 | ecryptfs_printk(KERN_ERR, "Failed to encrypt session key " | ||
1329 | "via a pki"); | ||
1330 | goto out; | ||
1331 | } | ||
1332 | if (ecryptfs_verbosity > 0) { | ||
1333 | ecryptfs_printk(KERN_DEBUG, "Encrypted key:\n"); | ||
1334 | ecryptfs_dump_hex(key_rec->enc_key, key_rec->enc_key_size); | ||
1335 | } | ||
1336 | encrypted_session_key_set: | ||
1337 | /* Now we have a valid key_rec. Append it to the | ||
1338 | * key_rec set. */ | ||
1339 | key_rec_size = (sizeof(struct ecryptfs_key_record) | ||
1340 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES | ||
1341 | + (key_rec->enc_key_size)); | ||
1342 | /* TODO: Include a packet size limit as a parameter to this | ||
1343 | * function once we have multi-packet headers (for versions | ||
1344 | * later than 0.1 */ | ||
1345 | if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) { | ||
1346 | ecryptfs_printk(KERN_ERR, "Keyset too large\n"); | ||
1347 | rc = -EINVAL; | ||
1348 | goto out; | ||
1349 | } | ||
1350 | /* ***** TAG 1 Packet Format ***** | ||
1351 | * | version number | 1 byte | | ||
1352 | * | key ID | 8 bytes | | ||
1353 | * | public key algorithm | 1 byte | | ||
1354 | * | encrypted session key | arbitrary | | ||
1355 | */ | ||
1356 | if ((0x02 + ECRYPTFS_SIG_SIZE + key_rec->enc_key_size) >= max) { | ||
1357 | ecryptfs_printk(KERN_ERR, | ||
1358 | "Authentication token is too large\n"); | ||
1359 | rc = -EINVAL; | ||
1360 | goto out; | ||
1361 | } | ||
1362 | dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE; | ||
1363 | /* This format is inspired by OpenPGP; see RFC 2440 | ||
1364 | * packet tag 1 */ | ||
1365 | rc = write_packet_length(&dest[(*packet_size)], | ||
1366 | (0x02 + ECRYPTFS_SIG_SIZE + | ||
1367 | key_rec->enc_key_size), | ||
1368 | &packet_size_length); | ||
1369 | if (rc) { | ||
1370 | ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet " | ||
1371 | "header; cannot generate packet length\n"); | ||
1372 | goto out; | ||
1373 | } | ||
1374 | (*packet_size) += packet_size_length; | ||
1375 | dest[(*packet_size)++] = 0x03; /* version 3 */ | ||
1376 | memcpy(&dest[(*packet_size)], key_rec->sig, ECRYPTFS_SIG_SIZE); | ||
1377 | (*packet_size) += ECRYPTFS_SIG_SIZE; | ||
1378 | dest[(*packet_size)++] = RFC2440_CIPHER_RSA; | ||
1379 | memcpy(&dest[(*packet_size)], key_rec->enc_key, | ||
1380 | key_rec->enc_key_size); | ||
1381 | (*packet_size) += key_rec->enc_key_size; | ||
1382 | out: | ||
1383 | if (rc) | ||
1384 | (*packet_size) = 0; | ||
1385 | return rc; | ||
1386 | } | ||
744 | 1387 | ||
745 | /** | 1388 | /** |
746 | * write_tag_11_packet | 1389 | * write_tag_11_packet |
@@ -756,8 +1399,8 @@ static int | |||
756 | write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length, | 1399 | write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length, |
757 | size_t *packet_length) | 1400 | size_t *packet_length) |
758 | { | 1401 | { |
759 | int rc = 0; | ||
760 | size_t packet_size_length; | 1402 | size_t packet_size_length; |
1403 | int rc = 0; | ||
761 | 1404 | ||
762 | (*packet_length) = 0; | 1405 | (*packet_length) = 0; |
763 | if ((13 + contents_length) > max) { | 1406 | if ((13 + contents_length) > max) { |
@@ -815,7 +1458,6 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
815 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | 1458 | struct ecryptfs_key_record *key_rec, size_t *packet_size) |
816 | { | 1459 | { |
817 | size_t i; | 1460 | size_t i; |
818 | size_t signature_is_valid = 0; | ||
819 | size_t encrypted_session_key_valid = 0; | 1461 | size_t encrypted_session_key_valid = 0; |
820 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; | 1462 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; |
821 | struct scatterlist dest_sg[2]; | 1463 | struct scatterlist dest_sg[2]; |
@@ -831,19 +1473,14 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
831 | int rc = 0; | 1473 | int rc = 0; |
832 | 1474 | ||
833 | (*packet_size) = 0; | 1475 | (*packet_size) = 0; |
834 | /* Check for a valid signature on the auth_tok */ | 1476 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature, |
835 | for (i = 0; i < ECRYPTFS_SIG_SIZE_HEX; i++) | ||
836 | signature_is_valid |= auth_tok->token.password.signature[i]; | ||
837 | if (!signature_is_valid) | ||
838 | BUG(); | ||
839 | ecryptfs_from_hex((*key_rec).sig, auth_tok->token.password.signature, | ||
840 | ECRYPTFS_SIG_SIZE); | 1477 | ECRYPTFS_SIG_SIZE); |
841 | encrypted_session_key_valid = 0; | 1478 | encrypted_session_key_valid = 0; |
842 | for (i = 0; i < crypt_stat->key_size; i++) | 1479 | for (i = 0; i < crypt_stat->key_size; i++) |
843 | encrypted_session_key_valid |= | 1480 | encrypted_session_key_valid |= |
844 | auth_tok->session_key.encrypted_key[i]; | 1481 | auth_tok->session_key.encrypted_key[i]; |
845 | if (encrypted_session_key_valid) { | 1482 | if (encrypted_session_key_valid) { |
846 | memcpy((*key_rec).enc_key, | 1483 | memcpy(key_rec->enc_key, |
847 | auth_tok->session_key.encrypted_key, | 1484 | auth_tok->session_key.encrypted_key, |
848 | auth_tok->session_key.encrypted_key_size); | 1485 | auth_tok->session_key.encrypted_key_size); |
849 | goto encrypted_session_key_set; | 1486 | goto encrypted_session_key_set; |
@@ -856,10 +1493,10 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
856 | memset((crypt_stat->key + 24), 0, 8); | 1493 | memset((crypt_stat->key + 24), 0, 8); |
857 | auth_tok->session_key.encrypted_key_size = 32; | 1494 | auth_tok->session_key.encrypted_key_size = 32; |
858 | } | 1495 | } |
859 | (*key_rec).enc_key_size = | 1496 | key_rec->enc_key_size = |
860 | auth_tok->session_key.encrypted_key_size; | 1497 | auth_tok->session_key.encrypted_key_size; |
861 | if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags, | 1498 | if (auth_tok->token.password.flags & |
862 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) { | 1499 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) { |
863 | ecryptfs_printk(KERN_DEBUG, "Using previously generated " | 1500 | ecryptfs_printk(KERN_DEBUG, "Using previously generated " |
864 | "session key encryption key of size [%d]\n", | 1501 | "session key encryption key of size [%d]\n", |
865 | auth_tok->token.password. | 1502 | auth_tok->token.password. |
@@ -877,15 +1514,15 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
877 | ecryptfs_dump_hex(session_key_encryption_key, 16); | 1514 | ecryptfs_dump_hex(session_key_encryption_key, 16); |
878 | } | 1515 | } |
879 | rc = virt_to_scatterlist(crypt_stat->key, | 1516 | rc = virt_to_scatterlist(crypt_stat->key, |
880 | (*key_rec).enc_key_size, src_sg, 2); | 1517 | key_rec->enc_key_size, src_sg, 2); |
881 | if (!rc) { | 1518 | if (!rc) { |
882 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | 1519 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " |
883 | "for crypt_stat session key\n"); | 1520 | "for crypt_stat session key\n"); |
884 | rc = -ENOMEM; | 1521 | rc = -ENOMEM; |
885 | goto out; | 1522 | goto out; |
886 | } | 1523 | } |
887 | rc = virt_to_scatterlist((*key_rec).enc_key, | 1524 | rc = virt_to_scatterlist(key_rec->enc_key, |
888 | (*key_rec).enc_key_size, dest_sg, 2); | 1525 | key_rec->enc_key_size, dest_sg, 2); |
889 | if (!rc) { | 1526 | if (!rc) { |
890 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | 1527 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " |
891 | "for crypt_stat encrypted session key\n"); | 1528 | "for crypt_stat encrypted session key\n"); |
@@ -941,14 +1578,14 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
941 | mutex_unlock(tfm_mutex); | 1578 | mutex_unlock(tfm_mutex); |
942 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); | 1579 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); |
943 | if (ecryptfs_verbosity > 0) | 1580 | if (ecryptfs_verbosity > 0) |
944 | ecryptfs_dump_hex((*key_rec).enc_key, | 1581 | ecryptfs_dump_hex(key_rec->enc_key, |
945 | (*key_rec).enc_key_size); | 1582 | key_rec->enc_key_size); |
946 | encrypted_session_key_set: | 1583 | encrypted_session_key_set: |
947 | /* Now we have a valid key_rec. Append it to the | 1584 | /* Now we have a valid key_rec. Append it to the |
948 | * key_rec set. */ | 1585 | * key_rec set. */ |
949 | key_rec_size = (sizeof(struct ecryptfs_key_record) | 1586 | key_rec_size = (sizeof(struct ecryptfs_key_record) |
950 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES | 1587 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES |
951 | + ((*key_rec).enc_key_size)); | 1588 | + (key_rec->enc_key_size)); |
952 | /* TODO: Include a packet size limit as a parameter to this | 1589 | /* TODO: Include a packet size limit as a parameter to this |
953 | * function once we have multi-packet headers (for versions | 1590 | * function once we have multi-packet headers (for versions |
954 | * later than 0.1 */ | 1591 | * later than 0.1 */ |
@@ -960,7 +1597,7 @@ encrypted_session_key_set: | |||
960 | /* TODO: Packet size limit */ | 1597 | /* TODO: Packet size limit */ |
961 | /* We have 5 bytes of surrounding packet data */ | 1598 | /* We have 5 bytes of surrounding packet data */ |
962 | if ((0x05 + ECRYPTFS_SALT_SIZE | 1599 | if ((0x05 + ECRYPTFS_SALT_SIZE |
963 | + (*key_rec).enc_key_size) >= max) { | 1600 | + key_rec->enc_key_size) >= max) { |
964 | ecryptfs_printk(KERN_ERR, "Authentication token is too " | 1601 | ecryptfs_printk(KERN_ERR, "Authentication token is too " |
965 | "large\n"); | 1602 | "large\n"); |
966 | rc = -EINVAL; | 1603 | rc = -EINVAL; |
@@ -972,7 +1609,7 @@ encrypted_session_key_set: | |||
972 | /* ver+cipher+s2k+hash+salt+iter+enc_key */ | 1609 | /* ver+cipher+s2k+hash+salt+iter+enc_key */ |
973 | rc = write_packet_length(&dest[(*packet_size)], | 1610 | rc = write_packet_length(&dest[(*packet_size)], |
974 | (0x05 + ECRYPTFS_SALT_SIZE | 1611 | (0x05 + ECRYPTFS_SALT_SIZE |
975 | + (*key_rec).enc_key_size), | 1612 | + key_rec->enc_key_size), |
976 | &packet_size_length); | 1613 | &packet_size_length); |
977 | if (rc) { | 1614 | if (rc) { |
978 | ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet " | 1615 | ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet " |
@@ -995,9 +1632,9 @@ encrypted_session_key_set: | |||
995 | ECRYPTFS_SALT_SIZE); | 1632 | ECRYPTFS_SALT_SIZE); |
996 | (*packet_size) += ECRYPTFS_SALT_SIZE; /* salt */ | 1633 | (*packet_size) += ECRYPTFS_SALT_SIZE; /* salt */ |
997 | dest[(*packet_size)++] = 0x60; /* hash iterations (65536) */ | 1634 | dest[(*packet_size)++] = 0x60; /* hash iterations (65536) */ |
998 | memcpy(&dest[(*packet_size)], (*key_rec).enc_key, | 1635 | memcpy(&dest[(*packet_size)], key_rec->enc_key, |
999 | (*key_rec).enc_key_size); | 1636 | key_rec->enc_key_size); |
1000 | (*packet_size) += (*key_rec).enc_key_size; | 1637 | (*packet_size) += key_rec->enc_key_size; |
1001 | out: | 1638 | out: |
1002 | if (desc.tfm && !tfm_mutex) | 1639 | if (desc.tfm && !tfm_mutex) |
1003 | crypto_free_blkcipher(desc.tfm); | 1640 | crypto_free_blkcipher(desc.tfm); |
@@ -1027,13 +1664,13 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1027 | struct dentry *ecryptfs_dentry, size_t *len, | 1664 | struct dentry *ecryptfs_dentry, size_t *len, |
1028 | size_t max) | 1665 | size_t max) |
1029 | { | 1666 | { |
1030 | int rc = 0; | ||
1031 | struct ecryptfs_auth_tok *auth_tok; | 1667 | struct ecryptfs_auth_tok *auth_tok; |
1032 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 1668 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
1033 | &ecryptfs_superblock_to_private( | 1669 | &ecryptfs_superblock_to_private( |
1034 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 1670 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
1035 | size_t written; | 1671 | size_t written; |
1036 | struct ecryptfs_key_record key_rec; | 1672 | struct ecryptfs_key_record key_rec; |
1673 | int rc = 0; | ||
1037 | 1674 | ||
1038 | (*len) = 0; | 1675 | (*len) = 0; |
1039 | if (mount_crypt_stat->global_auth_tok) { | 1676 | if (mount_crypt_stat->global_auth_tok) { |
@@ -1060,20 +1697,23 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1060 | goto out; | 1697 | goto out; |
1061 | } | 1698 | } |
1062 | (*len) += written; | 1699 | (*len) += written; |
1700 | } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { | ||
1701 | rc = write_tag_1_packet(dest_base + (*len), | ||
1702 | max, auth_tok, | ||
1703 | crypt_stat,mount_crypt_stat, | ||
1704 | &key_rec, &written); | ||
1705 | if (rc) { | ||
1706 | ecryptfs_printk(KERN_WARNING, "Error " | ||
1707 | "writing tag 1 packet\n"); | ||
1708 | goto out; | ||
1709 | } | ||
1710 | (*len) += written; | ||
1063 | } else { | 1711 | } else { |
1064 | ecryptfs_printk(KERN_WARNING, "Unsupported " | 1712 | ecryptfs_printk(KERN_WARNING, "Unsupported " |
1065 | "authentication token type\n"); | 1713 | "authentication token type\n"); |
1066 | rc = -EINVAL; | 1714 | rc = -EINVAL; |
1067 | goto out; | 1715 | goto out; |
1068 | } | 1716 | } |
1069 | if (rc) { | ||
1070 | ecryptfs_printk(KERN_WARNING, "Error writing " | ||
1071 | "authentication token packet with sig " | ||
1072 | "= [%s]\n", | ||
1073 | mount_crypt_stat->global_auth_tok_sig); | ||
1074 | rc = -EIO; | ||
1075 | goto out; | ||
1076 | } | ||
1077 | } else | 1717 | } else |
1078 | BUG(); | 1718 | BUG(); |
1079 | if (likely((max - (*len)) > 0)) { | 1719 | if (likely((max - (*len)) > 0)) { |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index fe41ab1566ee..87f05c4bd509 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (C) 2004-2006 International Business Machines Corp. | 6 | * Copyright (C) 2004-2006 International Business Machines Corp. |
7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | 7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> |
8 | * Michael C. Thompson <mcthomps@us.ibm.com> | 8 | * Michael C. Thompson <mcthomps@us.ibm.com> |
9 | * Tyler Hicks <tyhicks@ou.edu> | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU General Public License as | 12 | * modify it under the terms of the GNU General Public License as |
@@ -48,6 +49,43 @@ MODULE_PARM_DESC(ecryptfs_verbosity, | |||
48 | "Initial verbosity level (0 or 1; defaults to " | 49 | "Initial verbosity level (0 or 1; defaults to " |
49 | "0, which is Quiet)"); | 50 | "0, which is Quiet)"); |
50 | 51 | ||
52 | /** | ||
53 | * Module parameter that defines the number of netlink message buffer | ||
54 | * elements | ||
55 | */ | ||
56 | unsigned int ecryptfs_message_buf_len = ECRYPTFS_DEFAULT_MSG_CTX_ELEMS; | ||
57 | |||
58 | module_param(ecryptfs_message_buf_len, uint, 0); | ||
59 | MODULE_PARM_DESC(ecryptfs_message_buf_len, | ||
60 | "Number of message buffer elements"); | ||
61 | |||
62 | /** | ||
63 | * Module parameter that defines the maximum guaranteed amount of time to wait | ||
64 | * for a response through netlink. The actual sleep time will be, more than | ||
65 | * likely, a small amount greater than this specified value, but only less if | ||
66 | * the netlink message successfully arrives. | ||
67 | */ | ||
68 | signed long ecryptfs_message_wait_timeout = ECRYPTFS_MAX_MSG_CTX_TTL / HZ; | ||
69 | |||
70 | module_param(ecryptfs_message_wait_timeout, long, 0); | ||
71 | MODULE_PARM_DESC(ecryptfs_message_wait_timeout, | ||
72 | "Maximum number of seconds that an operation will " | ||
73 | "sleep while waiting for a message response from " | ||
74 | "userspace"); | ||
75 | |||
76 | /** | ||
77 | * Module parameter that is an estimate of the maximum number of users | ||
78 | * that will be concurrently using eCryptfs. Set this to the right | ||
79 | * value to balance performance and memory use. | ||
80 | */ | ||
81 | unsigned int ecryptfs_number_of_users = ECRYPTFS_DEFAULT_NUM_USERS; | ||
82 | |||
83 | module_param(ecryptfs_number_of_users, uint, 0); | ||
84 | MODULE_PARM_DESC(ecryptfs_number_of_users, "An estimate of the number of " | ||
85 | "concurrent users of eCryptfs"); | ||
86 | |||
87 | unsigned int ecryptfs_transport = ECRYPTFS_DEFAULT_TRANSPORT; | ||
88 | |||
51 | void __ecryptfs_printk(const char *fmt, ...) | 89 | void __ecryptfs_printk(const char *fmt, ...) |
52 | { | 90 | { |
53 | va_list args; | 91 | va_list args; |
@@ -347,9 +385,10 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
347 | rc = -EINVAL; | 385 | rc = -EINVAL; |
348 | goto out; | 386 | goto out; |
349 | } | 387 | } |
350 | if (auth_tok->token_type != ECRYPTFS_PASSWORD) { | 388 | if (auth_tok->token_type != ECRYPTFS_PASSWORD |
389 | && auth_tok->token_type != ECRYPTFS_PRIVATE_KEY) { | ||
351 | ecryptfs_printk(KERN_ERR, "Invalid auth_tok structure " | 390 | ecryptfs_printk(KERN_ERR, "Invalid auth_tok structure " |
352 | "returned from key\n"); | 391 | "returned from key query\n"); |
353 | rc = -EINVAL; | 392 | rc = -EINVAL; |
354 | goto out; | 393 | goto out; |
355 | } | 394 | } |
@@ -794,6 +833,11 @@ static int __init ecryptfs_init(void) | |||
794 | ecryptfs_free_kmem_caches(); | 833 | ecryptfs_free_kmem_caches(); |
795 | goto out; | 834 | goto out; |
796 | } | 835 | } |
836 | rc = ecryptfs_init_messaging(ecryptfs_transport); | ||
837 | if (rc) { | ||
838 | ecryptfs_printk(KERN_ERR, "Failure occured while attempting to " | ||
839 | "initialize the eCryptfs netlink socket\n"); | ||
840 | } | ||
797 | out: | 841 | out: |
798 | return rc; | 842 | return rc; |
799 | } | 843 | } |
@@ -805,6 +849,7 @@ static void __exit ecryptfs_exit(void) | |||
805 | sysfs_remove_file(&ecryptfs_subsys.kset.kobj, | 849 | sysfs_remove_file(&ecryptfs_subsys.kset.kobj, |
806 | &sysfs_attr_version_str.attr); | 850 | &sysfs_attr_version_str.attr); |
807 | subsystem_unregister(&ecryptfs_subsys); | 851 | subsystem_unregister(&ecryptfs_subsys); |
852 | ecryptfs_release_messaging(ecryptfs_transport); | ||
808 | unregister_filesystem(&ecryptfs_fs_type); | 853 | unregister_filesystem(&ecryptfs_fs_type); |
809 | ecryptfs_free_kmem_caches(); | 854 | ecryptfs_free_kmem_caches(); |
810 | } | 855 | } |
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index c22b32fc8e8c..e8ba6278ad2c 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -243,7 +243,8 @@ unlock: | |||
243 | * userspace. Returns zero upon delivery to desired context element; | 243 | * userspace. Returns zero upon delivery to desired context element; |
244 | * non-zero upon delivery failure or error. | 244 | * non-zero upon delivery failure or error. |
245 | */ | 245 | */ |
246 | int ecryptfs_process_response(struct ecryptfs_message *msg, pid_t pid, u32 seq) | 246 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, |
247 | pid_t pid, u32 seq) | ||
247 | { | 248 | { |
248 | struct ecryptfs_daemon_id *id; | 249 | struct ecryptfs_daemon_id *id; |
249 | struct ecryptfs_msg_ctx *msg_ctx; | 250 | struct ecryptfs_msg_ctx *msg_ctx; |
@@ -268,6 +269,13 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, pid_t pid, u32 seq) | |||
268 | msg_ctx->task->euid, pid); | 269 | msg_ctx->task->euid, pid); |
269 | goto wake_up; | 270 | goto wake_up; |
270 | } | 271 | } |
272 | if (msg_ctx->task->euid != uid) { | ||
273 | rc = -EBADMSG; | ||
274 | ecryptfs_printk(KERN_WARNING, "Received message from user " | ||
275 | "[%d]; expected message from user [%d]\n", | ||
276 | uid, msg_ctx->task->euid); | ||
277 | goto unlock; | ||
278 | } | ||
271 | if (id->pid != pid) { | 279 | if (id->pid != pid) { |
272 | rc = -EBADMSG; | 280 | rc = -EBADMSG; |
273 | ecryptfs_printk(KERN_ERR, "User [%d] received a " | 281 | ecryptfs_printk(KERN_ERR, "User [%d] received a " |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 06843d24f239..0af3aa3b4b3e 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -528,90 +528,6 @@ out: | |||
528 | return rc; | 528 | return rc; |
529 | } | 529 | } |
530 | 530 | ||
531 | static int | ||
532 | process_new_file(struct ecryptfs_crypt_stat *crypt_stat, | ||
533 | struct file *file, struct inode *inode) | ||
534 | { | ||
535 | struct page *header_page; | ||
536 | const struct address_space_operations *lower_a_ops; | ||
537 | struct inode *lower_inode; | ||
538 | struct file *lower_file; | ||
539 | char *header_virt; | ||
540 | int rc = 0; | ||
541 | int current_header_page = 0; | ||
542 | int header_pages; | ||
543 | int more_header_data_to_be_written = 1; | ||
544 | |||
545 | lower_inode = ecryptfs_inode_to_lower(inode); | ||
546 | lower_file = ecryptfs_file_to_lower(file); | ||
547 | lower_a_ops = lower_inode->i_mapping->a_ops; | ||
548 | header_pages = ((crypt_stat->header_extent_size | ||
549 | * crypt_stat->num_header_extents_at_front) | ||
550 | / PAGE_CACHE_SIZE); | ||
551 | BUG_ON(header_pages < 1); | ||
552 | while (current_header_page < header_pages) { | ||
553 | rc = ecryptfs_grab_and_map_lower_page(&header_page, | ||
554 | &header_virt, | ||
555 | lower_inode, | ||
556 | current_header_page); | ||
557 | if (rc) { | ||
558 | ecryptfs_printk(KERN_ERR, "grab_cache_page for " | ||
559 | "header page [%d] failed; rc = [%d]\n", | ||
560 | current_header_page, rc); | ||
561 | goto out; | ||
562 | } | ||
563 | rc = lower_a_ops->prepare_write(lower_file, header_page, 0, | ||
564 | PAGE_CACHE_SIZE); | ||
565 | if (rc) { | ||
566 | ecryptfs_printk(KERN_ERR, "Error preparing to write " | ||
567 | "header page out; rc = [%d]\n", rc); | ||
568 | goto out; | ||
569 | } | ||
570 | memset(header_virt, 0, PAGE_CACHE_SIZE); | ||
571 | if (more_header_data_to_be_written) { | ||
572 | rc = ecryptfs_write_headers_virt(header_virt, | ||
573 | crypt_stat, | ||
574 | file->f_dentry); | ||
575 | if (rc) { | ||
576 | ecryptfs_printk(KERN_WARNING, "Error " | ||
577 | "generating header; rc = " | ||
578 | "[%d]\n", rc); | ||
579 | rc = -EIO; | ||
580 | memset(header_virt, 0, PAGE_CACHE_SIZE); | ||
581 | ecryptfs_unmap_and_release_lower_page( | ||
582 | header_page); | ||
583 | goto out; | ||
584 | } | ||
585 | if (current_header_page == 0) | ||
586 | memset(header_virt, 0, 8); | ||
587 | more_header_data_to_be_written = 0; | ||
588 | } | ||
589 | rc = lower_a_ops->commit_write(lower_file, header_page, 0, | ||
590 | PAGE_CACHE_SIZE); | ||
591 | ecryptfs_unmap_and_release_lower_page(header_page); | ||
592 | if (rc < 0) { | ||
593 | ecryptfs_printk(KERN_ERR, | ||
594 | "Error commiting header page write; " | ||
595 | "rc = [%d]\n", rc); | ||
596 | break; | ||
597 | } | ||
598 | current_header_page++; | ||
599 | } | ||
600 | if (rc >= 0) { | ||
601 | rc = 0; | ||
602 | ecryptfs_printk(KERN_DEBUG, "lower_inode->i_blocks = " | ||
603 | "[0x%.16x]\n", lower_inode->i_blocks); | ||
604 | i_size_write(inode, 0); | ||
605 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; | ||
606 | mark_inode_dirty_sync(inode); | ||
607 | } | ||
608 | ecryptfs_printk(KERN_DEBUG, "Clearing ECRYPTFS_NEW_FILE flag in " | ||
609 | "crypt_stat at memory location [%p]\n", crypt_stat); | ||
610 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE); | ||
611 | out: | ||
612 | return rc; | ||
613 | } | ||
614 | |||
615 | /** | 531 | /** |
616 | * ecryptfs_commit_write | 532 | * ecryptfs_commit_write |
617 | * @file: The eCryptfs file object | 533 | * @file: The eCryptfs file object |
@@ -643,12 +559,7 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, | |||
643 | if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) { | 559 | if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) { |
644 | ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " | 560 | ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " |
645 | "crypt_stat at memory location [%p]\n", crypt_stat); | 561 | "crypt_stat at memory location [%p]\n", crypt_stat); |
646 | rc = process_new_file(crypt_stat, file, inode); | 562 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE); |
647 | if (rc) { | ||
648 | ecryptfs_printk(KERN_ERR, "Error processing new " | ||
649 | "file; rc = [%d]\n", rc); | ||
650 | goto out; | ||
651 | } | ||
652 | } else | 563 | } else |
653 | ecryptfs_printk(KERN_DEBUG, "Not a new file\n"); | 564 | ecryptfs_printk(KERN_DEBUG, "Not a new file\n"); |
654 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" | 565 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" |
diff --git a/fs/ecryptfs/netlink.c b/fs/ecryptfs/netlink.c index aba061d62118..e3aa2253c850 100644 --- a/fs/ecryptfs/netlink.c +++ b/fs/ecryptfs/netlink.c | |||
@@ -107,8 +107,8 @@ static int ecryptfs_process_nl_response(struct sk_buff *skb) | |||
107 | "incorrectly specified data length\n"); | 107 | "incorrectly specified data length\n"); |
108 | goto out; | 108 | goto out; |
109 | } | 109 | } |
110 | rc = ecryptfs_process_response(msg, NETLINK_CREDS(skb)->pid, | 110 | rc = ecryptfs_process_response(msg, NETLINK_CREDS(skb)->uid, |
111 | nlh->nlmsg_seq); | 111 | NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq); |
112 | if (rc) | 112 | if (rc) |
113 | printk(KERN_ERR | 113 | printk(KERN_ERR |
114 | "Error processing response message; rc = [%d]\n", rc); | 114 | "Error processing response message; rc = [%d]\n", rc); |