Blame view

kernel/compat.c 9.98 KB
d2912cb15   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
  /*
   *  linux/kernel/compat.c
   *
   *  Kernel compatibililty routines for e.g. 32 bit syscall support
   *  on 64 bit kernels.
   *
   *  Copyright (C) 2002-2003 Stephen Rothwell, IBM Corporation
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
12
13
14
15
16
   */
  
  #include <linux/linkage.h>
  #include <linux/compat.h>
  #include <linux/errno.h>
  #include <linux/time.h>
  #include <linux/signal.h>
  #include <linux/sched.h>	/* for MAX_SCHEDULE_TIMEOUT */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
  #include <linux/syscalls.h>
  #include <linux/unistd.h>
  #include <linux/security.h>
6e5fdeedc   Paul Gortmaker   kernel: Fix files...
20
  #include <linux/export.h>
1b2db9fb7   Christoph Lameter   [PATCH] sys_move_...
21
  #include <linux/migrate.h>
1711ef386   Toyo Abe   [PATCH] posix-tim...
22
  #include <linux/posix-timers.h>
f06febc96   Frank Mayhar   timers: fix itime...
23
  #include <linux/times.h>
e3d5a27d5   Paul Mackerras   Allow times and t...
24
  #include <linux/ptrace.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
25
  #include <linux/gfp.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26

7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
27
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28

9afc5eee6   Arnd Bergmann   y2038: globally r...
29
  static int __compat_get_timeval(struct timeval *tv, const struct old_timeval32 __user *ctv)
6684ba202   H. Peter Anvin   compat: Add helpe...
30
  {
96d4f267e   Linus Torvalds   Remove 'type' arg...
31
  	return (!access_ok(ctv, sizeof(*ctv)) ||
6684ba202   H. Peter Anvin   compat: Add helpe...
32
33
34
  			__get_user(tv->tv_sec, &ctv->tv_sec) ||
  			__get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
  }
6684ba202   H. Peter Anvin   compat: Add helpe...
35

9afc5eee6   Arnd Bergmann   y2038: globally r...
36
  static int __compat_put_timeval(const struct timeval *tv, struct old_timeval32 __user *ctv)
6684ba202   H. Peter Anvin   compat: Add helpe...
37
  {
96d4f267e   Linus Torvalds   Remove 'type' arg...
38
  	return (!access_ok(ctv, sizeof(*ctv)) ||
6684ba202   H. Peter Anvin   compat: Add helpe...
39
40
41
  			__put_user(tv->tv_sec, &ctv->tv_sec) ||
  			__put_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
  }
6684ba202   H. Peter Anvin   compat: Add helpe...
42

9afc5eee6   Arnd Bergmann   y2038: globally r...
43
  static int __compat_get_timespec(struct timespec *ts, const struct old_timespec32 __user *cts)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
  {
96d4f267e   Linus Torvalds   Remove 'type' arg...
45
  	return (!access_ok(cts, sizeof(*cts)) ||
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
  			__get_user(ts->tv_sec, &cts->tv_sec) ||
  			__get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
  }
9afc5eee6   Arnd Bergmann   y2038: globally r...
49
  static int __compat_put_timespec(const struct timespec *ts, struct old_timespec32 __user *cts)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
  {
96d4f267e   Linus Torvalds   Remove 'type' arg...
51
  	return (!access_ok(cts, sizeof(*cts)) ||
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
53
54
  			__put_user(ts->tv_sec, &cts->tv_sec) ||
  			__put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
  }
6684ba202   H. Peter Anvin   compat: Add helpe...
55
56
57
  int compat_get_timeval(struct timeval *tv, const void __user *utv)
  {
  	if (COMPAT_USE_64BIT_TIME)
6516a4661   Fabian Frederick   kernel/compat.c: ...
58
  		return copy_from_user(tv, utv, sizeof(*tv)) ? -EFAULT : 0;
6684ba202   H. Peter Anvin   compat: Add helpe...
59
  	else
81993e81a   H. Peter Anvin   compat: Get rid o...
60
  		return __compat_get_timeval(tv, utv);
6684ba202   H. Peter Anvin   compat: Add helpe...
61
62
63
64
65
66
  }
  EXPORT_SYMBOL_GPL(compat_get_timeval);
  
  int compat_put_timeval(const struct timeval *tv, void __user *utv)
  {
  	if (COMPAT_USE_64BIT_TIME)
6516a4661   Fabian Frederick   kernel/compat.c: ...
67
  		return copy_to_user(utv, tv, sizeof(*tv)) ? -EFAULT : 0;
6684ba202   H. Peter Anvin   compat: Add helpe...
68
  	else
81993e81a   H. Peter Anvin   compat: Get rid o...
69
  		return __compat_put_timeval(tv, utv);
6684ba202   H. Peter Anvin   compat: Add helpe...
70
71
72
73
74
75
  }
  EXPORT_SYMBOL_GPL(compat_put_timeval);
  
  int compat_get_timespec(struct timespec *ts, const void __user *uts)
  {
  	if (COMPAT_USE_64BIT_TIME)
6516a4661   Fabian Frederick   kernel/compat.c: ...
76
  		return copy_from_user(ts, uts, sizeof(*ts)) ? -EFAULT : 0;
6684ba202   H. Peter Anvin   compat: Add helpe...
77
  	else
81993e81a   H. Peter Anvin   compat: Get rid o...
78
  		return __compat_get_timespec(ts, uts);
6684ba202   H. Peter Anvin   compat: Add helpe...
79
80
81
82
83
84
  }
  EXPORT_SYMBOL_GPL(compat_get_timespec);
  
  int compat_put_timespec(const struct timespec *ts, void __user *uts)
  {
  	if (COMPAT_USE_64BIT_TIME)
6516a4661   Fabian Frederick   kernel/compat.c: ...
85
  		return copy_to_user(uts, ts, sizeof(*ts)) ? -EFAULT : 0;
6684ba202   H. Peter Anvin   compat: Add helpe...
86
  	else
81993e81a   H. Peter Anvin   compat: Get rid o...
87
  		return __compat_put_timespec(ts, uts);
6684ba202   H. Peter Anvin   compat: Add helpe...
88
89
  }
  EXPORT_SYMBOL_GPL(compat_put_timespec);
54ad9c46c   Al Viro   itimers: Move com...
90
  int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
  {
54ad9c46c   Al Viro   itimers: Move com...
92
  	struct compat_itimerval v32;
baa73d9e4   Nicolas Pitre   posix-timers: Mak...
93

54ad9c46c   Al Viro   itimers: Move com...
94
95
96
97
98
99
100
  	if (copy_from_user(&v32, i, sizeof(struct compat_itimerval)))
  		return -EFAULT;
  	o->it_interval.tv_sec = v32.it_interval.tv_sec;
  	o->it_interval.tv_usec = v32.it_interval.tv_usec;
  	o->it_value.tv_sec = v32.it_value.tv_sec;
  	o->it_value.tv_usec = v32.it_value.tv_usec;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
  }
54ad9c46c   Al Viro   itimers: Move com...
102
  int put_compat_itimerval(struct compat_itimerval __user *o, const struct itimerval *i)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
  {
54ad9c46c   Al Viro   itimers: Move com...
104
  	struct compat_itimerval v32;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105

54ad9c46c   Al Viro   itimers: Move com...
106
107
108
109
110
  	v32.it_interval.tv_sec = i->it_interval.tv_sec;
  	v32.it_interval.tv_usec = i->it_interval.tv_usec;
  	v32.it_value.tv_sec = i->it_value.tv_sec;
  	v32.it_value.tv_usec = i->it_value.tv_usec;
  	return copy_to_user(o, &v32, sizeof(struct compat_itimerval)) ? -EFAULT : 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
  }
be84cb438   Chris Metcalf   compat: fixes to ...
112
  #ifdef __ARCH_WANT_SYS_SIGPROCMASK
b7dafa0ef   Jan Kiszka   compat: Fix RT si...
113
114
115
116
117
  /*
   * sys_sigprocmask SIG_SETMASK sets the first (compat) word of the
   * blocked set of signals to the supplied signal set
   */
  static inline void compat_sig_setmask(sigset_t *blocked, compat_sigset_word set)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
  {
b7dafa0ef   Jan Kiszka   compat: Fix RT si...
119
120
  	memcpy(blocked->sig, &set, sizeof(set));
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121

5cf221002   Al Viro   switch compat_sys...
122
123
124
  COMPAT_SYSCALL_DEFINE3(sigprocmask, int, how,
  		       compat_old_sigset_t __user *, nset,
  		       compat_old_sigset_t __user *, oset)
b7dafa0ef   Jan Kiszka   compat: Fix RT si...
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
  {
  	old_sigset_t old_set, new_set;
  	sigset_t new_blocked;
  
  	old_set = current->blocked.sig[0];
  
  	if (nset) {
  		if (get_user(new_set, nset))
  			return -EFAULT;
  		new_set &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP));
  
  		new_blocked = current->blocked;
  
  		switch (how) {
  		case SIG_BLOCK:
  			sigaddsetmask(&new_blocked, new_set);
  			break;
  		case SIG_UNBLOCK:
  			sigdelsetmask(&new_blocked, new_set);
  			break;
  		case SIG_SETMASK:
  			compat_sig_setmask(&new_blocked, new_set);
  			break;
  		default:
  			return -EINVAL;
  		}
  
  		set_current_blocked(&new_blocked);
  	}
  
  	if (oset) {
  		if (put_user(old_set, oset))
  			return -EFAULT;
  	}
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
  }
be84cb438   Chris Metcalf   compat: fixes to ...
162
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
164
  int put_compat_rusage(const struct rusage *r, struct compat_rusage __user *ru)
  {
7668b679c   Al Viro   put_compat_rusage...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  	struct compat_rusage r32;
  	memset(&r32, 0, sizeof(r32));
  	r32.ru_utime.tv_sec = r->ru_utime.tv_sec;
  	r32.ru_utime.tv_usec = r->ru_utime.tv_usec;
  	r32.ru_stime.tv_sec = r->ru_stime.tv_sec;
  	r32.ru_stime.tv_usec = r->ru_stime.tv_usec;
  	r32.ru_maxrss = r->ru_maxrss;
  	r32.ru_ixrss = r->ru_ixrss;
  	r32.ru_idrss = r->ru_idrss;
  	r32.ru_isrss = r->ru_isrss;
  	r32.ru_minflt = r->ru_minflt;
  	r32.ru_majflt = r->ru_majflt;
  	r32.ru_nswap = r->ru_nswap;
  	r32.ru_inblock = r->ru_inblock;
  	r32.ru_oublock = r->ru_oublock;
  	r32.ru_msgsnd = r->ru_msgsnd;
  	r32.ru_msgrcv = r->ru_msgrcv;
  	r32.ru_nsignals = r->ru_nsignals;
  	r32.ru_nvcsw = r->ru_nvcsw;
  	r32.ru_nivcsw = r->ru_nivcsw;
  	if (copy_to_user(ru, &r32, sizeof(r32)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
187
188
  		return -EFAULT;
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
  static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr,
a45185d2d   Rusty Russell   cpumask: convert ...
190
  				    unsigned len, struct cpumask *new_mask)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
  {
  	unsigned long *k;
a45185d2d   Rusty Russell   cpumask: convert ...
193
194
195
196
  	if (len < cpumask_size())
  		memset(new_mask, 0, cpumask_size());
  	else if (len > cpumask_size())
  		len = cpumask_size();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197

a45185d2d   Rusty Russell   cpumask: convert ...
198
  	k = cpumask_bits(new_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
200
  	return compat_get_bitmap(k, user_mask_ptr, len * 8);
  }
62a6fa976   Heiko Carstens   kernel/compat: co...
201
202
203
  COMPAT_SYSCALL_DEFINE3(sched_setaffinity, compat_pid_t, pid,
  		       unsigned int, len,
  		       compat_ulong_t __user *, user_mask_ptr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
  {
a45185d2d   Rusty Russell   cpumask: convert ...
205
  	cpumask_var_t new_mask;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
  	int retval;
a45185d2d   Rusty Russell   cpumask: convert ...
207
208
209
210
  	if (!alloc_cpumask_var(&new_mask, GFP_KERNEL))
  		return -ENOMEM;
  
  	retval = compat_get_user_cpu_mask(user_mask_ptr, len, new_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
  	if (retval)
a45185d2d   Rusty Russell   cpumask: convert ...
212
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213

a45185d2d   Rusty Russell   cpumask: convert ...
214
215
216
217
  	retval = sched_setaffinity(pid, new_mask);
  out:
  	free_cpumask_var(new_mask);
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
  }
62a6fa976   Heiko Carstens   kernel/compat: co...
219
220
  COMPAT_SYSCALL_DEFINE3(sched_getaffinity, compat_pid_t,  pid, unsigned int, len,
  		       compat_ulong_t __user *, user_mask_ptr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
222
  {
  	int ret;
a45185d2d   Rusty Russell   cpumask: convert ...
223
  	cpumask_var_t mask;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224

fa9dc265a   KOSAKI Motohiro   cpumask: fix comp...
225
226
227
  	if ((len * BITS_PER_BYTE) < nr_cpu_ids)
  		return -EINVAL;
  	if (len & (sizeof(compat_ulong_t)-1))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
  		return -EINVAL;
a45185d2d   Rusty Russell   cpumask: convert ...
229
230
231
232
  	if (!alloc_cpumask_var(&mask, GFP_KERNEL))
  		return -ENOMEM;
  
  	ret = sched_getaffinity(pid, mask);
fa9dc265a   KOSAKI Motohiro   cpumask: fix comp...
233
  	if (ret == 0) {
4de373a12   Alexey Dobriyan   cpumask: make cpu...
234
  		unsigned int retlen = min(len, cpumask_size());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235

fa9dc265a   KOSAKI Motohiro   cpumask: fix comp...
236
237
238
239
240
  		if (compat_put_bitmap(user_mask_ptr, cpumask_bits(mask), retlen * 8))
  			ret = -EFAULT;
  		else
  			ret = retlen;
  	}
a45185d2d   Rusty Russell   cpumask: convert ...
241
  	free_cpumask_var(mask);
fa9dc265a   KOSAKI Motohiro   cpumask: fix comp...
242

a45185d2d   Rusty Russell   cpumask: convert ...
243
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
248
249
250
251
252
253
254
  /*
   * We currently only need the following fields from the sigevent
   * structure: sigev_value, sigev_signo, sig_notify and (sometimes
   * sigev_notify_thread_id).  The others are handled in user mode.
   * We also assume that copying sigev_value.sival_int is sufficient
   * to keep all the bits of sigev_value.sival_ptr intact.
   */
  int get_compat_sigevent(struct sigevent *event,
  		const struct compat_sigevent __user *u_event)
  {
51410d3c5   David S. Miller   [PATCH] Fix get_c...
255
  	memset(event, 0, sizeof(*event));
96d4f267e   Linus Torvalds   Remove 'type' arg...
256
  	return (!access_ok(u_event, sizeof(*u_event)) ||
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
258
259
260
261
262
263
264
  		__get_user(event->sigev_value.sival_int,
  			&u_event->sigev_value.sival_int) ||
  		__get_user(event->sigev_signo, &u_event->sigev_signo) ||
  		__get_user(event->sigev_notify, &u_event->sigev_notify) ||
  		__get_user(event->sigev_notify_thread_id,
  			&u_event->sigev_notify_thread_id))
  		? -EFAULT : 0;
  }
5fa3839a6   Stephen Rothwell   [PATCH] Constify ...
265
  long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
267
  		       unsigned long bitmap_size)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
269
270
271
  	unsigned long nr_compat_longs;
  
  	/* align bitmap up to nearest compat_long_t boundary */
  	bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
1e1fc1334   Al Viro   compat_{get,put}_...
272
  	nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273

594cc251f   Linus Torvalds   make 'user_access...
274
  	if (!user_access_begin(umask, bitmap_size / 8))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
  		return -EFAULT;
1e1fc1334   Al Viro   compat_{get,put}_...
276
277
278
279
280
281
  	while (nr_compat_longs > 1) {
  		compat_ulong_t l1, l2;
  		unsafe_get_user(l1, umask++, Efault);
  		unsafe_get_user(l2, umask++, Efault);
  		*mask++ = ((unsigned long)l2 << BITS_PER_COMPAT_LONG) | l1;
  		nr_compat_longs -= 2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
  	}
1e1fc1334   Al Viro   compat_{get,put}_...
283
284
285
  	if (nr_compat_longs)
  		unsafe_get_user(*mask, umask++, Efault);
  	user_access_end();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
  	return 0;
1e1fc1334   Al Viro   compat_{get,put}_...
287
288
289
290
  
  Efault:
  	user_access_end();
  	return -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
292
293
294
295
  }
  
  long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
  		       unsigned long bitmap_size)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
297
298
299
  	unsigned long nr_compat_longs;
  
  	/* align bitmap up to nearest compat_long_t boundary */
  	bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
1e1fc1334   Al Viro   compat_{get,put}_...
300
  	nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301

594cc251f   Linus Torvalds   make 'user_access...
302
  	if (!user_access_begin(umask, bitmap_size / 8))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
  		return -EFAULT;
1e1fc1334   Al Viro   compat_{get,put}_...
304
305
306
307
308
  	while (nr_compat_longs > 1) {
  		unsigned long m = *mask++;
  		unsafe_put_user((compat_ulong_t)m, umask++, Efault);
  		unsafe_put_user(m >> BITS_PER_COMPAT_LONG, umask++, Efault);
  		nr_compat_longs -= 2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
  	}
1e1fc1334   Al Viro   compat_{get,put}_...
310
311
312
  	if (nr_compat_longs)
  		unsafe_put_user((compat_ulong_t)*mask, umask++, Efault);
  	user_access_end();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
  	return 0;
1e1fc1334   Al Viro   compat_{get,put}_...
314
315
316
  Efault:
  	user_access_end();
  	return -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
  }
3968cf623   Al Viro   get_compat_sigset()
318
319
  int
  get_compat_sigset(sigset_t *set, const compat_sigset_t __user *compat)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  {
3968cf623   Al Viro   get_compat_sigset()
321
322
323
324
  #ifdef __BIG_ENDIAN
  	compat_sigset_t v;
  	if (copy_from_user(&v, compat, sizeof(compat_sigset_t)))
  		return -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
325
  	switch (_NSIG_WORDS) {
3968cf623   Al Viro   get_compat_sigset()
326
  	case 4: set->sig[3] = v.sig[6] | (((long)v.sig[7]) << 32 );
89963adcd   Stephen Rothwell   kernel/compat.c: ...
327
  		/* fall through */
3968cf623   Al Viro   get_compat_sigset()
328
  	case 3: set->sig[2] = v.sig[4] | (((long)v.sig[5]) << 32 );
89963adcd   Stephen Rothwell   kernel/compat.c: ...
329
  		/* fall through */
3968cf623   Al Viro   get_compat_sigset()
330
  	case 2: set->sig[1] = v.sig[2] | (((long)v.sig[3]) << 32 );
89963adcd   Stephen Rothwell   kernel/compat.c: ...
331
  		/* fall through */
3968cf623   Al Viro   get_compat_sigset()
332
  	case 1: set->sig[0] = v.sig[0] | (((long)v.sig[1]) << 32 );
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
333
  	}
3968cf623   Al Viro   get_compat_sigset()
334
335
336
337
338
  #else
  	if (copy_from_user(set, compat, sizeof(compat_sigset_t)))
  		return -EFAULT;
  #endif
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
  }
3968cf623   Al Viro   get_compat_sigset()
340
  EXPORT_SYMBOL_GPL(get_compat_sigset);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341

c41d68a51   H. Peter Anvin   compat: Make comp...
342
343
344
345
346
347
348
349
350
351
352
353
354
  /*
   * Allocate user-space memory for the duration of a single system call,
   * in order to marshall parameters inside a compat thunk.
   */
  void __user *compat_alloc_user_space(unsigned long len)
  {
  	void __user *ptr;
  
  	/* If len would occupy more than half of the entire compat space... */
  	if (unlikely(len > (((compat_uptr_t)~0) >> 1)))
  		return NULL;
  
  	ptr = arch_compat_alloc_user_space(len);
96d4f267e   Linus Torvalds   Remove 'type' arg...
355
  	if (unlikely(!access_ok(ptr, len)))
c41d68a51   H. Peter Anvin   compat: Make comp...
356
357
358
359
360
  		return NULL;
  
  	return ptr;
  }
  EXPORT_SYMBOL_GPL(compat_alloc_user_space);