aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/messaging.c
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2008-04-29 03:59:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:07 -0400
commit6a3fd92e73fffd9e583650c56ad9558afe51dc5c (patch)
treed65917432ffd0e6223dab3500819205433de22bd /fs/ecryptfs/messaging.c
parentf66e883eb6186bc43a79581b67aff7d1a69d0ff1 (diff)
eCryptfs: make key module subsystem respect namespaces
Make eCryptfs key module subsystem respect namespaces. Since I will be removing the netlink interface in a future patch, I just made changes to the netlink.c code so that it will not break the build. With my recent patches, the kernel module currently defaults to the device handle interface rather than the netlink interface. [akpm@linux-foundation.org: export free_user_ns()] Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ecryptfs/messaging.c')
-rw-r--r--fs/ecryptfs/messaging.c81
1 files changed, 60 insertions, 21 deletions
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c
index c6038bd60897..1b5c20058acb 100644
--- a/fs/ecryptfs/messaging.c
+++ b/fs/ecryptfs/messaging.c
@@ -20,6 +20,8 @@
20 * 02111-1307, USA. 20 * 02111-1307, USA.
21 */ 21 */
22#include <linux/sched.h> 22#include <linux/sched.h>
23#include <linux/user_namespace.h>
24#include <linux/nsproxy.h>
23#include "ecryptfs_kernel.h" 25#include "ecryptfs_kernel.h"
24 26
25static LIST_HEAD(ecryptfs_msg_ctx_free_list); 27static LIST_HEAD(ecryptfs_msg_ctx_free_list);
@@ -103,6 +105,7 @@ void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx)
103/** 105/**
104 * ecryptfs_find_daemon_by_euid 106 * ecryptfs_find_daemon_by_euid
105 * @euid: The effective user id which maps to the desired daemon id 107 * @euid: The effective user id which maps to the desired daemon id
108 * @user_ns: The namespace in which @euid applies
106 * @daemon: If return value is zero, points to the desired daemon pointer 109 * @daemon: If return value is zero, points to the desired daemon pointer
107 * 110 *
108 * Must be called with ecryptfs_daemon_hash_mux held. 111 * Must be called with ecryptfs_daemon_hash_mux held.
@@ -111,7 +114,8 @@ void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx)
111 * 114 *
112 * Returns zero if the user id exists in the list; non-zero otherwise. 115 * Returns zero if the user id exists in the list; non-zero otherwise.
113 */ 116 */
114int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid) 117int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid,
118 struct user_namespace *user_ns)
115{ 119{
116 struct hlist_node *elem; 120 struct hlist_node *elem;
117 int rc; 121 int rc;
@@ -119,7 +123,7 @@ int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid)
119 hlist_for_each_entry(*daemon, elem, 123 hlist_for_each_entry(*daemon, elem,
120 &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)], 124 &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)],
121 euid_chain) { 125 euid_chain) {
122 if ((*daemon)->euid == euid) { 126 if ((*daemon)->euid == euid && (*daemon)->user_ns == user_ns) {
123 rc = 0; 127 rc = 0;
124 goto out; 128 goto out;
125 } 129 }
@@ -186,6 +190,7 @@ out:
186 * ecryptfs_spawn_daemon - Create and initialize a new daemon struct 190 * ecryptfs_spawn_daemon - Create and initialize a new daemon struct
187 * @daemon: Pointer to set to newly allocated daemon struct 191 * @daemon: Pointer to set to newly allocated daemon struct
188 * @euid: Effective user id for the daemon 192 * @euid: Effective user id for the daemon
193 * @user_ns: The namespace in which @euid applies
189 * @pid: Process id for the daemon 194 * @pid: Process id for the daemon
190 * 195 *
191 * Must be called ceremoniously while in possession of 196 * Must be called ceremoniously while in possession of
@@ -194,7 +199,8 @@ out:
194 * Returns zero on success; non-zero otherwise 199 * Returns zero on success; non-zero otherwise
195 */ 200 */
196int 201int
197ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, pid_t pid) 202ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid,
203 struct user_namespace *user_ns, struct pid *pid)
198{ 204{
199 int rc = 0; 205 int rc = 0;
200 206
@@ -206,7 +212,8 @@ ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, pid_t pid)
206 goto out; 212 goto out;
207 } 213 }
208 (*daemon)->euid = euid; 214 (*daemon)->euid = euid;
209 (*daemon)->pid = pid; 215 (*daemon)->user_ns = get_user_ns(user_ns);
216 (*daemon)->pid = get_pid(pid);
210 (*daemon)->task = current; 217 (*daemon)->task = current;
211 mutex_init(&(*daemon)->mux); 218 mutex_init(&(*daemon)->mux);
212 INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); 219 INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue);
@@ -222,6 +229,7 @@ out:
222 * ecryptfs_process_helo 229 * ecryptfs_process_helo
223 * @transport: The underlying transport (netlink, etc.) 230 * @transport: The underlying transport (netlink, etc.)
224 * @euid: The user ID owner of the message 231 * @euid: The user ID owner of the message
232 * @user_ns: The namespace in which @euid applies
225 * @pid: The process ID for the userspace program that sent the 233 * @pid: The process ID for the userspace program that sent the
226 * message 234 * message
227 * 235 *
@@ -231,32 +239,33 @@ out:
231 * Returns zero after adding a new daemon to the hash list; 239 * Returns zero after adding a new daemon to the hash list;
232 * non-zero otherwise. 240 * non-zero otherwise.
233 */ 241 */
234int ecryptfs_process_helo(unsigned int transport, uid_t euid, pid_t pid) 242int ecryptfs_process_helo(unsigned int transport, uid_t euid,
243 struct user_namespace *user_ns, struct pid *pid)
235{ 244{
236 struct ecryptfs_daemon *new_daemon; 245 struct ecryptfs_daemon *new_daemon;
237 struct ecryptfs_daemon *old_daemon; 246 struct ecryptfs_daemon *old_daemon;
238 int rc; 247 int rc;
239 248
240 mutex_lock(&ecryptfs_daemon_hash_mux); 249 mutex_lock(&ecryptfs_daemon_hash_mux);
241 rc = ecryptfs_find_daemon_by_euid(&old_daemon, euid); 250 rc = ecryptfs_find_daemon_by_euid(&old_daemon, euid, user_ns);
242 if (rc != 0) { 251 if (rc != 0) {
243 printk(KERN_WARNING "Received request from user [%d] " 252 printk(KERN_WARNING "Received request from user [%d] "
244 "to register daemon [%d]; unregistering daemon " 253 "to register daemon [0x%p]; unregistering daemon "
245 "[%d]\n", euid, pid, old_daemon->pid); 254 "[0x%p]\n", euid, pid, old_daemon->pid);
246 rc = ecryptfs_send_raw_message(transport, ECRYPTFS_MSG_QUIT, 255 rc = ecryptfs_send_raw_message(transport, ECRYPTFS_MSG_QUIT,
247 old_daemon); 256 old_daemon);
248 if (rc) 257 if (rc)
249 printk(KERN_WARNING "Failed to send QUIT " 258 printk(KERN_WARNING "Failed to send QUIT "
250 "message to daemon [%d]; rc = [%d]\n", 259 "message to daemon [0x%p]; rc = [%d]\n",
251 old_daemon->pid, rc); 260 old_daemon->pid, rc);
252 hlist_del(&old_daemon->euid_chain); 261 hlist_del(&old_daemon->euid_chain);
253 kfree(old_daemon); 262 kfree(old_daemon);
254 } 263 }
255 rc = ecryptfs_spawn_daemon(&new_daemon, euid, pid); 264 rc = ecryptfs_spawn_daemon(&new_daemon, euid, user_ns, pid);
256 if (rc) 265 if (rc)
257 printk(KERN_ERR "%s: The gods are displeased with this attempt " 266 printk(KERN_ERR "%s: The gods are displeased with this attempt "
258 "to create a new daemon object for euid [%d]; pid [%d]; " 267 "to create a new daemon object for euid [%d]; pid "
259 "rc = [%d]\n", __func__, euid, pid, rc); 268 "[0x%p]; rc = [%d]\n", __func__, euid, pid, rc);
260 mutex_unlock(&ecryptfs_daemon_hash_mux); 269 mutex_unlock(&ecryptfs_daemon_hash_mux);
261 return rc; 270 return rc;
262} 271}
@@ -277,7 +286,7 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon)
277 || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { 286 || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) {
278 rc = -EBUSY; 287 rc = -EBUSY;
279 printk(KERN_WARNING "%s: Attempt to destroy daemon with pid " 288 printk(KERN_WARNING "%s: Attempt to destroy daemon with pid "
280 "[%d], but it is in the midst of a read or a poll\n", 289 "[0x%p], but it is in the midst of a read or a poll\n",
281 __func__, daemon->pid); 290 __func__, daemon->pid);
282 mutex_unlock(&daemon->mux); 291 mutex_unlock(&daemon->mux);
283 goto out; 292 goto out;
@@ -293,6 +302,10 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon)
293 hlist_del(&daemon->euid_chain); 302 hlist_del(&daemon->euid_chain);
294 if (daemon->task) 303 if (daemon->task)
295 wake_up_process(daemon->task); 304 wake_up_process(daemon->task);
305 if (daemon->pid)
306 put_pid(daemon->pid);
307 if (daemon->user_ns)
308 put_user_ns(daemon->user_ns);
296 mutex_unlock(&daemon->mux); 309 mutex_unlock(&daemon->mux);
297 memset(daemon, 0, sizeof(*daemon)); 310 memset(daemon, 0, sizeof(*daemon));
298 kfree(daemon); 311 kfree(daemon);
@@ -303,6 +316,7 @@ out:
303/** 316/**
304 * ecryptfs_process_quit 317 * ecryptfs_process_quit
305 * @euid: The user ID owner of the message 318 * @euid: The user ID owner of the message
319 * @user_ns: The namespace in which @euid applies
306 * @pid: The process ID for the userspace program that sent the 320 * @pid: The process ID for the userspace program that sent the
307 * message 321 * message
308 * 322 *
@@ -310,17 +324,18 @@ out:
310 * it is the registered that is requesting the deletion. Returns zero 324 * it is the registered that is requesting the deletion. Returns zero
311 * after deleting the desired daemon; non-zero otherwise. 325 * after deleting the desired daemon; non-zero otherwise.
312 */ 326 */
313int ecryptfs_process_quit(uid_t euid, pid_t pid) 327int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns,
328 struct pid *pid)
314{ 329{
315 struct ecryptfs_daemon *daemon; 330 struct ecryptfs_daemon *daemon;
316 int rc; 331 int rc;
317 332
318 mutex_lock(&ecryptfs_daemon_hash_mux); 333 mutex_lock(&ecryptfs_daemon_hash_mux);
319 rc = ecryptfs_find_daemon_by_euid(&daemon, euid); 334 rc = ecryptfs_find_daemon_by_euid(&daemon, euid, user_ns);
320 if (rc || !daemon) { 335 if (rc || !daemon) {
321 rc = -EINVAL; 336 rc = -EINVAL;
322 printk(KERN_ERR "Received request from user [%d] to " 337 printk(KERN_ERR "Received request from user [%d] to "
323 "unregister unrecognized daemon [%d]\n", euid, pid); 338 "unregister unrecognized daemon [0x%p]\n", euid, pid);
324 goto out_unlock; 339 goto out_unlock;
325 } 340 }
326 rc = ecryptfs_exorcise_daemon(daemon); 341 rc = ecryptfs_exorcise_daemon(daemon);
@@ -354,11 +369,14 @@ out_unlock:
354 * Returns zero on success; non-zero otherwise 369 * Returns zero on success; non-zero otherwise
355 */ 370 */
356int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, 371int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
357 pid_t pid, u32 seq) 372 struct user_namespace *user_ns, struct pid *pid,
373 u32 seq)
358{ 374{
359 struct ecryptfs_daemon *daemon; 375 struct ecryptfs_daemon *daemon;
360 struct ecryptfs_msg_ctx *msg_ctx; 376 struct ecryptfs_msg_ctx *msg_ctx;
361 size_t msg_size; 377 size_t msg_size;
378 struct nsproxy *nsproxy;
379 struct user_namespace *current_user_ns;
362 int rc; 380 int rc;
363 381
364 if (msg->index >= ecryptfs_message_buf_len) { 382 if (msg->index >= ecryptfs_message_buf_len) {
@@ -372,12 +390,25 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
372 msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; 390 msg_ctx = &ecryptfs_msg_ctx_arr[msg->index];
373 mutex_lock(&msg_ctx->mux); 391 mutex_lock(&msg_ctx->mux);
374 mutex_lock(&ecryptfs_daemon_hash_mux); 392 mutex_lock(&ecryptfs_daemon_hash_mux);
375 rc = ecryptfs_find_daemon_by_euid(&daemon, msg_ctx->task->euid); 393 rcu_read_lock();
394 nsproxy = task_nsproxy(msg_ctx->task);
395 if (nsproxy == NULL) {
396 rc = -EBADMSG;
397 printk(KERN_ERR "%s: Receiving process is a zombie. Dropping "
398 "message.\n", __func__);
399 rcu_read_unlock();
400 mutex_unlock(&ecryptfs_daemon_hash_mux);
401 goto wake_up;
402 }
403 current_user_ns = nsproxy->user_ns;
404 rc = ecryptfs_find_daemon_by_euid(&daemon, msg_ctx->task->euid,
405 current_user_ns);
406 rcu_read_unlock();
376 mutex_unlock(&ecryptfs_daemon_hash_mux); 407 mutex_unlock(&ecryptfs_daemon_hash_mux);
377 if (rc) { 408 if (rc) {
378 rc = -EBADMSG; 409 rc = -EBADMSG;
379 printk(KERN_WARNING "%s: User [%d] received a " 410 printk(KERN_WARNING "%s: User [%d] received a "
380 "message response from process [%d] but does " 411 "message response from process [0x%p] but does "
381 "not have a registered daemon\n", __func__, 412 "not have a registered daemon\n", __func__,
382 msg_ctx->task->euid, pid); 413 msg_ctx->task->euid, pid);
383 goto wake_up; 414 goto wake_up;
@@ -389,10 +420,17 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
389 euid, msg_ctx->task->euid); 420 euid, msg_ctx->task->euid);
390 goto unlock; 421 goto unlock;
391 } 422 }
423 if (current_user_ns != user_ns) {
424 rc = -EBADMSG;
425 printk(KERN_WARNING "%s: Received message from user_ns "
426 "[0x%p]; expected message from user_ns [0x%p]\n",
427 __func__, user_ns, nsproxy->user_ns);
428 goto unlock;
429 }
392 if (daemon->pid != pid) { 430 if (daemon->pid != pid) {
393 rc = -EBADMSG; 431 rc = -EBADMSG;
394 printk(KERN_ERR "%s: User [%d] sent a message response " 432 printk(KERN_ERR "%s: User [%d] sent a message response "
395 "from an unrecognized process [%d]\n", 433 "from an unrecognized process [0x%p]\n",
396 __func__, msg_ctx->task->euid, pid); 434 __func__, msg_ctx->task->euid, pid);
397 goto unlock; 435 goto unlock;
398 } 436 }
@@ -446,7 +484,8 @@ ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len,
446 struct ecryptfs_daemon *daemon; 484 struct ecryptfs_daemon *daemon;
447 int rc; 485 int rc;
448 486
449 rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid); 487 rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid,
488 current->nsproxy->user_ns);
450 if (rc || !daemon) { 489 if (rc || !daemon) {
451 rc = -ENOTCONN; 490 rc = -ENOTCONN;
452 printk(KERN_ERR "%s: User [%d] does not have a daemon " 491 printk(KERN_ERR "%s: User [%d] does not have a daemon "