Blame view
ipc/msgutil.c
2.8 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
f30c22695 fix file specific... |
2 |
* linux/ipc/msgutil.c |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 6 7 8 9 10 11 12 13 14 15 |
* Copyright (C) 1999, 2004 Manfred Spraul * * This file is released under GNU General Public Licence version 2 or * (at your option) any later version. * * See the file COPYING for more details. */ #include <linux/spinlock.h> #include <linux/init.h> #include <linux/security.h> #include <linux/slab.h> #include <linux/ipc.h> |
614b84cf4 namespaces: mqueu... |
16 |
#include <linux/ipc_namespace.h> |
1da177e4c Linux-2.6.12-rc2 |
17 18 19 |
#include <asm/uaccess.h> #include "util.h" |
7eafd7c74 namespaces: ipc n... |
20 |
DEFINE_SPINLOCK(mq_lock); |
614b84cf4 namespaces: mqueu... |
21 22 23 24 25 26 |
/* * The next 2 defines are here bc this is the only file * compiled when either CONFIG_SYSVIPC and CONFIG_POSIX_MQUEUE * and not CONFIG_IPC_NS. */ struct ipc_namespace init_ipc_ns = { |
7eafd7c74 namespaces: ipc n... |
27 |
.count = ATOMIC_INIT(1), |
614b84cf4 namespaces: mqueu... |
28 |
#ifdef CONFIG_POSIX_MQUEUE |
614b84cf4 namespaces: mqueu... |
29 30 31 32 |
.mq_queues_max = DFLT_QUEUESMAX, .mq_msg_max = DFLT_MSGMAX, .mq_msgsize_max = DFLT_MSGSIZEMAX, #endif |
b515498f5 userns: add a use... |
33 |
.user_ns = &init_user_ns, |
614b84cf4 namespaces: mqueu... |
34 35 36 |
}; atomic_t nr_ipc_ns = ATOMIC_INIT(1); |
1da177e4c Linux-2.6.12-rc2 |
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
struct msg_msgseg { struct msg_msgseg* next; /* the next part of the message follows immediately */ }; #define DATALEN_MSG (PAGE_SIZE-sizeof(struct msg_msg)) #define DATALEN_SEG (PAGE_SIZE-sizeof(struct msg_msgseg)) struct msg_msg *load_msg(const void __user *src, int len) { struct msg_msg *msg; struct msg_msgseg **pseg; int err; int alen; alen = len; if (alen > DATALEN_MSG) alen = DATALEN_MSG; |
5cbded585 [PATCH] getting r... |
55 |
msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
if (msg == NULL) return ERR_PTR(-ENOMEM); msg->next = NULL; msg->security = NULL; if (copy_from_user(msg + 1, src, alen)) { err = -EFAULT; goto out_err; } len -= alen; src = ((char __user *)src) + alen; pseg = &msg->next; while (len > 0) { struct msg_msgseg *seg; alen = len; if (alen > DATALEN_SEG) alen = DATALEN_SEG; |
5cbded585 [PATCH] getting r... |
75 |
seg = kmalloc(sizeof(*seg) + alen, |
1da177e4c Linux-2.6.12-rc2 |
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
GFP_KERNEL); if (seg == NULL) { err = -ENOMEM; goto out_err; } *pseg = seg; seg->next = NULL; if (copy_from_user(seg + 1, src, alen)) { err = -EFAULT; goto out_err; } pseg = &seg->next; len -= alen; src = ((char __user *)src) + alen; } err = security_msg_msg_alloc(msg); if (err) goto out_err; return msg; out_err: free_msg(msg); return ERR_PTR(err); } int store_msg(void __user *dest, struct msg_msg *msg, int len) { int alen; struct msg_msgseg *seg; alen = len; if (alen > DATALEN_MSG) alen = DATALEN_MSG; if (copy_to_user(dest, msg + 1, alen)) return -1; len -= alen; dest = ((char __user *)dest) + alen; seg = msg->next; while (len > 0) { alen = len; if (alen > DATALEN_SEG) alen = DATALEN_SEG; if (copy_to_user(dest, seg + 1, alen)) return -1; len -= alen; dest = ((char __user *)dest) + alen; seg = seg->next; } return 0; } void free_msg(struct msg_msg *msg) { struct msg_msgseg *seg; security_msg_msg_free(msg); seg = msg->next; kfree(msg); while (seg != NULL) { struct msg_msgseg *tmp = seg->next; kfree(seg); seg = tmp; } } |