History

Fix compat_sys_sigpending breakage

The latest change of compat_sys_sigpending in commit 8f13621abced ("sigpending(): move compat to native") has broken it in two ways. First, it tries to write 4 bytes more than userspace expects: sizeof(old_sigset_t) == sizeof(long) == 8 instead of sizeof(compat_old_sigset_t) == sizeof(u32) == 4. Second, on big endian architectures these bytes are being written in the wrong order. This bug was found by strace test suite.

Dmitry V. Levin committed 9 years ago

Commit fbb77611 parent 0fdd9511 file · +7 −4Browse files

Unified · Split

kernel/signal.c+7−4
@@ -3303,12 +3303,15 @@ SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) · 3302 unmodified lines
33033303 #ifdef CONFIG_COMPAT
33043304 COMPAT_SYSCALL_DEFINE1(sigpending, compat_old_sigset_t __user *, set32)
33053305 {
3306+#ifdef __BIG_ENDIAN
33063307 sigset_t set;
3307− int err = do_sigpending(&set, sizeof(old_sigset_t));
3308− if (err == 0)
3309− if (copy_to_user(set32, &set, sizeof(old_sigset_t)))
3310− err = -EFAULT;
3308+ int err = do_sigpending(&set, sizeof(set.sig[0]));
3309+ if (!err)
3310+ err = put_user(set.sig[0], set32);
33113311 return err;
3312+#else
3313+ return sys_rt_sigpending((sigset_t __user *)set32, sizeof(*set32));
3314+#endif
33123315 }
33133316 #endif
33143317