1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /**
3*4882a593Smuzhiyun * eCryptfs: Linux filesystem encryption layer
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2004-2008 International Business Machines Corp.
6*4882a593Smuzhiyun * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
7*4882a593Smuzhiyun * Tyler Hicks <code@tyhicks.com>
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun #include <linux/sched.h>
10*4882a593Smuzhiyun #include <linux/slab.h>
11*4882a593Smuzhiyun #include <linux/user_namespace.h>
12*4882a593Smuzhiyun #include <linux/nsproxy.h>
13*4882a593Smuzhiyun #include "ecryptfs_kernel.h"
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun static LIST_HEAD(ecryptfs_msg_ctx_free_list);
16*4882a593Smuzhiyun static LIST_HEAD(ecryptfs_msg_ctx_alloc_list);
17*4882a593Smuzhiyun static struct mutex ecryptfs_msg_ctx_lists_mux;
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun static struct hlist_head *ecryptfs_daemon_hash;
20*4882a593Smuzhiyun struct mutex ecryptfs_daemon_hash_mux;
21*4882a593Smuzhiyun static int ecryptfs_hash_bits;
22*4882a593Smuzhiyun #define ecryptfs_current_euid_hash(uid) \
23*4882a593Smuzhiyun hash_long((unsigned long)from_kuid(&init_user_ns, current_euid()), ecryptfs_hash_bits)
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun static u32 ecryptfs_msg_counter;
26*4882a593Smuzhiyun static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr;
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun /**
29*4882a593Smuzhiyun * ecryptfs_acquire_free_msg_ctx
30*4882a593Smuzhiyun * @msg_ctx: The context that was acquired from the free list
31*4882a593Smuzhiyun *
32*4882a593Smuzhiyun * Acquires a context element from the free list and locks the mutex
33*4882a593Smuzhiyun * on the context. Sets the msg_ctx task to current. Returns zero on
34*4882a593Smuzhiyun * success; non-zero on error or upon failure to acquire a free
35*4882a593Smuzhiyun * context element. Must be called with ecryptfs_msg_ctx_lists_mux
36*4882a593Smuzhiyun * held.
37*4882a593Smuzhiyun */
ecryptfs_acquire_free_msg_ctx(struct ecryptfs_msg_ctx ** msg_ctx)38*4882a593Smuzhiyun static int ecryptfs_acquire_free_msg_ctx(struct ecryptfs_msg_ctx **msg_ctx)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun struct list_head *p;
41*4882a593Smuzhiyun int rc;
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun if (list_empty(&ecryptfs_msg_ctx_free_list)) {
44*4882a593Smuzhiyun printk(KERN_WARNING "%s: The eCryptfs free "
45*4882a593Smuzhiyun "context list is empty. It may be helpful to "
46*4882a593Smuzhiyun "specify the ecryptfs_message_buf_len "
47*4882a593Smuzhiyun "parameter to be greater than the current "
48*4882a593Smuzhiyun "value of [%d]\n", __func__, ecryptfs_message_buf_len);
49*4882a593Smuzhiyun rc = -ENOMEM;
50*4882a593Smuzhiyun goto out;
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun list_for_each(p, &ecryptfs_msg_ctx_free_list) {
53*4882a593Smuzhiyun *msg_ctx = list_entry(p, struct ecryptfs_msg_ctx, node);
54*4882a593Smuzhiyun if (mutex_trylock(&(*msg_ctx)->mux)) {
55*4882a593Smuzhiyun (*msg_ctx)->task = current;
56*4882a593Smuzhiyun rc = 0;
57*4882a593Smuzhiyun goto out;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun rc = -ENOMEM;
61*4882a593Smuzhiyun out:
62*4882a593Smuzhiyun return rc;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /**
66*4882a593Smuzhiyun * ecryptfs_msg_ctx_free_to_alloc
67*4882a593Smuzhiyun * @msg_ctx: The context to move from the free list to the alloc list
68*4882a593Smuzhiyun *
69*4882a593Smuzhiyun * Must be called with ecryptfs_msg_ctx_lists_mux held.
70*4882a593Smuzhiyun */
ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx * msg_ctx)71*4882a593Smuzhiyun static void ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx *msg_ctx)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun list_move(&msg_ctx->node, &ecryptfs_msg_ctx_alloc_list);
74*4882a593Smuzhiyun msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_PENDING;
75*4882a593Smuzhiyun msg_ctx->counter = ++ecryptfs_msg_counter;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun /**
79*4882a593Smuzhiyun * ecryptfs_msg_ctx_alloc_to_free
80*4882a593Smuzhiyun * @msg_ctx: The context to move from the alloc list to the free list
81*4882a593Smuzhiyun *
82*4882a593Smuzhiyun * Must be called with ecryptfs_msg_ctx_lists_mux held.
83*4882a593Smuzhiyun */
ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx * msg_ctx)84*4882a593Smuzhiyun void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun list_move(&(msg_ctx->node), &ecryptfs_msg_ctx_free_list);
87*4882a593Smuzhiyun kfree(msg_ctx->msg);
88*4882a593Smuzhiyun msg_ctx->msg = NULL;
89*4882a593Smuzhiyun msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_FREE;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun /**
93*4882a593Smuzhiyun * ecryptfs_find_daemon_by_euid
94*4882a593Smuzhiyun * @daemon: If return value is zero, points to the desired daemon pointer
95*4882a593Smuzhiyun *
96*4882a593Smuzhiyun * Must be called with ecryptfs_daemon_hash_mux held.
97*4882a593Smuzhiyun *
98*4882a593Smuzhiyun * Search the hash list for the current effective user id.
99*4882a593Smuzhiyun *
100*4882a593Smuzhiyun * Returns zero if the user id exists in the list; non-zero otherwise.
101*4882a593Smuzhiyun */
ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon ** daemon)102*4882a593Smuzhiyun int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun int rc;
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun hlist_for_each_entry(*daemon,
107*4882a593Smuzhiyun &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()],
108*4882a593Smuzhiyun euid_chain) {
109*4882a593Smuzhiyun if (uid_eq((*daemon)->file->f_cred->euid, current_euid())) {
110*4882a593Smuzhiyun rc = 0;
111*4882a593Smuzhiyun goto out;
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun rc = -EINVAL;
115*4882a593Smuzhiyun out:
116*4882a593Smuzhiyun return rc;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun /**
120*4882a593Smuzhiyun * ecryptfs_spawn_daemon - Create and initialize a new daemon struct
121*4882a593Smuzhiyun * @daemon: Pointer to set to newly allocated daemon struct
122*4882a593Smuzhiyun * @file: File used when opening /dev/ecryptfs
123*4882a593Smuzhiyun *
124*4882a593Smuzhiyun * Must be called ceremoniously while in possession of
125*4882a593Smuzhiyun * ecryptfs_sacred_daemon_hash_mux
126*4882a593Smuzhiyun *
127*4882a593Smuzhiyun * Returns zero on success; non-zero otherwise
128*4882a593Smuzhiyun */
129*4882a593Smuzhiyun int
ecryptfs_spawn_daemon(struct ecryptfs_daemon ** daemon,struct file * file)130*4882a593Smuzhiyun ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun int rc = 0;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun (*daemon) = kzalloc(sizeof(**daemon), GFP_KERNEL);
135*4882a593Smuzhiyun if (!(*daemon)) {
136*4882a593Smuzhiyun rc = -ENOMEM;
137*4882a593Smuzhiyun goto out;
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun (*daemon)->file = file;
140*4882a593Smuzhiyun mutex_init(&(*daemon)->mux);
141*4882a593Smuzhiyun INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue);
142*4882a593Smuzhiyun init_waitqueue_head(&(*daemon)->wait);
143*4882a593Smuzhiyun (*daemon)->num_queued_msg_ctx = 0;
144*4882a593Smuzhiyun hlist_add_head(&(*daemon)->euid_chain,
145*4882a593Smuzhiyun &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()]);
146*4882a593Smuzhiyun out:
147*4882a593Smuzhiyun return rc;
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun /**
151*4882a593Smuzhiyun * ecryptfs_exorcise_daemon - Destroy the daemon struct
152*4882a593Smuzhiyun *
153*4882a593Smuzhiyun * Must be called ceremoniously while in possession of
154*4882a593Smuzhiyun * ecryptfs_daemon_hash_mux and the daemon's own mux.
155*4882a593Smuzhiyun */
ecryptfs_exorcise_daemon(struct ecryptfs_daemon * daemon)156*4882a593Smuzhiyun int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun struct ecryptfs_msg_ctx *msg_ctx, *msg_ctx_tmp;
159*4882a593Smuzhiyun int rc = 0;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun mutex_lock(&daemon->mux);
162*4882a593Smuzhiyun if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ)
163*4882a593Smuzhiyun || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) {
164*4882a593Smuzhiyun rc = -EBUSY;
165*4882a593Smuzhiyun mutex_unlock(&daemon->mux);
166*4882a593Smuzhiyun goto out;
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun list_for_each_entry_safe(msg_ctx, msg_ctx_tmp,
169*4882a593Smuzhiyun &daemon->msg_ctx_out_queue, daemon_out_list) {
170*4882a593Smuzhiyun list_del(&msg_ctx->daemon_out_list);
171*4882a593Smuzhiyun daemon->num_queued_msg_ctx--;
172*4882a593Smuzhiyun printk(KERN_WARNING "%s: Warning: dropping message that is in "
173*4882a593Smuzhiyun "the out queue of a dying daemon\n", __func__);
174*4882a593Smuzhiyun ecryptfs_msg_ctx_alloc_to_free(msg_ctx);
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun hlist_del(&daemon->euid_chain);
177*4882a593Smuzhiyun mutex_unlock(&daemon->mux);
178*4882a593Smuzhiyun kfree_sensitive(daemon);
179*4882a593Smuzhiyun out:
180*4882a593Smuzhiyun return rc;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun /**
184*4882a593Smuzhiyun * ecryptfs_process_reponse
185*4882a593Smuzhiyun * @msg: The ecryptfs message received; the caller should sanity check
186*4882a593Smuzhiyun * msg->data_len and free the memory
187*4882a593Smuzhiyun * @seq: The sequence number of the message; must match the sequence
188*4882a593Smuzhiyun * number for the existing message context waiting for this
189*4882a593Smuzhiyun * response
190*4882a593Smuzhiyun *
191*4882a593Smuzhiyun * Processes a response message after sending an operation request to
192*4882a593Smuzhiyun * userspace. Some other process is awaiting this response. Before
193*4882a593Smuzhiyun * sending out its first communications, the other process allocated a
194*4882a593Smuzhiyun * msg_ctx from the ecryptfs_msg_ctx_arr at a particular index. The
195*4882a593Smuzhiyun * response message contains this index so that we can copy over the
196*4882a593Smuzhiyun * response message into the msg_ctx that the process holds a
197*4882a593Smuzhiyun * reference to. The other process is going to wake up, check to see
198*4882a593Smuzhiyun * that msg_ctx->state == ECRYPTFS_MSG_CTX_STATE_DONE, and then
199*4882a593Smuzhiyun * proceed to read off and process the response message. Returns zero
200*4882a593Smuzhiyun * upon delivery to desired context element; non-zero upon delivery
201*4882a593Smuzhiyun * failure or error.
202*4882a593Smuzhiyun *
203*4882a593Smuzhiyun * Returns zero on success; non-zero otherwise
204*4882a593Smuzhiyun */
ecryptfs_process_response(struct ecryptfs_daemon * daemon,struct ecryptfs_message * msg,u32 seq)205*4882a593Smuzhiyun int ecryptfs_process_response(struct ecryptfs_daemon *daemon,
206*4882a593Smuzhiyun struct ecryptfs_message *msg, u32 seq)
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun struct ecryptfs_msg_ctx *msg_ctx;
209*4882a593Smuzhiyun size_t msg_size;
210*4882a593Smuzhiyun int rc;
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun if (msg->index >= ecryptfs_message_buf_len) {
213*4882a593Smuzhiyun rc = -EINVAL;
214*4882a593Smuzhiyun printk(KERN_ERR "%s: Attempt to reference "
215*4882a593Smuzhiyun "context buffer at index [%d]; maximum "
216*4882a593Smuzhiyun "allowable is [%d]\n", __func__, msg->index,
217*4882a593Smuzhiyun (ecryptfs_message_buf_len - 1));
218*4882a593Smuzhiyun goto out;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun msg_ctx = &ecryptfs_msg_ctx_arr[msg->index];
221*4882a593Smuzhiyun mutex_lock(&msg_ctx->mux);
222*4882a593Smuzhiyun if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) {
223*4882a593Smuzhiyun rc = -EINVAL;
224*4882a593Smuzhiyun printk(KERN_WARNING "%s: Desired context element is not "
225*4882a593Smuzhiyun "pending a response\n", __func__);
226*4882a593Smuzhiyun goto unlock;
227*4882a593Smuzhiyun } else if (msg_ctx->counter != seq) {
228*4882a593Smuzhiyun rc = -EINVAL;
229*4882a593Smuzhiyun printk(KERN_WARNING "%s: Invalid message sequence; "
230*4882a593Smuzhiyun "expected [%d]; received [%d]\n", __func__,
231*4882a593Smuzhiyun msg_ctx->counter, seq);
232*4882a593Smuzhiyun goto unlock;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun msg_size = (sizeof(*msg) + msg->data_len);
235*4882a593Smuzhiyun msg_ctx->msg = kmemdup(msg, msg_size, GFP_KERNEL);
236*4882a593Smuzhiyun if (!msg_ctx->msg) {
237*4882a593Smuzhiyun rc = -ENOMEM;
238*4882a593Smuzhiyun goto unlock;
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE;
241*4882a593Smuzhiyun wake_up_process(msg_ctx->task);
242*4882a593Smuzhiyun rc = 0;
243*4882a593Smuzhiyun unlock:
244*4882a593Smuzhiyun mutex_unlock(&msg_ctx->mux);
245*4882a593Smuzhiyun out:
246*4882a593Smuzhiyun return rc;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun /**
250*4882a593Smuzhiyun * ecryptfs_send_message_locked
251*4882a593Smuzhiyun * @data: The data to send
252*4882a593Smuzhiyun * @data_len: The length of data
253*4882a593Smuzhiyun * @msg_ctx: The message context allocated for the send
254*4882a593Smuzhiyun *
255*4882a593Smuzhiyun * Must be called with ecryptfs_daemon_hash_mux held.
256*4882a593Smuzhiyun *
257*4882a593Smuzhiyun * Returns zero on success; non-zero otherwise
258*4882a593Smuzhiyun */
259*4882a593Smuzhiyun static int
ecryptfs_send_message_locked(char * data,int data_len,u8 msg_type,struct ecryptfs_msg_ctx ** msg_ctx)260*4882a593Smuzhiyun ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
261*4882a593Smuzhiyun struct ecryptfs_msg_ctx **msg_ctx)
262*4882a593Smuzhiyun {
263*4882a593Smuzhiyun struct ecryptfs_daemon *daemon;
264*4882a593Smuzhiyun int rc;
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun rc = ecryptfs_find_daemon_by_euid(&daemon);
267*4882a593Smuzhiyun if (rc) {
268*4882a593Smuzhiyun rc = -ENOTCONN;
269*4882a593Smuzhiyun goto out;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun mutex_lock(&ecryptfs_msg_ctx_lists_mux);
272*4882a593Smuzhiyun rc = ecryptfs_acquire_free_msg_ctx(msg_ctx);
273*4882a593Smuzhiyun if (rc) {
274*4882a593Smuzhiyun mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
275*4882a593Smuzhiyun printk(KERN_WARNING "%s: Could not claim a free "
276*4882a593Smuzhiyun "context element\n", __func__);
277*4882a593Smuzhiyun goto out;
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun ecryptfs_msg_ctx_free_to_alloc(*msg_ctx);
280*4882a593Smuzhiyun mutex_unlock(&(*msg_ctx)->mux);
281*4882a593Smuzhiyun mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
282*4882a593Smuzhiyun rc = ecryptfs_send_miscdev(data, data_len, *msg_ctx, msg_type, 0,
283*4882a593Smuzhiyun daemon);
284*4882a593Smuzhiyun if (rc)
285*4882a593Smuzhiyun printk(KERN_ERR "%s: Error attempting to send message to "
286*4882a593Smuzhiyun "userspace daemon; rc = [%d]\n", __func__, rc);
287*4882a593Smuzhiyun out:
288*4882a593Smuzhiyun return rc;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun /**
292*4882a593Smuzhiyun * ecryptfs_send_message
293*4882a593Smuzhiyun * @data: The data to send
294*4882a593Smuzhiyun * @data_len: The length of data
295*4882a593Smuzhiyun * @msg_ctx: The message context allocated for the send
296*4882a593Smuzhiyun *
297*4882a593Smuzhiyun * Grabs ecryptfs_daemon_hash_mux.
298*4882a593Smuzhiyun *
299*4882a593Smuzhiyun * Returns zero on success; non-zero otherwise
300*4882a593Smuzhiyun */
ecryptfs_send_message(char * data,int data_len,struct ecryptfs_msg_ctx ** msg_ctx)301*4882a593Smuzhiyun int ecryptfs_send_message(char *data, int data_len,
302*4882a593Smuzhiyun struct ecryptfs_msg_ctx **msg_ctx)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun int rc;
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun mutex_lock(&ecryptfs_daemon_hash_mux);
307*4882a593Smuzhiyun rc = ecryptfs_send_message_locked(data, data_len, ECRYPTFS_MSG_REQUEST,
308*4882a593Smuzhiyun msg_ctx);
309*4882a593Smuzhiyun mutex_unlock(&ecryptfs_daemon_hash_mux);
310*4882a593Smuzhiyun return rc;
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun /**
314*4882a593Smuzhiyun * ecryptfs_wait_for_response
315*4882a593Smuzhiyun * @msg_ctx: The context that was assigned when sending a message
316*4882a593Smuzhiyun * @msg: The incoming message from userspace; not set if rc != 0
317*4882a593Smuzhiyun *
318*4882a593Smuzhiyun * Sleeps until awaken by ecryptfs_receive_message or until the amount
319*4882a593Smuzhiyun * of time exceeds ecryptfs_message_wait_timeout. If zero is
320*4882a593Smuzhiyun * returned, msg will point to a valid message from userspace; a
321*4882a593Smuzhiyun * non-zero value is returned upon failure to receive a message or an
322*4882a593Smuzhiyun * error occurs. Callee must free @msg on success.
323*4882a593Smuzhiyun */
ecryptfs_wait_for_response(struct ecryptfs_msg_ctx * msg_ctx,struct ecryptfs_message ** msg)324*4882a593Smuzhiyun int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx,
325*4882a593Smuzhiyun struct ecryptfs_message **msg)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun signed long timeout = ecryptfs_message_wait_timeout * HZ;
328*4882a593Smuzhiyun int rc = 0;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun sleep:
331*4882a593Smuzhiyun timeout = schedule_timeout_interruptible(timeout);
332*4882a593Smuzhiyun mutex_lock(&ecryptfs_msg_ctx_lists_mux);
333*4882a593Smuzhiyun mutex_lock(&msg_ctx->mux);
334*4882a593Smuzhiyun if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_DONE) {
335*4882a593Smuzhiyun if (timeout) {
336*4882a593Smuzhiyun mutex_unlock(&msg_ctx->mux);
337*4882a593Smuzhiyun mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
338*4882a593Smuzhiyun goto sleep;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun rc = -ENOMSG;
341*4882a593Smuzhiyun } else {
342*4882a593Smuzhiyun *msg = msg_ctx->msg;
343*4882a593Smuzhiyun msg_ctx->msg = NULL;
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun ecryptfs_msg_ctx_alloc_to_free(msg_ctx);
346*4882a593Smuzhiyun mutex_unlock(&msg_ctx->mux);
347*4882a593Smuzhiyun mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
348*4882a593Smuzhiyun return rc;
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun
ecryptfs_init_messaging(void)351*4882a593Smuzhiyun int __init ecryptfs_init_messaging(void)
352*4882a593Smuzhiyun {
353*4882a593Smuzhiyun int i;
354*4882a593Smuzhiyun int rc = 0;
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun if (ecryptfs_number_of_users > ECRYPTFS_MAX_NUM_USERS) {
357*4882a593Smuzhiyun ecryptfs_number_of_users = ECRYPTFS_MAX_NUM_USERS;
358*4882a593Smuzhiyun printk(KERN_WARNING "%s: Specified number of users is "
359*4882a593Smuzhiyun "too large, defaulting to [%d] users\n", __func__,
360*4882a593Smuzhiyun ecryptfs_number_of_users);
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun mutex_init(&ecryptfs_daemon_hash_mux);
363*4882a593Smuzhiyun mutex_lock(&ecryptfs_daemon_hash_mux);
364*4882a593Smuzhiyun ecryptfs_hash_bits = 1;
365*4882a593Smuzhiyun while (ecryptfs_number_of_users >> ecryptfs_hash_bits)
366*4882a593Smuzhiyun ecryptfs_hash_bits++;
367*4882a593Smuzhiyun ecryptfs_daemon_hash = kmalloc((sizeof(struct hlist_head)
368*4882a593Smuzhiyun * (1 << ecryptfs_hash_bits)),
369*4882a593Smuzhiyun GFP_KERNEL);
370*4882a593Smuzhiyun if (!ecryptfs_daemon_hash) {
371*4882a593Smuzhiyun rc = -ENOMEM;
372*4882a593Smuzhiyun mutex_unlock(&ecryptfs_daemon_hash_mux);
373*4882a593Smuzhiyun goto out;
374*4882a593Smuzhiyun }
375*4882a593Smuzhiyun for (i = 0; i < (1 << ecryptfs_hash_bits); i++)
376*4882a593Smuzhiyun INIT_HLIST_HEAD(&ecryptfs_daemon_hash[i]);
377*4882a593Smuzhiyun mutex_unlock(&ecryptfs_daemon_hash_mux);
378*4882a593Smuzhiyun ecryptfs_msg_ctx_arr = kmalloc((sizeof(struct ecryptfs_msg_ctx)
379*4882a593Smuzhiyun * ecryptfs_message_buf_len),
380*4882a593Smuzhiyun GFP_KERNEL);
381*4882a593Smuzhiyun if (!ecryptfs_msg_ctx_arr) {
382*4882a593Smuzhiyun kfree(ecryptfs_daemon_hash);
383*4882a593Smuzhiyun rc = -ENOMEM;
384*4882a593Smuzhiyun goto out;
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun mutex_init(&ecryptfs_msg_ctx_lists_mux);
387*4882a593Smuzhiyun mutex_lock(&ecryptfs_msg_ctx_lists_mux);
388*4882a593Smuzhiyun ecryptfs_msg_counter = 0;
389*4882a593Smuzhiyun for (i = 0; i < ecryptfs_message_buf_len; i++) {
390*4882a593Smuzhiyun INIT_LIST_HEAD(&ecryptfs_msg_ctx_arr[i].node);
391*4882a593Smuzhiyun INIT_LIST_HEAD(&ecryptfs_msg_ctx_arr[i].daemon_out_list);
392*4882a593Smuzhiyun mutex_init(&ecryptfs_msg_ctx_arr[i].mux);
393*4882a593Smuzhiyun mutex_lock(&ecryptfs_msg_ctx_arr[i].mux);
394*4882a593Smuzhiyun ecryptfs_msg_ctx_arr[i].index = i;
395*4882a593Smuzhiyun ecryptfs_msg_ctx_arr[i].state = ECRYPTFS_MSG_CTX_STATE_FREE;
396*4882a593Smuzhiyun ecryptfs_msg_ctx_arr[i].counter = 0;
397*4882a593Smuzhiyun ecryptfs_msg_ctx_arr[i].task = NULL;
398*4882a593Smuzhiyun ecryptfs_msg_ctx_arr[i].msg = NULL;
399*4882a593Smuzhiyun list_add_tail(&ecryptfs_msg_ctx_arr[i].node,
400*4882a593Smuzhiyun &ecryptfs_msg_ctx_free_list);
401*4882a593Smuzhiyun mutex_unlock(&ecryptfs_msg_ctx_arr[i].mux);
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
404*4882a593Smuzhiyun rc = ecryptfs_init_ecryptfs_miscdev();
405*4882a593Smuzhiyun if (rc)
406*4882a593Smuzhiyun ecryptfs_release_messaging();
407*4882a593Smuzhiyun out:
408*4882a593Smuzhiyun return rc;
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun
ecryptfs_release_messaging(void)411*4882a593Smuzhiyun void ecryptfs_release_messaging(void)
412*4882a593Smuzhiyun {
413*4882a593Smuzhiyun if (ecryptfs_msg_ctx_arr) {
414*4882a593Smuzhiyun int i;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun mutex_lock(&ecryptfs_msg_ctx_lists_mux);
417*4882a593Smuzhiyun for (i = 0; i < ecryptfs_message_buf_len; i++) {
418*4882a593Smuzhiyun mutex_lock(&ecryptfs_msg_ctx_arr[i].mux);
419*4882a593Smuzhiyun kfree(ecryptfs_msg_ctx_arr[i].msg);
420*4882a593Smuzhiyun mutex_unlock(&ecryptfs_msg_ctx_arr[i].mux);
421*4882a593Smuzhiyun }
422*4882a593Smuzhiyun kfree(ecryptfs_msg_ctx_arr);
423*4882a593Smuzhiyun mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun if (ecryptfs_daemon_hash) {
426*4882a593Smuzhiyun struct ecryptfs_daemon *daemon;
427*4882a593Smuzhiyun struct hlist_node *n;
428*4882a593Smuzhiyun int i;
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun mutex_lock(&ecryptfs_daemon_hash_mux);
431*4882a593Smuzhiyun for (i = 0; i < (1 << ecryptfs_hash_bits); i++) {
432*4882a593Smuzhiyun int rc;
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun hlist_for_each_entry_safe(daemon, n,
435*4882a593Smuzhiyun &ecryptfs_daemon_hash[i],
436*4882a593Smuzhiyun euid_chain) {
437*4882a593Smuzhiyun rc = ecryptfs_exorcise_daemon(daemon);
438*4882a593Smuzhiyun if (rc)
439*4882a593Smuzhiyun printk(KERN_ERR "%s: Error whilst "
440*4882a593Smuzhiyun "attempting to destroy daemon; "
441*4882a593Smuzhiyun "rc = [%d]. Dazed and confused, "
442*4882a593Smuzhiyun "but trying to continue.\n",
443*4882a593Smuzhiyun __func__, rc);
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun kfree(ecryptfs_daemon_hash);
447*4882a593Smuzhiyun mutex_unlock(&ecryptfs_daemon_hash_mux);
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun ecryptfs_destroy_ecryptfs_miscdev();
450*4882a593Smuzhiyun return;
451*4882a593Smuzhiyun }
452