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