dmaengine/ste_dma40: fix Oops due to double free of client descriptor
[linux-2.6.git] / fs / signalfd.c
index b07565c..492465b 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/list.h>
@@ -87,6 +88,7 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
                 err |= __put_user(kinfo->si_tid, &uinfo->ssi_tid);
                 err |= __put_user(kinfo->si_overrun, &uinfo->ssi_overrun);
                 err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr);
+                err |= __put_user(kinfo->si_int, &uinfo->ssi_int);
                break;
        case __SI_POLL:
                err |= __put_user(kinfo->si_band, &uinfo->ssi_band);
@@ -97,6 +99,16 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
 #ifdef __ARCH_SI_TRAPNO
                err |= __put_user(kinfo->si_trapno, &uinfo->ssi_trapno);
 #endif
+#ifdef BUS_MCEERR_AO
+               /* 
+                * Other callers might not initialize the si_lsb field,
+                * so check explicitly for the right codes here.
+                */
+               if (kinfo->si_code == BUS_MCEERR_AR ||
+                   kinfo->si_code == BUS_MCEERR_AO)
+                       err |= __put_user((short) kinfo->si_addr_lsb,
+                                         &uinfo->ssi_addr_lsb);
+#endif
                break;
        case __SI_CHLD:
                err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
@@ -110,6 +122,7 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
                err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
                err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
                err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr);
+               err |= __put_user(kinfo->si_int, &uinfo->ssi_int);
                break;
        default:
                /*
@@ -203,6 +216,7 @@ static const struct file_operations signalfd_fops = {
        .release        = signalfd_release,
        .poll           = signalfd_poll,
        .read           = signalfd_read,
+       .llseek         = noop_llseek,
 };
 
 SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask,
@@ -236,7 +250,7 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask,
                 * anon_inode_getfd() will install the fd.
                 */
                ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx,
-                                      flags & (O_CLOEXEC | O_NONBLOCK));
+                                      O_RDWR | (flags & (O_CLOEXEC | O_NONBLOCK)));
                if (ufd < 0)
                        kfree(ctx);
        } else {