Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * eCryptfs: Linux filesystem encryption layer
0004  *
0005  * Copyright (C) 2008 International Business Machines Corp.
0006  *   Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
0007  */
0008 
0009 #include <linux/fs.h>
0010 #include <linux/hash.h>
0011 #include <linux/random.h>
0012 #include <linux/miscdevice.h>
0013 #include <linux/poll.h>
0014 #include <linux/slab.h>
0015 #include <linux/wait.h>
0016 #include <linux/module.h>
0017 #include "ecryptfs_kernel.h"
0018 
0019 static atomic_t ecryptfs_num_miscdev_opens;
0020 
0021 /**
0022  * ecryptfs_miscdev_poll
0023  * @file: dev file
0024  * @pt: dev poll table (ignored)
0025  *
0026  * Returns the poll mask
0027  */
0028 static __poll_t
0029 ecryptfs_miscdev_poll(struct file *file, poll_table *pt)
0030 {
0031     struct ecryptfs_daemon *daemon = file->private_data;
0032     __poll_t mask = 0;
0033 
0034     mutex_lock(&daemon->mux);
0035     if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
0036         printk(KERN_WARNING "%s: Attempt to poll on zombified "
0037                "daemon\n", __func__);
0038         goto out_unlock_daemon;
0039     }
0040     if (daemon->flags & ECRYPTFS_DAEMON_IN_READ)
0041         goto out_unlock_daemon;
0042     if (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)
0043         goto out_unlock_daemon;
0044     daemon->flags |= ECRYPTFS_DAEMON_IN_POLL;
0045     mutex_unlock(&daemon->mux);
0046     poll_wait(file, &daemon->wait, pt);
0047     mutex_lock(&daemon->mux);
0048     if (!list_empty(&daemon->msg_ctx_out_queue))
0049         mask |= EPOLLIN | EPOLLRDNORM;
0050 out_unlock_daemon:
0051     daemon->flags &= ~ECRYPTFS_DAEMON_IN_POLL;
0052     mutex_unlock(&daemon->mux);
0053     return mask;
0054 }
0055 
0056 /**
0057  * ecryptfs_miscdev_open
0058  * @inode: inode of miscdev handle (ignored)
0059  * @file: file for miscdev handle
0060  *
0061  * Returns zero on success; non-zero otherwise
0062  */
0063 static int
0064 ecryptfs_miscdev_open(struct inode *inode, struct file *file)
0065 {
0066     struct ecryptfs_daemon *daemon = NULL;
0067     int rc;
0068 
0069     mutex_lock(&ecryptfs_daemon_hash_mux);
0070     rc = ecryptfs_find_daemon_by_euid(&daemon);
0071     if (!rc) {
0072         rc = -EINVAL;
0073         goto out_unlock_daemon_list;
0074     }
0075     rc = ecryptfs_spawn_daemon(&daemon, file);
0076     if (rc) {
0077         printk(KERN_ERR "%s: Error attempting to spawn daemon; "
0078                "rc = [%d]\n", __func__, rc);
0079         goto out_unlock_daemon_list;
0080     }
0081     mutex_lock(&daemon->mux);
0082     if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) {
0083         rc = -EBUSY;
0084         goto out_unlock_daemon;
0085     }
0086     daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN;
0087     file->private_data = daemon;
0088     atomic_inc(&ecryptfs_num_miscdev_opens);
0089 out_unlock_daemon:
0090     mutex_unlock(&daemon->mux);
0091 out_unlock_daemon_list:
0092     mutex_unlock(&ecryptfs_daemon_hash_mux);
0093     return rc;
0094 }
0095 
0096 /**
0097  * ecryptfs_miscdev_release
0098  * @inode: inode of fs/ecryptfs/euid handle (ignored)
0099  * @file: file for fs/ecryptfs/euid handle
0100  *
0101  * This keeps the daemon registered until the daemon sends another
0102  * ioctl to fs/ecryptfs/ctl or until the kernel module unregisters.
0103  *
0104  * Returns zero on success; non-zero otherwise
0105  */
0106 static int
0107 ecryptfs_miscdev_release(struct inode *inode, struct file *file)
0108 {
0109     struct ecryptfs_daemon *daemon = file->private_data;
0110     int rc;
0111 
0112     mutex_lock(&daemon->mux);
0113     BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN));
0114     daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN;
0115     atomic_dec(&ecryptfs_num_miscdev_opens);
0116     mutex_unlock(&daemon->mux);
0117 
0118     mutex_lock(&ecryptfs_daemon_hash_mux);
0119     rc = ecryptfs_exorcise_daemon(daemon);
0120     mutex_unlock(&ecryptfs_daemon_hash_mux);
0121     if (rc) {
0122         printk(KERN_CRIT "%s: Fatal error whilst attempting to "
0123                "shut down daemon; rc = [%d]. Please report this "
0124                "bug.\n", __func__, rc);
0125         BUG();
0126     }
0127     return rc;
0128 }
0129 
0130 /**
0131  * ecryptfs_send_miscdev
0132  * @data: Data to send to daemon; may be NULL
0133  * @data_size: Amount of data to send to daemon
0134  * @msg_ctx: Message context, which is used to handle the reply. If
0135  *           this is NULL, then we do not expect a reply.
0136  * @msg_type: Type of message
0137  * @msg_flags: Flags for message
0138  * @daemon: eCryptfs daemon object
0139  *
0140  * Add msg_ctx to queue and then, if it exists, notify the blocked
0141  * miscdevess about the data being available. Must be called with
0142  * ecryptfs_daemon_hash_mux held.
0143  *
0144  * Returns zero on success; non-zero otherwise
0145  */
0146 int ecryptfs_send_miscdev(char *data, size_t data_size,
0147               struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
0148               u16 msg_flags, struct ecryptfs_daemon *daemon)
0149 {
0150     struct ecryptfs_message *msg;
0151 
0152     msg = kmalloc((sizeof(*msg) + data_size), GFP_KERNEL);
0153     if (!msg)
0154         return -ENOMEM;
0155 
0156     mutex_lock(&msg_ctx->mux);
0157     msg_ctx->msg = msg;
0158     msg_ctx->msg->index = msg_ctx->index;
0159     msg_ctx->msg->data_len = data_size;
0160     msg_ctx->type = msg_type;
0161     memcpy(msg_ctx->msg->data, data, data_size);
0162     msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size);
0163     list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue);
0164     mutex_unlock(&msg_ctx->mux);
0165 
0166     mutex_lock(&daemon->mux);
0167     daemon->num_queued_msg_ctx++;
0168     wake_up_interruptible(&daemon->wait);
0169     mutex_unlock(&daemon->mux);
0170 
0171     return 0;
0172 }
0173 
0174 /*
0175  * miscdevfs packet format:
0176  *  Octet 0: Type
0177  *  Octets 1-4: network byte order msg_ctx->counter
0178  *  Octets 5-N0: Size of struct ecryptfs_message to follow
0179  *  Octets N0-N1: struct ecryptfs_message (including data)
0180  *
0181  *  Octets 5-N1 not written if the packet type does not include a message
0182  */
0183 #define PKT_TYPE_SIZE       1
0184 #define PKT_CTR_SIZE        4
0185 #define MIN_NON_MSG_PKT_SIZE    (PKT_TYPE_SIZE + PKT_CTR_SIZE)
0186 #define MIN_MSG_PKT_SIZE    (PKT_TYPE_SIZE + PKT_CTR_SIZE \
0187                  + ECRYPTFS_MIN_PKT_LEN_SIZE)
0188 /* 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES comes from tag 65 packet format */
0189 #define MAX_MSG_PKT_SIZE    (PKT_TYPE_SIZE + PKT_CTR_SIZE \
0190                  + ECRYPTFS_MAX_PKT_LEN_SIZE \
0191                  + sizeof(struct ecryptfs_message) \
0192                  + 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)
0193 #define PKT_TYPE_OFFSET     0
0194 #define PKT_CTR_OFFSET      PKT_TYPE_SIZE
0195 #define PKT_LEN_OFFSET      (PKT_TYPE_SIZE + PKT_CTR_SIZE)
0196 
0197 /**
0198  * ecryptfs_miscdev_read - format and send message from queue
0199  * @file: miscdevfs handle
0200  * @buf: User buffer into which to copy the next message on the daemon queue
0201  * @count: Amount of space available in @buf
0202  * @ppos: Offset in file (ignored)
0203  *
0204  * Pulls the most recent message from the daemon queue, formats it for
0205  * being sent via a miscdevfs handle, and copies it into @buf
0206  *
0207  * Returns the number of bytes copied into the user buffer
0208  */
0209 static ssize_t
0210 ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
0211               loff_t *ppos)
0212 {
0213     struct ecryptfs_daemon *daemon = file->private_data;
0214     struct ecryptfs_msg_ctx *msg_ctx;
0215     size_t packet_length_size;
0216     char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE];
0217     size_t i;
0218     size_t total_length;
0219     int rc;
0220 
0221     mutex_lock(&daemon->mux);
0222     if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
0223         rc = 0;
0224         printk(KERN_WARNING "%s: Attempt to read from zombified "
0225                "daemon\n", __func__);
0226         goto out_unlock_daemon;
0227     }
0228     if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) {
0229         rc = 0;
0230         goto out_unlock_daemon;
0231     }
0232     /* This daemon will not go away so long as this flag is set */
0233     daemon->flags |= ECRYPTFS_DAEMON_IN_READ;
0234 check_list:
0235     if (list_empty(&daemon->msg_ctx_out_queue)) {
0236         mutex_unlock(&daemon->mux);
0237         rc = wait_event_interruptible(
0238             daemon->wait, !list_empty(&daemon->msg_ctx_out_queue));
0239         mutex_lock(&daemon->mux);
0240         if (rc < 0) {
0241             rc = 0;
0242             goto out_unlock_daemon;
0243         }
0244     }
0245     if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
0246         rc = 0;
0247         goto out_unlock_daemon;
0248     }
0249     if (list_empty(&daemon->msg_ctx_out_queue)) {
0250         /* Something else jumped in since the
0251          * wait_event_interruptable() and removed the
0252          * message from the queue; try again */
0253         goto check_list;
0254     }
0255     msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue,
0256                    struct ecryptfs_msg_ctx, daemon_out_list);
0257     BUG_ON(!msg_ctx);
0258     mutex_lock(&msg_ctx->mux);
0259     if (msg_ctx->msg) {
0260         rc = ecryptfs_write_packet_length(packet_length,
0261                           msg_ctx->msg_size,
0262                           &packet_length_size);
0263         if (rc) {
0264             rc = 0;
0265             printk(KERN_WARNING "%s: Error writing packet length; "
0266                    "rc = [%d]\n", __func__, rc);
0267             goto out_unlock_msg_ctx;
0268         }
0269     } else {
0270         packet_length_size = 0;
0271         msg_ctx->msg_size = 0;
0272     }
0273     total_length = (PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_length_size
0274             + msg_ctx->msg_size);
0275     if (count < total_length) {
0276         rc = 0;
0277         printk(KERN_WARNING "%s: Only given user buffer of "
0278                "size [%zd], but we need [%zd] to read the "
0279                "pending message\n", __func__, count, total_length);
0280         goto out_unlock_msg_ctx;
0281     }
0282     rc = -EFAULT;
0283     if (put_user(msg_ctx->type, buf))
0284         goto out_unlock_msg_ctx;
0285     if (put_user(cpu_to_be32(msg_ctx->counter),
0286              (__be32 __user *)(&buf[PKT_CTR_OFFSET])))
0287         goto out_unlock_msg_ctx;
0288     i = PKT_TYPE_SIZE + PKT_CTR_SIZE;
0289     if (msg_ctx->msg) {
0290         if (copy_to_user(&buf[i], packet_length, packet_length_size))
0291             goto out_unlock_msg_ctx;
0292         i += packet_length_size;
0293         if (copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size))
0294             goto out_unlock_msg_ctx;
0295         i += msg_ctx->msg_size;
0296     }
0297     rc = i;
0298     list_del(&msg_ctx->daemon_out_list);
0299     kfree(msg_ctx->msg);
0300     msg_ctx->msg = NULL;
0301     /* We do not expect a reply from the userspace daemon for any
0302      * message type other than ECRYPTFS_MSG_REQUEST */
0303     if (msg_ctx->type != ECRYPTFS_MSG_REQUEST)
0304         ecryptfs_msg_ctx_alloc_to_free(msg_ctx);
0305 out_unlock_msg_ctx:
0306     mutex_unlock(&msg_ctx->mux);
0307 out_unlock_daemon:
0308     daemon->flags &= ~ECRYPTFS_DAEMON_IN_READ;
0309     mutex_unlock(&daemon->mux);
0310     return rc;
0311 }
0312 
0313 /**
0314  * ecryptfs_miscdev_response - miscdevess response to message previously sent to daemon
0315  * @daemon: eCryptfs daemon object
0316  * @data: Bytes comprising struct ecryptfs_message
0317  * @data_size: sizeof(struct ecryptfs_message) + data len
0318  * @seq: Sequence number for miscdev response packet
0319  *
0320  * Returns zero on success; non-zero otherwise
0321  */
0322 static int ecryptfs_miscdev_response(struct ecryptfs_daemon *daemon, char *data,
0323                      size_t data_size, u32 seq)
0324 {
0325     struct ecryptfs_message *msg = (struct ecryptfs_message *)data;
0326     int rc;
0327 
0328     if ((sizeof(*msg) + msg->data_len) != data_size) {
0329         printk(KERN_WARNING "%s: (sizeof(*msg) + msg->data_len) = "
0330                "[%zd]; data_size = [%zd]. Invalid packet.\n", __func__,
0331                (sizeof(*msg) + msg->data_len), data_size);
0332         rc = -EINVAL;
0333         goto out;
0334     }
0335     rc = ecryptfs_process_response(daemon, msg, seq);
0336     if (rc)
0337         printk(KERN_ERR
0338                "Error processing response message; rc = [%d]\n", rc);
0339 out:
0340     return rc;
0341 }
0342 
0343 /**
0344  * ecryptfs_miscdev_write - handle write to daemon miscdev handle
0345  * @file: File for misc dev handle
0346  * @buf: Buffer containing user data
0347  * @count: Amount of data in @buf
0348  * @ppos: Pointer to offset in file (ignored)
0349  *
0350  * Returns the number of bytes read from @buf
0351  */
0352 static ssize_t
0353 ecryptfs_miscdev_write(struct file *file, const char __user *buf,
0354                size_t count, loff_t *ppos)
0355 {
0356     __be32 counter_nbo;
0357     u32 seq;
0358     size_t packet_size, packet_size_length;
0359     char *data;
0360     unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE];
0361     ssize_t rc;
0362 
0363     if (count == 0) {
0364         return 0;
0365     } else if (count == MIN_NON_MSG_PKT_SIZE) {
0366         /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */
0367         goto memdup;
0368     } else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) {
0369         printk(KERN_WARNING "%s: Acceptable packet size range is "
0370                "[%d-%zu], but amount of data written is [%zu].\n",
0371                __func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count);
0372         return -EINVAL;
0373     }
0374 
0375     if (copy_from_user(packet_size_peek, &buf[PKT_LEN_OFFSET],
0376                sizeof(packet_size_peek))) {
0377         printk(KERN_WARNING "%s: Error while inspecting packet size\n",
0378                __func__);
0379         return -EFAULT;
0380     }
0381 
0382     rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size,
0383                       &packet_size_length);
0384     if (rc) {
0385         printk(KERN_WARNING "%s: Error parsing packet length; "
0386                "rc = [%zd]\n", __func__, rc);
0387         return rc;
0388     }
0389 
0390     if ((PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_size_length + packet_size)
0391         != count) {
0392         printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__,
0393                packet_size);
0394         return -EINVAL;
0395     }
0396 
0397 memdup:
0398     data = memdup_user(buf, count);
0399     if (IS_ERR(data)) {
0400         printk(KERN_ERR "%s: memdup_user returned error [%ld]\n",
0401                __func__, PTR_ERR(data));
0402         return PTR_ERR(data);
0403     }
0404     switch (data[PKT_TYPE_OFFSET]) {
0405     case ECRYPTFS_MSG_RESPONSE:
0406         if (count < (MIN_MSG_PKT_SIZE
0407                  + sizeof(struct ecryptfs_message))) {
0408             printk(KERN_WARNING "%s: Minimum acceptable packet "
0409                    "size is [%zd], but amount of data written is "
0410                    "only [%zd]. Discarding response packet.\n",
0411                    __func__,
0412                    (MIN_MSG_PKT_SIZE
0413                 + sizeof(struct ecryptfs_message)), count);
0414             rc = -EINVAL;
0415             goto out_free;
0416         }
0417         memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE);
0418         seq = be32_to_cpu(counter_nbo);
0419         rc = ecryptfs_miscdev_response(file->private_data,
0420                 &data[PKT_LEN_OFFSET + packet_size_length],
0421                 packet_size, seq);
0422         if (rc) {
0423             printk(KERN_WARNING "%s: Failed to deliver miscdev "
0424                    "response to requesting operation; rc = [%zd]\n",
0425                    __func__, rc);
0426             goto out_free;
0427         }
0428         break;
0429     case ECRYPTFS_MSG_HELO:
0430     case ECRYPTFS_MSG_QUIT:
0431         break;
0432     default:
0433         ecryptfs_printk(KERN_WARNING, "Dropping miscdev "
0434                 "message of unrecognized type [%d]\n",
0435                 data[0]);
0436         rc = -EINVAL;
0437         goto out_free;
0438     }
0439     rc = count;
0440 out_free:
0441     kfree(data);
0442     return rc;
0443 }
0444 
0445 
0446 static const struct file_operations ecryptfs_miscdev_fops = {
0447     .owner   = THIS_MODULE,
0448     .open    = ecryptfs_miscdev_open,
0449     .poll    = ecryptfs_miscdev_poll,
0450     .read    = ecryptfs_miscdev_read,
0451     .write   = ecryptfs_miscdev_write,
0452     .release = ecryptfs_miscdev_release,
0453     .llseek  = noop_llseek,
0454 };
0455 
0456 static struct miscdevice ecryptfs_miscdev = {
0457     .minor = MISC_DYNAMIC_MINOR,
0458     .name  = "ecryptfs",
0459     .fops  = &ecryptfs_miscdev_fops
0460 };
0461 
0462 /**
0463  * ecryptfs_init_ecryptfs_miscdev
0464  *
0465  * Messages sent to the userspace daemon from the kernel are placed on
0466  * a queue associated with the daemon. The next read against the
0467  * miscdev handle by that daemon will return the oldest message placed
0468  * on the message queue for the daemon.
0469  *
0470  * Returns zero on success; non-zero otherwise
0471  */
0472 int __init ecryptfs_init_ecryptfs_miscdev(void)
0473 {
0474     int rc;
0475 
0476     atomic_set(&ecryptfs_num_miscdev_opens, 0);
0477     rc = misc_register(&ecryptfs_miscdev);
0478     if (rc)
0479         printk(KERN_ERR "%s: Failed to register miscellaneous device "
0480                "for communications with userspace daemons; rc = [%d]\n",
0481                __func__, rc);
0482     return rc;
0483 }
0484 
0485 /**
0486  * ecryptfs_destroy_ecryptfs_miscdev
0487  *
0488  * All of the daemons must be exorcised prior to calling this
0489  * function.
0490  */
0491 void ecryptfs_destroy_ecryptfs_miscdev(void)
0492 {
0493     BUG_ON(atomic_read(&ecryptfs_num_miscdev_opens) != 0);
0494     misc_deregister(&ecryptfs_miscdev);
0495 }