aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/compat.c49
-rw-r--r--fs/eventpoll.c47
2 files changed, 47 insertions, 49 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 2ae2a98891cd..45137a3832f3 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -44,7 +44,6 @@
44#include <linux/signal.h> 44#include <linux/signal.h>
45#include <linux/poll.h> 45#include <linux/poll.h>
46#include <linux/mm.h> 46#include <linux/mm.h>
47#include <linux/eventpoll.h>
48#include <linux/fs_struct.h> 47#include <linux/fs_struct.h>
49#include <linux/slab.h> 48#include <linux/slab.h>
50#include <linux/pagemap.h> 49#include <linux/pagemap.h>
@@ -1659,54 +1658,6 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
1659 return ret; 1658 return ret;
1660} 1659}
1661 1660
1662#ifdef CONFIG_EPOLL
1663
1664asmlinkage long compat_sys_epoll_pwait(int epfd,
1665 struct compat_epoll_event __user *events,
1666 int maxevents, int timeout,
1667 const compat_sigset_t __user *sigmask,
1668 compat_size_t sigsetsize)
1669{
1670 long err;
1671 compat_sigset_t csigmask;
1672 sigset_t ksigmask, sigsaved;
1673
1674 /*
1675 * If the caller wants a certain signal mask to be set during the wait,
1676 * we apply it here.
1677 */
1678 if (sigmask) {
1679 if (sigsetsize != sizeof(compat_sigset_t))
1680 return -EINVAL;
1681 if (copy_from_user(&csigmask, sigmask, sizeof(csigmask)))
1682 return -EFAULT;
1683 sigset_from_compat(&ksigmask, &csigmask);
1684 sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
1685 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1686 }
1687
1688 err = sys_epoll_wait(epfd, events, maxevents, timeout);
1689
1690 /*
1691 * If we changed the signal mask, we need to restore the original one.
1692 * In case we've got a signal while waiting, we do not restore the
1693 * signal mask yet, and we allow do_signal() to deliver the signal on
1694 * the way back to userspace, before the signal mask is restored.
1695 */
1696 if (sigmask) {
1697 if (err == -EINTR) {
1698 memcpy(&current->saved_sigmask, &sigsaved,
1699 sizeof(sigsaved));
1700 set_restore_sigmask();
1701 } else
1702 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1703 }
1704
1705 return err;
1706}
1707
1708#endif /* CONFIG_EPOLL */
1709
1710#ifdef CONFIG_FHANDLE 1661#ifdef CONFIG_FHANDLE
1711/* 1662/*
1712 * Exactly like fs/open.c:sys_open_by_handle_at(), except that it 1663 * Exactly like fs/open.c:sys_open_by_handle_at(), except that it
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 9fec1836057a..495d15558f42 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -40,6 +40,7 @@
40#include <linux/atomic.h> 40#include <linux/atomic.h>
41#include <linux/proc_fs.h> 41#include <linux/proc_fs.h>
42#include <linux/seq_file.h> 42#include <linux/seq_file.h>
43#include <linux/compat.h>
43 44
44/* 45/*
45 * LOCKING: 46 * LOCKING:
@@ -1940,6 +1941,52 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events,
1940 return error; 1941 return error;
1941} 1942}
1942 1943
1944#ifdef CONFIG_COMPAT
1945COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd,
1946 struct epoll_event __user *, events,
1947 int, maxevents, int, timeout,
1948 const compat_sigset_t __user *, sigmask,
1949 compat_size_t, sigsetsize)
1950{
1951 long err;
1952 compat_sigset_t csigmask;
1953 sigset_t ksigmask, sigsaved;
1954
1955 /*
1956 * If the caller wants a certain signal mask to be set during the wait,
1957 * we apply it here.
1958 */
1959 if (sigmask) {
1960 if (sigsetsize != sizeof(compat_sigset_t))
1961 return -EINVAL;
1962 if (copy_from_user(&csigmask, sigmask, sizeof(csigmask)))
1963 return -EFAULT;
1964 sigset_from_compat(&ksigmask, &csigmask);
1965 sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
1966 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1967 }
1968
1969 err = sys_epoll_wait(epfd, events, maxevents, timeout);
1970
1971 /*
1972 * If we changed the signal mask, we need to restore the original one.
1973 * In case we've got a signal while waiting, we do not restore the
1974 * signal mask yet, and we allow do_signal() to deliver the signal on
1975 * the way back to userspace, before the signal mask is restored.
1976 */
1977 if (sigmask) {
1978 if (err == -EINTR) {
1979 memcpy(&current->saved_sigmask, &sigsaved,
1980 sizeof(sigsaved));
1981 set_restore_sigmask();
1982 } else
1983 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1984 }
1985
1986 return err;
1987}
1988#endif
1989
1943static int __init eventpoll_init(void) 1990static int __init eventpoll_init(void)
1944{ 1991{
1945 struct sysinfo si; 1992 struct sysinfo si;