1#include <linux/compat.h>
2#include <linux/uaccess.h>
3
4int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
5{
6 int err = 0;
7 bool ia32 = test_thread_flag(TIF_IA32);
8
9 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
10 return -EFAULT;
11
12 put_user_try {
13
14
15
16
17
18 put_user_ex(from->si_signo, &to->si_signo);
19 put_user_ex(from->si_errno, &to->si_errno);
20 put_user_ex((short)from->si_code, &to->si_code);
21
22 if (from->si_code < 0) {
23 put_user_ex(from->si_pid, &to->si_pid);
24 put_user_ex(from->si_uid, &to->si_uid);
25 put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
26 } else {
27
28
29
30
31 put_user_ex(from->_sifields._pad[0],
32 &to->_sifields._pad[0]);
33 switch (from->si_code >> 16) {
34 case __SI_FAULT >> 16:
35 break;
36 case __SI_SYS >> 16:
37 put_user_ex(from->si_syscall, &to->si_syscall);
38 put_user_ex(from->si_arch, &to->si_arch);
39 break;
40 case __SI_CHLD >> 16:
41 if (ia32) {
42 put_user_ex(from->si_utime, &to->si_utime);
43 put_user_ex(from->si_stime, &to->si_stime);
44 } else {
45 put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
46 put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
47 }
48 put_user_ex(from->si_status, &to->si_status);
49
50 default:
51 case __SI_KILL >> 16:
52 put_user_ex(from->si_uid, &to->si_uid);
53 break;
54 case __SI_POLL >> 16:
55 put_user_ex(from->si_fd, &to->si_fd);
56 break;
57 case __SI_TIMER >> 16:
58 put_user_ex(from->si_overrun, &to->si_overrun);
59 put_user_ex(ptr_to_compat(from->si_ptr),
60 &to->si_ptr);
61 break;
62
63 case __SI_RT >> 16:
64 case __SI_MESGQ >> 16:
65 put_user_ex(from->si_uid, &to->si_uid);
66 put_user_ex(from->si_int, &to->si_int);
67 break;
68 }
69 }
70 } put_user_catch(err);
71
72 return err;
73}
74
75int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
76{
77 int err = 0;
78 u32 ptr32;
79
80 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
81 return -EFAULT;
82
83 get_user_try {
84 get_user_ex(to->si_signo, &from->si_signo);
85 get_user_ex(to->si_errno, &from->si_errno);
86 get_user_ex(to->si_code, &from->si_code);
87
88 get_user_ex(to->si_pid, &from->si_pid);
89 get_user_ex(to->si_uid, &from->si_uid);
90 get_user_ex(ptr32, &from->si_ptr);
91 to->si_ptr = compat_ptr(ptr32);
92 } get_user_catch(err);
93
94 return err;
95}
96