diff options
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/compat.c | 98 | ||||
-rw-r--r-- | ipc/syscall.c | 90 |
2 files changed, 93 insertions, 95 deletions
diff --git a/ipc/compat.c b/ipc/compat.c index 3c25ca1e46c7..00c2e3beccc8 100644 --- a/ipc/compat.c +++ b/ipc/compat.c | |||
@@ -39,11 +39,6 @@ struct compat_msgbuf { | |||
39 | char mtext[1]; | 39 | char mtext[1]; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct compat_ipc_kludge { | ||
43 | compat_uptr_t msgp; | ||
44 | compat_long_t msgtyp; | ||
45 | }; | ||
46 | |||
47 | int get_compat_ipc64_perm(struct ipc64_perm *to, | 42 | int get_compat_ipc64_perm(struct ipc64_perm *to, |
48 | struct compat_ipc64_perm __user *from) | 43 | struct compat_ipc64_perm __user *from) |
49 | { | 44 | { |
@@ -104,95 +99,6 @@ static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bu | |||
104 | return msgsz; | 99 | return msgsz; |
105 | } | 100 | } |
106 | 101 | ||
107 | #ifndef COMPAT_SHMLBA | ||
108 | #define COMPAT_SHMLBA SHMLBA | ||
109 | #endif | ||
110 | |||
111 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC | ||
112 | COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, | ||
113 | u32, third, compat_uptr_t, ptr, u32, fifth) | ||
114 | { | ||
115 | int version; | ||
116 | u32 pad; | ||
117 | |||
118 | version = call >> 16; /* hack for backward compatibility */ | ||
119 | call &= 0xffff; | ||
120 | |||
121 | switch (call) { | ||
122 | case SEMOP: | ||
123 | /* struct sembuf is the same on 32 and 64bit :)) */ | ||
124 | return sys_semtimedop(first, compat_ptr(ptr), second, NULL); | ||
125 | case SEMTIMEDOP: | ||
126 | return compat_sys_semtimedop(first, compat_ptr(ptr), second, | ||
127 | compat_ptr(fifth)); | ||
128 | case SEMGET: | ||
129 | return sys_semget(first, second, third); | ||
130 | case SEMCTL: | ||
131 | if (!ptr) | ||
132 | return -EINVAL; | ||
133 | if (get_user(pad, (u32 __user *) compat_ptr(ptr))) | ||
134 | return -EFAULT; | ||
135 | return compat_sys_semctl(first, second, third, pad); | ||
136 | |||
137 | case MSGSND: { | ||
138 | struct compat_msgbuf __user *up = compat_ptr(ptr); | ||
139 | compat_long_t type; | ||
140 | |||
141 | if (first < 0 || second < 0) | ||
142 | return -EINVAL; | ||
143 | |||
144 | if (get_user(type, &up->mtype)) | ||
145 | return -EFAULT; | ||
146 | |||
147 | return do_msgsnd(first, type, up->mtext, second, third); | ||
148 | } | ||
149 | case MSGRCV: { | ||
150 | void __user *uptr = compat_ptr(ptr); | ||
151 | |||
152 | if (first < 0 || second < 0) | ||
153 | return -EINVAL; | ||
154 | |||
155 | if (!version) { | ||
156 | struct compat_ipc_kludge ipck; | ||
157 | if (!uptr) | ||
158 | return -EINVAL; | ||
159 | if (copy_from_user(&ipck, uptr, sizeof(ipck))) | ||
160 | return -EFAULT; | ||
161 | uptr = compat_ptr(ipck.msgp); | ||
162 | fifth = ipck.msgtyp; | ||
163 | } | ||
164 | return do_msgrcv(first, uptr, second, (s32)fifth, third, | ||
165 | compat_do_msg_fill); | ||
166 | } | ||
167 | case MSGGET: | ||
168 | return sys_msgget(first, second); | ||
169 | case MSGCTL: | ||
170 | return compat_sys_msgctl(first, second, compat_ptr(ptr)); | ||
171 | |||
172 | case SHMAT: { | ||
173 | int err; | ||
174 | unsigned long raddr; | ||
175 | |||
176 | if (version == 1) | ||
177 | return -EINVAL; | ||
178 | err = do_shmat(first, compat_ptr(ptr), second, &raddr, | ||
179 | COMPAT_SHMLBA); | ||
180 | if (err < 0) | ||
181 | return err; | ||
182 | return put_user(raddr, (compat_ulong_t *)compat_ptr(third)); | ||
183 | } | ||
184 | case SHMDT: | ||
185 | return sys_shmdt(compat_ptr(ptr)); | ||
186 | case SHMGET: | ||
187 | return sys_shmget(first, (unsigned)second, third); | ||
188 | case SHMCTL: | ||
189 | return compat_sys_shmctl(first, second, compat_ptr(ptr)); | ||
190 | } | ||
191 | |||
192 | return -ENOSYS; | ||
193 | } | ||
194 | #endif | ||
195 | |||
196 | COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp, | 102 | COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp, |
197 | compat_ssize_t, msgsz, int, msgflg) | 103 | compat_ssize_t, msgsz, int, msgflg) |
198 | { | 104 | { |
@@ -211,6 +117,10 @@ COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, | |||
211 | msgflg, compat_do_msg_fill); | 117 | msgflg, compat_do_msg_fill); |
212 | } | 118 | } |
213 | 119 | ||
120 | #ifndef COMPAT_SHMLBA | ||
121 | #define COMPAT_SHMLBA SHMLBA | ||
122 | #endif | ||
123 | |||
214 | COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg) | 124 | COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg) |
215 | { | 125 | { |
216 | unsigned long ret; | 126 | unsigned long ret; |
diff --git a/ipc/syscall.c b/ipc/syscall.c index 52429489cde0..667022746ca5 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c | |||
@@ -5,12 +5,12 @@ | |||
5 | * the individual syscalls instead. | 5 | * the individual syscalls instead. |
6 | */ | 6 | */ |
7 | #include <linux/unistd.h> | 7 | #include <linux/unistd.h> |
8 | #include <linux/syscalls.h> | ||
8 | 9 | ||
9 | #ifdef __ARCH_WANT_SYS_IPC | 10 | #ifdef __ARCH_WANT_SYS_IPC |
10 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
11 | #include <linux/ipc.h> | 12 | #include <linux/ipc.h> |
12 | #include <linux/shm.h> | 13 | #include <linux/shm.h> |
13 | #include <linux/syscalls.h> | ||
14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
15 | 15 | ||
16 | SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, | 16 | SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, |
@@ -97,3 +97,91 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, | |||
97 | } | 97 | } |
98 | } | 98 | } |
99 | #endif | 99 | #endif |
100 | |||
101 | #ifdef CONFIG_COMPAT | ||
102 | #include <linux/compat.h> | ||
103 | |||
104 | #ifndef COMPAT_SHMLBA | ||
105 | #define COMPAT_SHMLBA SHMLBA | ||
106 | #endif | ||
107 | |||
108 | struct compat_ipc_kludge { | ||
109 | compat_uptr_t msgp; | ||
110 | compat_long_t msgtyp; | ||
111 | }; | ||
112 | |||
113 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC | ||
114 | COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, | ||
115 | u32, third, compat_uptr_t, ptr, u32, fifth) | ||
116 | { | ||
117 | int version; | ||
118 | u32 pad; | ||
119 | |||
120 | version = call >> 16; /* hack for backward compatibility */ | ||
121 | call &= 0xffff; | ||
122 | |||
123 | switch (call) { | ||
124 | case SEMOP: | ||
125 | /* struct sembuf is the same on 32 and 64bit :)) */ | ||
126 | return sys_semtimedop(first, compat_ptr(ptr), second, NULL); | ||
127 | case SEMTIMEDOP: | ||
128 | return compat_sys_semtimedop(first, compat_ptr(ptr), second, | ||
129 | compat_ptr(fifth)); | ||
130 | case SEMGET: | ||
131 | return sys_semget(first, second, third); | ||
132 | case SEMCTL: | ||
133 | if (!ptr) | ||
134 | return -EINVAL; | ||
135 | if (get_user(pad, (u32 __user *) compat_ptr(ptr))) | ||
136 | return -EFAULT; | ||
137 | return compat_sys_semctl(first, second, third, pad); | ||
138 | |||
139 | case MSGSND: | ||
140 | return compat_sys_msgsnd(first, ptr, second, third); | ||
141 | |||
142 | case MSGRCV: { | ||
143 | void __user *uptr = compat_ptr(ptr); | ||
144 | |||
145 | if (first < 0 || second < 0) | ||
146 | return -EINVAL; | ||
147 | |||
148 | if (!version) { | ||
149 | struct compat_ipc_kludge ipck; | ||
150 | if (!uptr) | ||
151 | return -EINVAL; | ||
152 | if (copy_from_user(&ipck, uptr, sizeof(ipck))) | ||
153 | return -EFAULT; | ||
154 | return compat_sys_msgrcv(first, ipck.msgp, second, | ||
155 | ipck.msgtyp, third); | ||
156 | } | ||
157 | return compat_sys_msgrcv(first, ptr, second, fifth, third); | ||
158 | } | ||
159 | case MSGGET: | ||
160 | return sys_msgget(first, second); | ||
161 | case MSGCTL: | ||
162 | return compat_sys_msgctl(first, second, compat_ptr(ptr)); | ||
163 | |||
164 | case SHMAT: { | ||
165 | int err; | ||
166 | unsigned long raddr; | ||
167 | |||
168 | if (version == 1) | ||
169 | return -EINVAL; | ||
170 | err = do_shmat(first, compat_ptr(ptr), second, &raddr, | ||
171 | COMPAT_SHMLBA); | ||
172 | if (err < 0) | ||
173 | return err; | ||
174 | return put_user(raddr, (compat_ulong_t *)compat_ptr(third)); | ||
175 | } | ||
176 | case SHMDT: | ||
177 | return sys_shmdt(compat_ptr(ptr)); | ||
178 | case SHMGET: | ||
179 | return sys_shmget(first, (unsigned)second, third); | ||
180 | case SHMCTL: | ||
181 | return compat_sys_shmctl(first, second, compat_ptr(ptr)); | ||
182 | } | ||
183 | |||
184 | return -ENOSYS; | ||
185 | } | ||
186 | #endif | ||
187 | #endif | ||