aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/miscdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ecryptfs/miscdev.c')
-rw-r--r--fs/ecryptfs/miscdev.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
index 940a82e63dc..0dc5a3d554a 100644
--- a/fs/ecryptfs/miscdev.c
+++ b/fs/ecryptfs/miscdev.c
@@ -409,11 +409,47 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
409 ssize_t sz = 0; 409 ssize_t sz = 0;
410 char *data; 410 char *data;
411 uid_t euid = current_euid(); 411 uid_t euid = current_euid();
412 unsigned char packet_size_peek[3];
412 int rc; 413 int rc;
413 414
414 if (count == 0) 415 if (count == 0) {
415 goto out; 416 goto out;
417 } else if (count == (1 + 4)) {
418 /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */
419 goto memdup;
420 } else if (count < (1 + 4 + 1)
421 || count > (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
422 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)) {
423 printk(KERN_WARNING "%s: Acceptable packet size range is "
424 "[%d-%lu], but amount of data written is [%zu].",
425 __func__, (1 + 4 + 1),
426 (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
427 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES), count);
428 return -EINVAL;
429 }
430
431 if (copy_from_user(packet_size_peek, (buf + 1 + 4),
432 sizeof(packet_size_peek))) {
433 printk(KERN_WARNING "%s: Error while inspecting packet size\n",
434 __func__);
435 return -EFAULT;
436 }
437
438 rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size,
439 &packet_size_length);
440 if (rc) {
441 printk(KERN_WARNING "%s: Error parsing packet length; "
442 "rc = [%d]\n", __func__, rc);
443 return rc;
444 }
445
446 if ((1 + 4 + packet_size_length + packet_size) != count) {
447 printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__,
448 packet_size);
449 return -EINVAL;
450 }
416 451
452memdup:
417 data = memdup_user(buf, count); 453 data = memdup_user(buf, count);
418 if (IS_ERR(data)) { 454 if (IS_ERR(data)) {
419 printk(KERN_ERR "%s: memdup_user returned error [%ld]\n", 455 printk(KERN_ERR "%s: memdup_user returned error [%ld]\n",
@@ -435,23 +471,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
435 } 471 }
436 memcpy(&counter_nbo, &data[i], 4); 472 memcpy(&counter_nbo, &data[i], 4);
437 seq = be32_to_cpu(counter_nbo); 473 seq = be32_to_cpu(counter_nbo);
438 i += 4; 474 i += 4 + packet_size_length;
439 rc = ecryptfs_parse_packet_length(&data[i], &packet_size,
440 &packet_size_length);
441 if (rc) {
442 printk(KERN_WARNING "%s: Error parsing packet length; "
443 "rc = [%d]\n", __func__, rc);
444 goto out_free;
445 }
446 i += packet_size_length;
447 if ((1 + 4 + packet_size_length + packet_size) != count) {
448 printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])"
449 " + packet_size([%zd]))([%zd]) != "
450 "count([%zd]). Invalid packet format.\n",
451 __func__, packet_size_length, packet_size,
452 (1 + packet_size_length + packet_size), count);
453 goto out_free;
454 }
455 rc = ecryptfs_miscdev_response(&data[i], packet_size, 475 rc = ecryptfs_miscdev_response(&data[i], packet_size,
456 euid, current_user_ns(), 476 euid, current_user_ns(),
457 task_pid(current), seq); 477 task_pid(current), seq);