linux/fs/ecryptfs/miscdev.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/**
   3 * eCryptfs: Linux filesystem encryption layer
   4 *
   5 * Copyright (C) 2008 International Business Machines Corp.
   6 *   Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
   7 */
   8
   9#include <linux/fs.h>
  10#include <linux/hash.h>
  11#include <linux/random.h>
  12#include <linux/miscdevice.h>
  13#include <linux/poll.h>
  14#include <linux/slab.h>
  15#include <linux/wait.h>
  16#include <linux/module.h>
  17#include "ecryptfs_kernel.h"
  18
  19static atomic_t ecryptfs_num_miscdev_opens;
  20
  21/**
  22 * ecryptfs_miscdev_poll
  23 * @file: dev file
  24 * @pt: dev poll table (ignored)
  25 *
  26 * Returns the poll mask
  27 */
  28static __poll_t
  29ecryptfs_miscdev_poll(struct file *file, poll_table *pt)
  30{
  31        struct ecryptfs_daemon *daemon = file->private_data;
  32        __poll_t mask = 0;
  33
  34        mutex_lock(&daemon->mux);
  35        if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
  36                printk(KERN_WARNING "%s: Attempt to poll on zombified "
  37                       "daemon\n", __func__);
  38                goto out_unlock_daemon;
  39        }
  40        if (daemon->flags & ECRYPTFS_DAEMON_IN_READ)
  41                goto out_unlock_daemon;
  42        if (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)
  43                goto out_unlock_daemon;
  44        daemon->flags |= ECRYPTFS_DAEMON_IN_POLL;
  45        mutex_unlock(&daemon->mux);
  46        poll_wait(file, &daemon->wait, pt);
  47        mutex_lock(&daemon->mux);
  48        if (!list_empty(&daemon->msg_ctx_out_queue))
  49                mask |= EPOLLIN | EPOLLRDNORM;
  50out_unlock_daemon:
  51        daemon->flags &= ~ECRYPTFS_DAEMON_IN_POLL;
  52        mutex_unlock(&daemon->mux);
  53        return mask;
  54}
  55
  56/**
  57 * ecryptfs_miscdev_open
  58 * @inode: inode of miscdev handle (ignored)
  59 * @file: file for miscdev handle
  60 *
  61 * Returns zero on success; non-zero otherwise
  62 */
  63static int
  64ecryptfs_miscdev_open(struct inode *inode, struct file *file)
  65{
  66        struct ecryptfs_daemon *daemon = NULL;
  67        int rc;
  68
  69        mutex_lock(&ecryptfs_daemon_hash_mux);
  70        rc = ecryptfs_find_daemon_by_euid(&daemon);
  71        if (!rc) {
  72                rc = -EINVAL;
  73                goto out_unlock_daemon_list;
  74        }
  75        rc = ecryptfs_spawn_daemon(&daemon, file);
  76        if (rc) {
  77                printk(KERN_ERR "%s: Error attempting to spawn daemon; "
  78                       "rc = [%d]\n", __func__, rc);
  79                goto out_unlock_daemon_list;
  80        }
  81        mutex_lock(&daemon->mux);
  82        if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) {
  83                rc = -EBUSY;
  84                goto out_unlock_daemon;
  85        }
  86        daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN;
  87        file->private_data = daemon;
  88        atomic_inc(&ecryptfs_num_miscdev_opens);
  89out_unlock_daemon:
  90        mutex_unlock(&daemon->mux);
  91out_unlock_daemon_list:
  92        mutex_unlock(&ecryptfs_daemon_hash_mux);
  93        return rc;
  94}
  95
  96/**
  97 * ecryptfs_miscdev_release
  98 * @inode: inode of fs/ecryptfs/euid handle (ignored)
  99 * @file: file for fs/ecryptfs/euid handle
 100 *
 101 * This keeps the daemon registered until the daemon sends another
 102 * ioctl to fs/ecryptfs/ctl or until the kernel module unregisters.
 103 *
 104 * Returns zero on success; non-zero otherwise
 105 */
 106static int
 107ecryptfs_miscdev_release(struct inode *inode, struct file *file)
 108{
 109        struct ecryptfs_daemon *daemon = file->private_data;
 110        int rc;
 111
 112        mutex_lock(&daemon->mux);
 113        BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN));
 114        daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN;
 115        atomic_dec(&ecryptfs_num_miscdev_opens);
 116        mutex_unlock(&daemon->mux);
 117
 118        mutex_lock(&ecryptfs_daemon_hash_mux);
 119        rc = ecryptfs_exorcise_daemon(daemon);
 120        mutex_unlock(&ecryptfs_daemon_hash_mux);
 121        if (rc) {
 122                printk(KERN_CRIT "%s: Fatal error whilst attempting to "
 123                       "shut down daemon; rc = [%d]. Please report this "
 124                       "bug.\n", __func__, rc);
 125                BUG();
 126        }
 127        return rc;
 128}
 129
 130/**
 131 * ecryptfs_send_miscdev
 132 * @data: Data to send to daemon; may be NULL
 133 * @data_size: Amount of data to send to daemon
 134 * @msg_ctx: Message context, which is used to handle the reply. If
 135 *           this is NULL, then we do not expect a reply.
 136 * @msg_type: Type of message
 137 * @msg_flags: Flags for message
 138 * @daemon: eCryptfs daemon object
 139 *
 140 * Add msg_ctx to queue and then, if it exists, notify the blocked
 141 * miscdevess about the data being available. Must be called with
 142 * ecryptfs_daemon_hash_mux held.
 143 *
 144 * Returns zero on success; non-zero otherwise
 145 */
 146int ecryptfs_send_miscdev(char *data, size_t data_size,
 147                          struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
 148                          u16 msg_flags, struct ecryptfs_daemon *daemon)
 149{
 150        struct ecryptfs_message *msg;
 151
 152        msg = kmalloc((sizeof(*msg) + data_size), GFP_KERNEL);
 153        if (!msg)
 154                return -ENOMEM;
 155
 156        mutex_lock(&msg_ctx->mux);
 157        msg_ctx->msg = msg;
 158        msg_ctx->msg->index = msg_ctx->index;
 159        msg_ctx->msg->data_len = data_size;
 160        msg_ctx->type = msg_type;
 161        memcpy(msg_ctx->msg->data, data, data_size);
 162        msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size);
 163        list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue);
 164        mutex_unlock(&msg_ctx->mux);
 165
 166        mutex_lock(&daemon->mux);
 167        daemon->num_queued_msg_ctx++;
 168        wake_up_interruptible(&daemon->wait);
 169        mutex_unlock(&daemon->mux);
 170
 171        return 0;
 172}
 173
 174/*
 175 * miscdevfs packet format:
 176 *  Octet 0: Type
 177 *  Octets 1-4: network byte order msg_ctx->counter
 178 *  Octets 5-N0: Size of struct ecryptfs_message to follow
 179 *  Octets N0-N1: struct ecryptfs_message (including data)
 180 *
 181 *  Octets 5-N1 not written if the packet type does not include a message
 182 */
 183#define PKT_TYPE_SIZE           1
 184#define PKT_CTR_SIZE            4
 185#define MIN_NON_MSG_PKT_SIZE    (PKT_TYPE_SIZE + PKT_CTR_SIZE)
 186#define MIN_MSG_PKT_SIZE        (PKT_TYPE_SIZE + PKT_CTR_SIZE \
 187                                 + ECRYPTFS_MIN_PKT_LEN_SIZE)
 188/* 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES comes from tag 65 packet format */
 189#define MAX_MSG_PKT_SIZE        (PKT_TYPE_SIZE + PKT_CTR_SIZE \
 190                                 + ECRYPTFS_MAX_PKT_LEN_SIZE \
 191                                 + sizeof(struct ecryptfs_message) \
 192                                 + 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)
 193#define PKT_TYPE_OFFSET         0
 194#define PKT_CTR_OFFSET          PKT_TYPE_SIZE
 195#define PKT_LEN_OFFSET          (PKT_TYPE_SIZE + PKT_CTR_SIZE)
 196
 197/**
 198 * ecryptfs_miscdev_read - format and send message from queue
 199 * @file: miscdevfs handle
 200 * @buf: User buffer into which to copy the next message on the daemon queue
 201 * @count: Amount of space available in @buf
 202 * @ppos: Offset in file (ignored)
 203 *
 204 * Pulls the most recent message from the daemon queue, formats it for
 205 * being sent via a miscdevfs handle, and copies it into @buf
 206 *
 207 * Returns the number of bytes copied into the user buffer
 208 */
 209static ssize_t
 210ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
 211                      loff_t *ppos)
 212{
 213        struct ecryptfs_daemon *daemon = file->private_data;
 214        struct ecryptfs_msg_ctx *msg_ctx;
 215        size_t packet_length_size;
 216        char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE];
 217        size_t i;
 218        size_t total_length;
 219        int rc;
 220
 221        mutex_lock(&daemon->mux);
 222        if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
 223                rc = 0;
 224                printk(KERN_WARNING "%s: Attempt to read from zombified "
 225                       "daemon\n", __func__);
 226                goto out_unlock_daemon;
 227        }
 228        if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) {
 229                rc = 0;
 230                goto out_unlock_daemon;
 231        }
 232        /* This daemon will not go away so long as this flag is set */
 233        daemon->flags |= ECRYPTFS_DAEMON_IN_READ;
 234check_list:
 235        if (list_empty(&daemon->msg_ctx_out_queue)) {
 236                mutex_unlock(&daemon->mux);
 237                rc = wait_event_interruptible(
 238                        daemon->wait, !list_empty(&daemon->msg_ctx_out_queue));
 239                mutex_lock(&daemon->mux);
 240                if (rc < 0) {
 241                        rc = 0;
 242                        goto out_unlock_daemon;
 243                }
 244        }
 245        if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
 246                rc = 0;
 247                goto out_unlock_daemon;
 248        }
 249        if (list_empty(&daemon->msg_ctx_out_queue)) {
 250                /* Something else jumped in since the
 251                 * wait_event_interruptable() and removed the
 252                 * message from the queue; try again */
 253                goto check_list;
 254        }
 255        msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue,
 256                                   struct ecryptfs_msg_ctx, daemon_out_list);
 257        BUG_ON(!msg_ctx);
 258        mutex_lock(&msg_ctx->mux);
 259        if (msg_ctx->msg) {
 260                rc = ecryptfs_write_packet_length(packet_length,
 261                                                  msg_ctx->msg_size,
 262                                                  &packet_length_size);
 263                if (rc) {
 264                        rc = 0;
 265                        printk(KERN_WARNING "%s: Error writing packet length; "
 266                               "rc = [%d]\n", __func__, rc);
 267                        goto out_unlock_msg_ctx;
 268                }
 269        } else {
 270                packet_length_size = 0;
 271                msg_ctx->msg_size = 0;
 272        }
 273        total_length = (PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_length_size
 274                        + msg_ctx->msg_size);
 275        if (count < total_length) {
 276                rc = 0;
 277                printk(KERN_WARNING "%s: Only given user buffer of "
 278                       "size [%zd], but we need [%zd] to read the "
 279                       "pending message\n", __func__, count, total_length);
 280                goto out_unlock_msg_ctx;
 281        }
 282        rc = -EFAULT;
 283        if (put_user(msg_ctx->type, buf))
 284                goto out_unlock_msg_ctx;
 285        if (put_user(cpu_to_be32(msg_ctx->counter),
 286                     (__be32 __user *)(&buf[PKT_CTR_OFFSET])))
 287                goto out_unlock_msg_ctx;
 288        i = PKT_TYPE_SIZE + PKT_CTR_SIZE;
 289        if (msg_ctx->msg) {
 290                if (copy_to_user(&buf[i], packet_length, packet_length_size))
 291                        goto out_unlock_msg_ctx;
 292                i += packet_length_size;
 293                if (copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size))
 294                        goto out_unlock_msg_ctx;
 295                i += msg_ctx->msg_size;
 296        }
 297        rc = i;
 298        list_del(&msg_ctx->daemon_out_list);
 299        kfree(msg_ctx->msg);
 300        msg_ctx->msg = NULL;
 301        /* We do not expect a reply from the userspace daemon for any
 302         * message type other than ECRYPTFS_MSG_REQUEST */
 303        if (msg_ctx->type != ECRYPTFS_MSG_REQUEST)
 304                ecryptfs_msg_ctx_alloc_to_free(msg_ctx);
 305out_unlock_msg_ctx:
 306        mutex_unlock(&msg_ctx->mux);
 307out_unlock_daemon:
 308        daemon->flags &= ~ECRYPTFS_DAEMON_IN_READ;
 309        mutex_unlock(&daemon->mux);
 310        return rc;
 311}
 312
 313/**
 314 * ecryptfs_miscdev_response - miscdevess response to message previously sent to daemon
 315 * @data: Bytes comprising struct ecryptfs_message
 316 * @data_size: sizeof(struct ecryptfs_message) + data len
 317 * @seq: Sequence number for miscdev response packet
 318 *
 319 * Returns zero on success; non-zero otherwise
 320 */
 321static int ecryptfs_miscdev_response(struct ecryptfs_daemon *daemon, char *data,
 322                                     size_t data_size, u32 seq)
 323{
 324        struct ecryptfs_message *msg = (struct ecryptfs_message *)data;
 325        int rc;
 326
 327        if ((sizeof(*msg) + msg->data_len) != data_size) {
 328                printk(KERN_WARNING "%s: (sizeof(*msg) + msg->data_len) = "
 329                       "[%zd]; data_size = [%zd]. Invalid packet.\n", __func__,
 330                       (sizeof(*msg) + msg->data_len), data_size);
 331                rc = -EINVAL;
 332                goto out;
 333        }
 334        rc = ecryptfs_process_response(daemon, msg, seq);
 335        if (rc)
 336                printk(KERN_ERR
 337                       "Error processing response message; rc = [%d]\n", rc);
 338out:
 339        return rc;
 340}
 341
 342/**
 343 * ecryptfs_miscdev_write - handle write to daemon miscdev handle
 344 * @file: File for misc dev handle
 345 * @buf: Buffer containing user data
 346 * @count: Amount of data in @buf
 347 * @ppos: Pointer to offset in file (ignored)
 348 *
 349 * Returns the number of bytes read from @buf
 350 */
 351static ssize_t
 352ecryptfs_miscdev_write(struct file *file, const char __user *buf,
 353                       size_t count, loff_t *ppos)
 354{
 355        __be32 counter_nbo;
 356        u32 seq;
 357        size_t packet_size, packet_size_length;
 358        char *data;
 359        unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE];
 360        ssize_t rc;
 361
 362        if (count == 0) {
 363                return 0;
 364        } else if (count == MIN_NON_MSG_PKT_SIZE) {
 365                /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */
 366                goto memdup;
 367        } else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) {
 368                printk(KERN_WARNING "%s: Acceptable packet size range is "
 369                       "[%d-%zu], but amount of data written is [%zu].\n",
 370                       __func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count);
 371                return -EINVAL;
 372        }
 373
 374        if (copy_from_user(packet_size_peek, &buf[PKT_LEN_OFFSET],
 375                           sizeof(packet_size_peek))) {
 376                printk(KERN_WARNING "%s: Error while inspecting packet size\n",
 377                       __func__);
 378                return -EFAULT;
 379        }
 380
 381        rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size,
 382                                          &packet_size_length);
 383        if (rc) {
 384                printk(KERN_WARNING "%s: Error parsing packet length; "
 385                       "rc = [%zd]\n", __func__, rc);
 386                return rc;
 387        }
 388
 389        if ((PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_size_length + packet_size)
 390            != count) {
 391                printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__,
 392                       packet_size);
 393                return -EINVAL;
 394        }
 395
 396memdup:
 397        data = memdup_user(buf, count);
 398        if (IS_ERR(data)) {
 399                printk(KERN_ERR "%s: memdup_user returned error [%ld]\n",
 400                       __func__, PTR_ERR(data));
 401                return PTR_ERR(data);
 402        }
 403        switch (data[PKT_TYPE_OFFSET]) {
 404        case ECRYPTFS_MSG_RESPONSE:
 405                if (count < (MIN_MSG_PKT_SIZE
 406                             + sizeof(struct ecryptfs_message))) {
 407                        printk(KERN_WARNING "%s: Minimum acceptable packet "
 408                               "size is [%zd], but amount of data written is "
 409                               "only [%zd]. Discarding response packet.\n",
 410                               __func__,
 411                               (MIN_MSG_PKT_SIZE
 412                                + sizeof(struct ecryptfs_message)), count);
 413                        rc = -EINVAL;
 414                        goto out_free;
 415                }
 416                memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE);
 417                seq = be32_to_cpu(counter_nbo);
 418                rc = ecryptfs_miscdev_response(file->private_data,
 419                                &data[PKT_LEN_OFFSET + packet_size_length],
 420                                packet_size, seq);
 421                if (rc) {
 422                        printk(KERN_WARNING "%s: Failed to deliver miscdev "
 423                               "response to requesting operation; rc = [%zd]\n",
 424                               __func__, rc);
 425                        goto out_free;
 426                }
 427                break;
 428        case ECRYPTFS_MSG_HELO:
 429        case ECRYPTFS_MSG_QUIT:
 430                break;
 431        default:
 432                ecryptfs_printk(KERN_WARNING, "Dropping miscdev "
 433                                "message of unrecognized type [%d]\n",
 434                                data[0]);
 435                rc = -EINVAL;
 436                goto out_free;
 437        }
 438        rc = count;
 439out_free:
 440        kfree(data);
 441        return rc;
 442}
 443
 444
 445static const struct file_operations ecryptfs_miscdev_fops = {
 446        .owner   = THIS_MODULE,
 447        .open    = ecryptfs_miscdev_open,
 448        .poll    = ecryptfs_miscdev_poll,
 449        .read    = ecryptfs_miscdev_read,
 450        .write   = ecryptfs_miscdev_write,
 451        .release = ecryptfs_miscdev_release,
 452        .llseek  = noop_llseek,
 453};
 454
 455static struct miscdevice ecryptfs_miscdev = {
 456        .minor = MISC_DYNAMIC_MINOR,
 457        .name  = "ecryptfs",
 458        .fops  = &ecryptfs_miscdev_fops
 459};
 460
 461/**
 462 * ecryptfs_init_ecryptfs_miscdev
 463 *
 464 * Messages sent to the userspace daemon from the kernel are placed on
 465 * a queue associated with the daemon. The next read against the
 466 * miscdev handle by that daemon will return the oldest message placed
 467 * on the message queue for the daemon.
 468 *
 469 * Returns zero on success; non-zero otherwise
 470 */
 471int __init ecryptfs_init_ecryptfs_miscdev(void)
 472{
 473        int rc;
 474
 475        atomic_set(&ecryptfs_num_miscdev_opens, 0);
 476        rc = misc_register(&ecryptfs_miscdev);
 477        if (rc)
 478                printk(KERN_ERR "%s: Failed to register miscellaneous device "
 479                       "for communications with userspace daemons; rc = [%d]\n",
 480                       __func__, rc);
 481        return rc;
 482}
 483
 484/**
 485 * ecryptfs_destroy_ecryptfs_miscdev
 486 *
 487 * All of the daemons must be exorcised prior to calling this
 488 * function.
 489 */
 490void ecryptfs_destroy_ecryptfs_miscdev(void)
 491{
 492        BUG_ON(atomic_read(&ecryptfs_num_miscdev_opens) != 0);
 493        misc_deregister(&ecryptfs_miscdev);
 494}
 495