1 #include <linux/compat.h>
2 #include <linux/uaccess.h>
4 int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
7 bool ia32 = test_thread_flag(TIF_IA32);
9 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
13 /* If you change siginfo_t structure, please make sure that
14 this code is fixed accordingly.
15 It should never copy any pad contained in the structure
16 to avoid security leaks, but must copy the generic
17 3 ints plus the relevant union member. */
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);
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);
28 * First 32bits of unions are always present:
29 * si_pid === si_band === si_tid === si_addr(LS half)
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 if (from->si_signo == SIGBUS &&
36 (from->si_code == BUS_MCEERR_AR ||
37 from->si_code == BUS_MCEERR_AO))
38 put_user_ex(from->si_addr_lsb, &to->si_addr_lsb);
40 if (from->si_signo == SIGSEGV) {
41 if (from->si_code == SEGV_BNDERR) {
42 compat_uptr_t lower = (unsigned long)&to->si_lower;
43 compat_uptr_t upper = (unsigned long)&to->si_upper;
44 put_user_ex(lower, &to->si_lower);
45 put_user_ex(upper, &to->si_upper);
47 if (from->si_code == SEGV_PKUERR)
48 put_user_ex(from->si_pkey, &to->si_pkey);
52 put_user_ex(from->si_syscall, &to->si_syscall);
53 put_user_ex(from->si_arch, &to->si_arch);
57 put_user_ex(from->si_utime, &to->si_utime);
58 put_user_ex(from->si_stime, &to->si_stime);
60 put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
61 put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
63 put_user_ex(from->si_status, &to->si_status);
67 put_user_ex(from->si_uid, &to->si_uid);
70 put_user_ex(from->si_fd, &to->si_fd);
72 case __SI_TIMER >> 16:
73 put_user_ex(from->si_overrun, &to->si_overrun);
74 put_user_ex(ptr_to_compat(from->si_ptr),
77 /* This is not generated by the kernel as of now. */
79 case __SI_MESGQ >> 16:
80 put_user_ex(from->si_uid, &to->si_uid);
81 put_user_ex(from->si_int, &to->si_int);
85 } put_user_catch(err);
90 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
95 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
99 get_user_ex(to->si_signo, &from->si_signo);
100 get_user_ex(to->si_errno, &from->si_errno);
101 get_user_ex(to->si_code, &from->si_code);
103 get_user_ex(to->si_pid, &from->si_pid);
104 get_user_ex(to->si_uid, &from->si_uid);
105 get_user_ex(ptr32, &from->si_ptr);
106 to->si_ptr = compat_ptr(ptr32);
107 } get_user_catch(err);