Merge branch 'master' into next
authorJames Morris <jmorris@namei.org>
Thu, 4 Dec 2008 06:16:36 +0000 (17:16 +1100)
committerJames Morris <jmorris@namei.org>
Thu, 4 Dec 2008 06:16:36 +0000 (17:16 +1100)
Conflicts:
fs/nfsd/nfs4recover.c

Manually fixed above to use new creds API functions, e.g.
nfs4_save_creds().

Signed-off-by: James Morris <jmorris@namei.org>
18 files changed:
1  2 
Documentation/kernel-parameters.txt
fs/cifs/misc.c
fs/namei.c
fs/nfsd/nfs4recover.c
fs/ocfs2/dlm/dlmfs.c
fs/ubifs/dir.c
include/linux/sched.h
include/linux/security.h
ipc/util.c
kernel/cgroup.c
kernel/ptrace.c
kernel/sched.c
kernel/sysctl.c
kernel/trace/trace.c
mm/migrate.c
net/rose/af_rose.c
net/socket.c
net/unix/af_unix.c

index 4974fbe546bc7643c6875d3af68a0421ce34a628,e0f346d201edb70fae654c55f6be842c4465a5ff..d8c4ceec37436a210c5a030c56c227f7253fe2c7
@@@ -294,7 -294,9 +294,9 @@@ and is between 256 and 4096 characters
                        Possible values are:
                        isolate - enable device isolation (each device, as far
                                  as possible, will get its own protection
-                                 domain)
+                                 domain) [default]
+                       share - put every device behind one IOMMU into the
+                               same protection domain
                        fullflush - enable flushing of IO/TLB entries when
                                    they are unmapped. Otherwise they are
                                    flushed before they will be reused, which
                        it is equivalent to "nosmp", which also disables
                        the IO APIC.
  
-       max_addr=[KMG]  [KNL,BOOT,ia64] All physical memory greater than or
-                       equal to this physical address is ignored.
+       max_addr=nn[KMG]        [KNL,BOOT,ia64] All physical memory greater than
+                       or equal to this physical address is ignored.
  
        max_luns=       [SCSI] Maximum number of LUNs to probe.
                        Should be between 1 and 2^32-1.
  
        mga=            [HW,DRM]
  
+       min_addr=nn[KMG]        [KNL,BOOT,ia64] All physical memory below this
+                       physical address is ignored.
        mminit_loglevel=
                        [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this
                        parameter allows control of the logging verbosity for
                        instruction doesn't work correctly and not to
                        use it.
  
 +      no_file_caps    Tells the kernel not to honor file capabilities.  The
 +                      only way then for a file to be executed with privilege
 +                      is to be setuid root or executed by root.
 +
        nohalt          [IA-64] Tells the kernel not to use the power saving
                        function PAL_HALT_LIGHT when idle. This increases
                        power-consumption. On the positive side, it reduces
diff --combined fs/cifs/misc.c
index f108040ca1bc624f45fdfb0f809158e17bc8d045,9ee3f689c2b0c0f78468082658d0aad8cf56791c..8a82d076450b052cb5a5ee628d3441675784362f
@@@ -338,13 -338,13 +338,13 @@@ header_assemble(struct smb_hdr *buffer
                /*  BB Add support for establishing new tCon and SMB Session  */
                /*      with userid/password pairs found on the smb session   */
                /*      for other target tcp/ip addresses               BB    */
 -                              if (current->fsuid != treeCon->ses->linux_uid) {
 +                              if (current_fsuid() != treeCon->ses->linux_uid) {
                                        cFYI(1, ("Multiuser mode and UID "
                                                 "did not match tcon uid"));
                                        read_lock(&cifs_tcp_ses_lock);
                                        list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
                                                ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
 -                                              if (ses->linux_uid == current->fsuid) {
 +                                              if (ses->linux_uid == current_fsuid()) {
                                                        if (ses->server == treeCon->ses->server) {
                                                                cFYI(1, ("found matching uid substitute right smb_uid"));
                                                                buffer->Uid = ses->Suid;
@@@ -555,12 -555,14 +555,14 @@@ is_valid_oplock_break(struct smb_hdr *b
                                continue;
  
                        cifs_stats_inc(&tcon->num_oplock_brks);
+                       write_lock(&GlobalSMBSeslock);
                        list_for_each(tmp2, &tcon->openFileList) {
                                netfile = list_entry(tmp2, struct cifsFileInfo,
                                                     tlist);
                                if (pSMB->Fid != netfile->netfid)
                                        continue;
  
+                               write_unlock(&GlobalSMBSeslock);
                                read_unlock(&cifs_tcp_ses_lock);
                                cFYI(1, ("file id match, oplock break"));
                                pCifsInode = CIFS_I(netfile->pInode);
  
                                return true;
                        }
+                       write_unlock(&GlobalSMBSeslock);
                        read_unlock(&cifs_tcp_ses_lock);
                        cFYI(1, ("No matching file for oplock break"));
                        return true;
diff --combined fs/namei.c
index 42d7b760693621eccda7fe5d9db7c1d7abb13bf5,d34e0f9681c6557d83852cf04646afbf9e670d98..af3783fff1de66ee922411dac7d5ad92811291d7
@@@ -186,7 -186,7 +186,7 @@@ int generic_permission(struct inode *in
  
        mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
  
 -      if (current->fsuid == inode->i_uid)
 +      if (current_fsuid() == inode->i_uid)
                mode >>= 6;
        else {
                if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) {
@@@ -441,7 -441,7 +441,7 @@@ static int exec_permission_lite(struct 
        if (inode->i_op && inode->i_op->permission)
                return -EAGAIN;
  
 -      if (current->fsuid == inode->i_uid)
 +      if (current_fsuid() == inode->i_uid)
                mode >>= 6;
        else if (in_group_p(inode->i_gid))
                mode >>= 3;
@@@ -1334,13 -1334,11 +1334,13 @@@ static int user_path_parent(int dfd, co
   */
  static inline int check_sticky(struct inode *dir, struct inode *inode)
  {
 +      uid_t fsuid = current_fsuid();
 +
        if (!(dir->i_mode & S_ISVTX))
                return 0;
 -      if (inode->i_uid == current->fsuid)
 +      if (inode->i_uid == fsuid)
                return 0;
 -      if (dir->i_uid == current->fsuid)
 +      if (dir->i_uid == fsuid)
                return 0;
        return !capable(CAP_FOWNER);
  }
@@@ -1380,7 -1378,7 +1380,7 @@@ static int may_delete(struct inode *dir
        if (IS_APPEND(dir))
                return -EPERM;
        if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
-           IS_IMMUTABLE(victim->d_inode))
+           IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode))
                return -EPERM;
        if (isdir) {
                if (!S_ISDIR(victim->d_inode->i_mode))
diff --combined fs/nfsd/nfs4recover.c
index 9371ea12d7fa459e6ff9b6f6babd148eaccfd1fb,b79ec930d9f1af003ddfb1fd9d130b12f6755f8b..0f9d6efaa62bb553bb95b3063516bcb793f52929
  static struct path rec_dir;
  static int rec_dir_init = 0;
  
 -static void
 -nfs4_save_user(uid_t *saveuid, gid_t *savegid)
 +static int
 +nfs4_save_creds(const struct cred **original_creds)
  {
 -      *saveuid = current->fsuid;
 -      *savegid = current->fsgid;
 -      current->fsuid = 0;
 -      current->fsgid = 0;
 +      struct cred *new;
 +
 +      new = prepare_creds();
 +      if (!new)
 +              return -ENOMEM;
 +
 +      new->fsuid = 0;
 +      new->fsgid = 0;
 +      *original_creds = override_creds(new);
 +      put_cred(new);
 +      return 0;
  }
  
  static void
 -nfs4_reset_user(uid_t saveuid, gid_t savegid)
 +nfs4_reset_creds(const struct cred *original)
  {
 -      current->fsuid = saveuid;
 -      current->fsgid = savegid;
 +      revert_creds(original);
  }
  
  static void
@@@ -135,9 -129,10 +135,9 @@@ nfsd4_sync_rec_dir(void
  int
  nfsd4_create_clid_dir(struct nfs4_client *clp)
  {
 +      const struct cred *original_cred;
        char *dname = clp->cl_recdir;
        struct dentry *dentry;
 -      uid_t uid;
 -      gid_t gid;
        int status;
  
        dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname);
        if (!rec_dir_init || clp->cl_firststate)
                return 0;
  
 -      nfs4_save_user(&uid, &gid);
 +      status = nfs4_save_creds(&original_cred);
 +      if (status < 0)
 +              return status;
  
        /* lock the parent */
        mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
@@@ -175,7 -168,7 +175,7 @@@ out_unlock
                clp->cl_firststate = 1;
                nfsd4_sync_rec_dir();
        }
 -      nfs4_reset_user(uid, gid);
 +      nfs4_reset_creds(original_cred);
        dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status);
        return status;
  }
@@@ -218,28 -211,26 +218,29 @@@ nfsd4_build_dentrylist(void *arg, cons
  static int
  nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
  {
 +      const struct cred *original_cred;
        struct file *filp;
        struct dentry_list_arg dla = {
                .parent = dir,
        };
        struct list_head *dentries = &dla.dentries;
        struct dentry_list *child;
 -      uid_t uid;
 -      gid_t gid;
        int status;
  
        if (!rec_dir_init)
                return 0;
  
 -      nfs4_save_user(&uid, &gid);
 +      status = nfs4_save_creds(&original_cred);
 +      if (status < 0)
 +              return status;
+       INIT_LIST_HEAD(dentries);
  
 -      filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
 +      filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY,
 +                         current_cred());
        status = PTR_ERR(filp);
        if (IS_ERR(filp))
                goto out;
 +      INIT_LIST_HEAD(dentries);
        status = vfs_readdir(filp, nfsd4_build_dentrylist, &dla);
        fput(filp);
        while (!list_empty(dentries)) {
@@@ -258,7 -249,7 +259,7 @@@ out
                dput(child->dentry);
                kfree(child);
        }
 -      nfs4_reset_user(uid, gid);
 +      nfs4_reset_creds(original_cred);
        return status;
  }
  
@@@ -320,7 -311,8 +321,7 @@@ out
  void
  nfsd4_remove_clid_dir(struct nfs4_client *clp)
  {
 -      uid_t uid;
 -      gid_t gid;
 +      const struct cred *original_cred;
        int status;
  
        if (!rec_dir_init || !clp->cl_firststate)
        if (status)
                goto out;
        clp->cl_firststate = 0;
 -      nfs4_save_user(&uid, &gid);
 +
 +      status = nfs4_save_creds(&original_cred);
 +      if (status < 0)
 +              goto out;
 +
        status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1);
 -      nfs4_reset_user(uid, gid);
 +      nfs4_reset_creds(original_cred);
        if (status == 0)
                nfsd4_sync_rec_dir();
        mnt_drop_write(rec_dir.mnt);
@@@ -413,21 -401,16 +414,21 @@@ nfsd4_recdir_load(void) 
  void
  nfsd4_init_recdir(char *rec_dirname)
  {
 -      uid_t                   uid = 0;
 -      gid_t                   gid = 0;
 -      int                     status;
 +      const struct cred *original_cred;
 +      int status;
  
        printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
                        rec_dirname);
  
        BUG_ON(rec_dir_init);
  
 -      nfs4_save_user(&uid, &gid);
 +      status = nfs4_save_creds(&original_cred);
 +      if (status < 0) {
 +              printk("NFSD: Unable to change credentials to find recovery"
 +                     " directory: error %d\n",
 +                     status);
 +              return;
 +      }
  
        status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
                        &rec_dir);
  
        if (!status)
                rec_dir_init = 1;
 -      nfs4_reset_user(uid, gid);
 +      nfs4_reset_creds(original_cred);
  }
  
  void
diff --combined fs/ocfs2/dlm/dlmfs.c
index 3516d8a4166b1d68be3ada7bfdf5513df82f0ad6,ba962d71b34d15e7e089c741a9d6bd0d14559e79..6f7a77d5402001071f4f75a6f7ccbf5cf666a537
@@@ -339,8 -339,8 +339,8 @@@ static struct inode *dlmfs_get_root_ino
                ip = DLMFS_I(inode);
  
                inode->i_mode = mode;
 -              inode->i_uid = current->fsuid;
 -              inode->i_gid = current->fsgid;
 +              inode->i_uid = current_fsuid();
 +              inode->i_gid = current_fsgid();
                inode->i_blocks = 0;
                inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
@@@ -365,8 -365,8 +365,8 @@@ static struct inode *dlmfs_get_inode(st
                return NULL;
  
        inode->i_mode = mode;
 -      inode->i_uid = current->fsuid;
 -      inode->i_gid = current->fsgid;
 +      inode->i_uid = current_fsuid();
 +      inode->i_gid = current_fsgid();
        inode->i_blocks = 0;
        inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
@@@ -608,8 -608,10 +608,10 @@@ static int __init init_dlmfs_fs(void
                                0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
                                        SLAB_MEM_SPREAD),
                                dlmfs_init_once);
-       if (!dlmfs_inode_cache)
+       if (!dlmfs_inode_cache) {
+               status = -ENOMEM;
                goto bail;
+       }
        cleanup_inode = 1;
  
        user_dlm_worker = create_singlethread_workqueue("user_dlm");
diff --combined fs/ubifs/dir.c
index 856189014a3a3706368eb9d6dc987e2ba7c50233,0422c98e17932e41ecca3f25c6dea8aedb10e133..f448ab1f9c38eb7861ec62ad998fdebce72e1aa9
@@@ -104,13 -104,13 +104,13 @@@ struct inode *ubifs_new_inode(struct ub
         */
        inode->i_flags |= (S_NOCMTIME);
  
 -      inode->i_uid = current->fsuid;
 +      inode->i_uid = current_fsuid();
        if (dir->i_mode & S_ISGID) {
                inode->i_gid = dir->i_gid;
                if (S_ISDIR(mode))
                        mode |= S_ISGID;
        } else
 -              inode->i_gid = current->fsgid;
 +              inode->i_gid = current_fsgid();
        inode->i_mode = mode;
        inode->i_mtime = inode->i_atime = inode->i_ctime =
                         ubifs_current_time(inode);
                        return ERR_PTR(-EINVAL);
                }
                ubifs_warn("running out of inode numbers (current %lu, max %d)",
-                          c->highest_inum, INUM_WATERMARK);
+                          (unsigned long)c->highest_inum, INUM_WATERMARK);
        }
  
        inode->i_ino = ++c->highest_inum;
@@@ -428,7 -428,8 +428,8 @@@ static int ubifs_readdir(struct file *f
                dbg_gen("feed '%s', ino %llu, new f_pos %#x",
                        dent->name, (unsigned long long)le64_to_cpu(dent->inum),
                        key_hash_flash(c, &dent->key));
-               ubifs_assert(dent->ch.sqnum > ubifs_inode(dir)->creat_sqnum);
+               ubifs_assert(le64_to_cpu(dent->ch.sqnum) >
+                            ubifs_inode(dir)->creat_sqnum);
  
                nm.len = le16_to_cpu(dent->nlen);
                over = filldir(dirent, dent->name, nm.len, file->f_pos,
diff --combined include/linux/sched.h
index 7f8015a3082e1c20eadca552cff2ce2c00052251,55e30d11447790dd433d0e874285ced3a5499328..9624e2cfc2dcdd36b193aed42befca13c35bb2fc
@@@ -572,6 -572,12 +572,6 @@@ struct signal_struct 
         */
        struct rlimit rlim[RLIM_NLIMITS];
  
 -      /* keep the process-shared keyrings here so that they do the right
 -       * thing in threads created with CLONE_THREAD */
 -#ifdef CONFIG_KEYS
 -      struct key *session_keyring;    /* keyring inherited over fork */
 -      struct key *process_keyring;    /* keyring private to this process */
 -#endif
  #ifdef CONFIG_BSD_PROCESS_ACCT
        struct pacct_struct pacct;      /* per-process accounting information */
  #endif
@@@ -624,6 -630,10 +624,10 @@@ struct user_struct 
        atomic_t inotify_watches; /* How many inotify watches does this user have? */
        atomic_t inotify_devs;  /* How many inotify devs does this user have opened? */
  #endif
+ #ifdef CONFIG_EPOLL
+       atomic_t epoll_devs;    /* The number of epoll descriptors currently open */
+       atomic_t epoll_watches; /* The number of file descriptors currently watched */
+ #endif
  #ifdef CONFIG_POSIX_MQUEUE
        /* protected by mq_lock */
        unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
        /* Hash table maintenance information */
        struct hlist_node uidhash_node;
        uid_t uid;
 +      struct user_namespace *user_ns;
  
  #ifdef CONFIG_USER_SCHED
        struct task_group *tg;
@@@ -656,7 -665,6 +660,7 @@@ extern struct user_struct *find_user(ui
  extern struct user_struct root_user;
  #define INIT_USER (&root_user)
  
 +
  struct backing_dev_info;
  struct reclaim_state;
  
@@@ -880,7 -888,38 +884,7 @@@ partition_sched_domains(int ndoms_new, 
  #endif        /* !CONFIG_SMP */
  
  struct io_context;                    /* See blkdev.h */
 -#define NGROUPS_SMALL         32
 -#define NGROUPS_PER_BLOCK     ((unsigned int)(PAGE_SIZE / sizeof(gid_t)))
 -struct group_info {
 -      int ngroups;
 -      atomic_t usage;
 -      gid_t small_block[NGROUPS_SMALL];
 -      int nblocks;
 -      gid_t *blocks[0];
 -};
  
 -/*
 - * get_group_info() must be called with the owning task locked (via task_lock())
 - * when task != current.  The reason being that the vast majority of callers are
 - * looking at current->group_info, which can not be changed except by the
 - * current task.  Changing current->group_info requires the task lock, too.
 - */
 -#define get_group_info(group_info) do { \
 -      atomic_inc(&(group_info)->usage); \
 -} while (0)
 -
 -#define put_group_info(group_info) do { \
 -      if (atomic_dec_and_test(&(group_info)->usage)) \
 -              groups_free(group_info); \
 -} while (0)
 -
 -extern struct group_info *groups_alloc(int gidsetsize);
 -extern void groups_free(struct group_info *group_info);
 -extern int set_current_groups(struct group_info *group_info);
 -extern int groups_search(struct group_info *group_info, gid_t grp);
 -/* access the groups "array" with this macro */
 -#define GROUP_AT(gi, i) \
 -    ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK])
  
  #ifdef ARCH_HAS_PREFETCH_SWITCH_STACK
  extern void prefetch_stack(struct task_struct *t);
@@@ -1147,12 -1186,17 +1151,12 @@@ struct task_struct 
        struct list_head cpu_timers[3];
  
  /* process credentials */
 -      uid_t uid,euid,suid,fsuid;
 -      gid_t gid,egid,sgid,fsgid;
 -      struct group_info *group_info;
 -      kernel_cap_t   cap_effective, cap_inheritable, cap_permitted, cap_bset;
 -      struct user_struct *user;
 -      unsigned securebits;
 -#ifdef CONFIG_KEYS
 -      unsigned char jit_keyring;      /* default keyring to attach requested keys to */
 -      struct key *request_key_auth;   /* assumed request_key authority */
 -      struct key *thread_keyring;     /* keyring private to this thread */
 -#endif
 +      const struct cred *real_cred;   /* objective and real subjective task
 +                                       * credentials (COW) */
 +      const struct cred *cred;        /* effective (overridable) subjective task
 +                                       * credentials (COW) */
 +      struct mutex cred_exec_mutex;   /* execve vs ptrace cred calculation mutex */
 +
        char comm[TASK_COMM_LEN]; /* executable name excluding path
                                     - access with [gs]et_task_comm (which lock
                                       it with task_lock())
        int (*notifier)(void *priv);
        void *notifier_data;
        sigset_t *notifier_mask;
 -#ifdef CONFIG_SECURITY
 -      void *security;
 -#endif
        struct audit_context *audit_context;
  #ifdef CONFIG_AUDITSYSCALL
        uid_t loginuid;
@@@ -1728,6 -1775,7 +1732,6 @@@ static inline struct user_struct *get_u
        return u;
  }
  extern void free_uid(struct user_struct *);
 -extern void switch_uid(struct user_struct *);
  extern void release_uids(struct user_namespace *ns);
  
  #include <asm/current.h>
@@@ -1746,6 -1794,9 +1750,6 @@@ extern void wake_up_new_task(struct tas
  extern void sched_fork(struct task_struct *p, int clone_flags);
  extern void sched_dead(struct task_struct *p);
  
 -extern int in_group_p(gid_t);
 -extern int in_egroup_p(gid_t);
 -
  extern void proc_caches_init(void);
  extern void flush_signals(struct task_struct *);
  extern void ignore_signals(struct task_struct *);
@@@ -1877,8 -1928,6 +1881,8 @@@ static inline unsigned long wait_task_i
  #define for_each_process(p) \
        for (p = &init_task ; (p = next_task(p)) != &init_task ; )
  
 +extern bool is_single_threaded(struct task_struct *);
 +
  /*
   * Careful: do_each_thread/while_each_thread is a double loop so
   *          'break' will not work as expected - use goto instead.
diff --combined include/linux/security.h
index 59a11e19b617d2b2e55151a8214d5163cccefd4c,e3d4ecda267381d85da5697b2ad681c1da749fe3..6423abf1ac0faee1385d460bcd9951b1bd85a955
  /* Maximum number of letters for an LSM name string */
  #define SECURITY_NAME_MAX     10
  
 +/* If capable should audit the security request */
 +#define SECURITY_CAP_NOAUDIT 0
 +#define SECURITY_CAP_AUDIT 1
 +
  struct ctl_table;
  struct audit_krule;
  
   * These functions are in security/capability.c and are used
   * as the default capabilities functions
   */
 -extern int cap_capable(struct task_struct *tsk, int cap);
 +extern int cap_capable(struct task_struct *tsk, int cap, int audit);
  extern int cap_settime(struct timespec *ts, struct timezone *tz);
  extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode);
  extern int cap_ptrace_traceme(struct task_struct *parent);
  extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
 -extern int cap_capset_check(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
 -extern void cap_capset_set(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
 -extern int cap_bprm_set_security(struct linux_binprm *bprm);
 -extern void cap_bprm_apply_creds(struct linux_binprm *bprm, int unsafe);
 +extern int cap_capset(struct cred *new, const struct cred *old,
 +                    const kernel_cap_t *effective,
 +                    const kernel_cap_t *inheritable,
 +                    const kernel_cap_t *permitted);
 +extern int cap_bprm_set_creds(struct linux_binprm *bprm);
  extern int cap_bprm_secureexec(struct linux_binprm *bprm);
  extern int cap_inode_setxattr(struct dentry *dentry, const char *name,
                              const void *value, size_t size, int flags);
  extern int cap_inode_removexattr(struct dentry *dentry, const char *name);
  extern int cap_inode_need_killpriv(struct dentry *dentry);
  extern int cap_inode_killpriv(struct dentry *dentry);
 -extern int cap_task_post_setuid(uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
 -extern void cap_task_reparent_to_init(struct task_struct *p);
 +extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags);
  extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
 -                        unsigned long arg4, unsigned long arg5, long *rc_p);
 +                        unsigned long arg4, unsigned long arg5);
  extern int cap_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp);
  extern int cap_task_setioprio(struct task_struct *p, int ioprio);
  extern int cap_task_setnice(struct task_struct *p, int nice);
@@@ -109,7 -105,7 +109,7 @@@ extern unsigned long mmap_min_addr
  struct sched_param;
  struct request_sock;
  
 -/* bprm_apply_creds unsafe reasons */
 +/* bprm->unsafe reasons */
  #define LSM_UNSAFE_SHARE      1
  #define LSM_UNSAFE_PTRACE     2
  #define LSM_UNSAFE_PTRACE_CAP 4
@@@ -153,7 -149,36 +153,7 @@@ static inline void security_free_mnt_op
   *
   * Security hooks for program execution operations.
   *
 - * @bprm_alloc_security:
 - *    Allocate and attach a security structure to the @bprm->security field.
 - *    The security field is initialized to NULL when the bprm structure is
 - *    allocated.
 - *    @bprm contains the linux_binprm structure to be modified.
 - *    Return 0 if operation was successful.
 - * @bprm_free_security:
 - *    @bprm contains the linux_binprm structure to be modified.
 - *    Deallocate and clear the @bprm->security field.
 - * @bprm_apply_creds:
 - *    Compute and set the security attributes of a process being transformed
 - *    by an execve operation based on the old attributes (current->security)
 - *    and the information saved in @bprm->security by the set_security hook.
 - *    Since this hook function (and its caller) are void, this hook can not
 - *    return an error.  However, it can leave the security attributes of the
 - *    process unchanged if an access failure occurs at this point.
 - *    bprm_apply_creds is called under task_lock.  @unsafe indicates various
 - *    reasons why it may be unsafe to change security state.
 - *    @bprm contains the linux_binprm structure.
 - * @bprm_post_apply_creds:
 - *    Runs after bprm_apply_creds with the task_lock dropped, so that
 - *    functions which cannot be called safely under the task_lock can
 - *    be used.  This hook is a good place to perform state changes on
 - *    the process such as closing open file descriptors to which access
 - *    is no longer granted if the attributes were changed.
 - *    Note that a security module might need to save state between
 - *    bprm_apply_creds and bprm_post_apply_creds to store the decision
 - *    on whether the process may proceed.
 - *    @bprm contains the linux_binprm structure.
 - * @bprm_set_security:
 + * @bprm_set_creds:
   *    Save security information in the bprm->security field, typically based
   *    on information about the bprm->file, for later use by the apply_creds
   *    hook.  This hook may also optionally check permissions (e.g. for
   *    @bprm contains the linux_binprm structure.
   *    Return 0 if the hook is successful and permission is granted.
   * @bprm_check_security:
 - *    This hook mediates the point when a search for a binary handler will
 - *    begin.  It allows a check the @bprm->security value which is set in
 - *    the preceding set_security call.  The primary difference from
 - *    set_security is that the argv list and envp list are reliably
 - *    available in @bprm.  This hook may be called multiple times
 - *    during a single execve; and in each pass set_security is called
 - *    first.
 + *    This hook mediates the point when a search for a binary handler will
 + *    begin.  It allows a check the @bprm->security value which is set in the
 + *    preceding set_creds call.  The primary difference from set_creds is
 + *    that the argv list and envp list are reliably available in @bprm.  This
 + *    hook may be called multiple times during a single execve; and in each
 + *    pass set_creds is called first.
   *    @bprm contains the linux_binprm structure.
   *    Return 0 if the hook is successful and permission is granted.
 + * @bprm_committing_creds:
 + *    Prepare to install the new security attributes of a process being
 + *    transformed by an execve operation, based on the old credentials
 + *    pointed to by @current->cred and the information set in @bprm->cred by
 + *    the bprm_set_creds hook.  @bprm points to the linux_binprm structure.
 + *    This hook is a good place to perform state changes on the process such
 + *    as closing open file descriptors to which access will no longer be
 + *    granted when the attributes are changed.  This is called immediately
 + *    before commit_creds().
 + * @bprm_committed_creds:
 + *    Tidy up after the installation of the new security attributes of a
 + *    process being transformed by an execve operation.  The new credentials
 + *    have, by this point, been set to @current->cred.  @bprm points to the
 + *    linux_binprm structure.  This hook is a good place to perform state
 + *    changes on the process such as clearing out non-inheritable signal
 + *    state.  This is called immediately after commit_creds().
   * @bprm_secureexec:
   *    Return a boolean value (0 or 1) indicating whether a "secure exec"
   *    is required.  The flag is passed in the auxiliary table
   *    manual page for definitions of the @clone_flags.
   *    @clone_flags contains the flags indicating what should be shared.
   *    Return 0 if permission is granted.
 - * @task_alloc_security:
 - *    @p contains the task_struct for child process.
 - *    Allocate and attach a security structure to the p->security field. The
 - *    security field is initialized to NULL when the task structure is
 - *    allocated.
 - *    Return 0 if operation was successful.
 - * @task_free_security:
 - *    @p contains the task_struct for process.
 - *    Deallocate and clear the p->security field.
 + * @cred_free:
 + *    @cred points to the credentials.
 + *    Deallocate and clear the cred->security field in a set of credentials.
 + * @cred_prepare:
 + *    @new points to the new credentials.
 + *    @old points to the original credentials.
 + *    @gfp indicates the atomicity of any memory allocations.
 + *    Prepare a new set of credentials by copying the data from the old set.
 + * @cred_commit:
 + *    @new points to the new credentials.
 + *    @old points to the original credentials.
 + *    Install a new set of credentials.
 + * @kernel_act_as:
 + *    Set the credentials for a kernel service to act as (subjective context).
 + *    @new points to the credentials to be modified.
 + *    @secid specifies the security ID to be set
 + *    The current task must be the one that nominated @secid.
 + *    Return 0 if successful.
 + * @kernel_create_files_as:
 + *    Set the file creation context in a set of credentials to be the same as
 + *    the objective context of the specified inode.
 + *    @new points to the credentials to be modified.
 + *    @inode points to the inode to use as a reference.
 + *    The current task must be the one that nominated @inode.
 + *    Return 0 if successful.
   * @task_setuid:
   *    Check permission before setting one or more of the user identity
   *    attributes of the current process.  The @flags parameter indicates
   *    @id2 contains a uid.
   *    @flags contains one of the LSM_SETID_* values.
   *    Return 0 if permission is granted.
 - * @task_post_setuid:
 + * @task_fix_setuid:
   *    Update the module's state after setting one or more of the user
   *    identity attributes of the current process.  The @flags parameter
   *    indicates which of the set*uid system calls invoked this hook.  If
 - *    @flags is LSM_SETID_FS, then @old_ruid is the old fs uid and the other
 - *    parameters are not used.
 - *    @old_ruid contains the old real uid (or fs uid if LSM_SETID_FS).
 - *    @old_euid contains the old effective uid (or -1 if LSM_SETID_FS).
 - *    @old_suid contains the old saved uid (or -1 if LSM_SETID_FS).
 + *    @new is the set of credentials that will be installed.  Modifications
 + *    should be made to this rather than to @current->cred.
 + *    @old is the set of credentials that are being replaces
   *    @flags contains one of the LSM_SETID_* values.
   *    Return 0 on success.
   * @task_setgid:
   *    @arg3 contains a argument.
   *    @arg4 contains a argument.
   *    @arg5 contains a argument.
 - *      @rc_p contains a pointer to communicate back the forced return code
 - *    Return 0 if permission is granted, and non-zero if the security module
 - *      has taken responsibility (setting *rc_p) for the prctl call.
 - * @task_reparent_to_init:
 - *    Set the security attributes in @p->security for a kernel thread that
 - *    is being reparented to the init task.
 - *    @p contains the task_struct for the kernel thread.
 + *    Return -ENOSYS if no-one wanted to handle this op, any other value to
 + *    cause prctl() to return immediately with that value.
   * @task_to_inode:
   *    Set the security attributes for an inode based on an associated task's
   *    security attributes, e.g. for /proc/pid inodes.
   *    See whether a specific operational right is granted to a process on a
   *    key.
   *    @key_ref refers to the key (key pointer + possession attribute bit).
 - *    @context points to the process to provide the context against which to
 + *    @cred points to the credentials to provide the context against which to
   *    evaluate the security data on the key.
   *    @perm describes the combination of permissions required of this key.
   *    Return 1 if permission granted, 0 if permission denied and -ve it the
   *    @child process.
   *    Security modules may also want to perform a process tracing check
   *    during an execve in the set_security or apply_creds hooks of
 + *    tracing check during an execve in the bprm_set_creds hook of
   *    binprm_security_ops if the process is being traced and its security
   *    attributes would be changed by the execve.
   *    @child contains the task_struct structure for the target process.
   *    @inheritable contains the inheritable capability set.
   *    @permitted contains the permitted capability set.
   *    Return 0 if the capability sets were successfully obtained.
 - * @capset_check:
 - *    Check permission before setting the @effective, @inheritable, and
 - *    @permitted capability sets for the @target process.
 - *    Caveat:  @target is also set to current if a set of processes is
 - *    specified (i.e. all processes other than current and init or a
 - *    particular process group).  Hence, the capset_set hook may need to
 - *    revalidate permission to the actual target process.
 - *    @target contains the task_struct structure for target process.
 - *    @effective contains the effective capability set.
 - *    @inheritable contains the inheritable capability set.
 - *    @permitted contains the permitted capability set.
 - *    Return 0 if permission is granted.
 - * @capset_set:
 + * @capset:
   *    Set the @effective, @inheritable, and @permitted capability sets for
 - *    the @target process.  Since capset_check cannot always check permission
 - *    to the real @target process, this hook may also perform permission
 - *    checking to determine if the current process is allowed to set the
 - *    capability sets of the @target process.  However, this hook has no way
 - *    of returning an error due to the structure of the sys_capset code.
 - *    @target contains the task_struct structure for target process.
 + *    the current process.
 + *    @new contains the new credentials structure for target process.
 + *    @old contains the current credentials structure for target process.
   *    @effective contains the effective capability set.
   *    @inheritable contains the inheritable capability set.
   *    @permitted contains the permitted capability set.
 + *    Return 0 and update @new if permission is granted.
   * @capable:
   *    Check whether the @tsk process has the @cap capability.
   *    @tsk contains the task_struct for the process.
@@@ -1285,12 -1299,15 +1285,12 @@@ struct security_operations 
        int (*capget) (struct task_struct *target,
                       kernel_cap_t *effective,
                       kernel_cap_t *inheritable, kernel_cap_t *permitted);
 -      int (*capset_check) (struct task_struct *target,
 -                           kernel_cap_t *effective,
 -                           kernel_cap_t *inheritable,
 -                           kernel_cap_t *permitted);
 -      void (*capset_set) (struct task_struct *target,
 -                          kernel_cap_t *effective,
 -                          kernel_cap_t *inheritable,
 -                          kernel_cap_t *permitted);
 -      int (*capable) (struct task_struct *tsk, int cap);
 +      int (*capset) (struct cred *new,
 +                     const struct cred *old,
 +                     const kernel_cap_t *effective,
 +                     const kernel_cap_t *inheritable,
 +                     const kernel_cap_t *permitted);
 +      int (*capable) (struct task_struct *tsk, int cap, int audit);
        int (*acct) (struct file *file);
        int (*sysctl) (struct ctl_table *table, int op);
        int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
        int (*settime) (struct timespec *ts, struct timezone *tz);
        int (*vm_enough_memory) (struct mm_struct *mm, long pages);
  
 -      int (*bprm_alloc_security) (struct linux_binprm *bprm);
 -      void (*bprm_free_security) (struct linux_binprm *bprm);
 -      void (*bprm_apply_creds) (struct linux_binprm *bprm, int unsafe);
 -      void (*bprm_post_apply_creds) (struct linux_binprm *bprm);
 -      int (*bprm_set_security) (struct linux_binprm *bprm);
 +      int (*bprm_set_creds) (struct linux_binprm *bprm);
        int (*bprm_check_security) (struct linux_binprm *bprm);
        int (*bprm_secureexec) (struct linux_binprm *bprm);
 +      void (*bprm_committing_creds) (struct linux_binprm *bprm);
 +      void (*bprm_committed_creds) (struct linux_binprm *bprm);
  
        int (*sb_alloc_security) (struct super_block *sb);
        void (*sb_free_security) (struct super_block *sb);
        int (*file_send_sigiotask) (struct task_struct *tsk,
                                    struct fown_struct *fown, int sig);
        int (*file_receive) (struct file *file);
 -      int (*dentry_open) (struct file *file);
 +      int (*dentry_open) (struct file *file, const struct cred *cred);
  
        int (*task_create) (unsigned long clone_flags);
 -      int (*task_alloc_security) (struct task_struct *p);
 -      void (*task_free_security) (struct task_struct *p);
 +      void (*cred_free) (struct cred *cred);
 +      int (*cred_prepare)(struct cred *new, const struct cred *old,
 +                          gfp_t gfp);
 +      void (*cred_commit)(struct cred *new, const struct cred *old);
 +      int (*kernel_act_as)(struct cred *new, u32 secid);
 +      int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
        int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags);
 -      int (*task_post_setuid) (uid_t old_ruid /* or fsuid */ ,
 -                               uid_t old_euid, uid_t old_suid, int flags);
 +      int (*task_fix_setuid) (struct cred *new, const struct cred *old,
 +                              int flags);
        int (*task_setgid) (gid_t id0, gid_t id1, gid_t id2, int flags);
        int (*task_setpgid) (struct task_struct *p, pid_t pgid);
        int (*task_getpgid) (struct task_struct *p);
        int (*task_wait) (struct task_struct *p);
        int (*task_prctl) (int option, unsigned long arg2,
                           unsigned long arg3, unsigned long arg4,
 -                         unsigned long arg5, long *rc_p);
 -      void (*task_reparent_to_init) (struct task_struct *p);
 +                         unsigned long arg5);
        void (*task_to_inode) (struct task_struct *p, struct inode *inode);
  
        int (*ipc_permission) (struct kern_ipc_perm *ipcp, short flag);
  
        /* key management security hooks */
  #ifdef CONFIG_KEYS
 -      int (*key_alloc) (struct key *key, struct task_struct *tsk, unsigned long flags);
 +      int (*key_alloc) (struct key *key, const struct cred *cred, unsigned long flags);
        void (*key_free) (struct key *key);
        int (*key_permission) (key_ref_t key_ref,
 -                             struct task_struct *context,
 +                             const struct cred *cred,
                               key_perm_t perm);
        int (*key_getsecurity)(struct key *key, char **_buffer);
  #endif        /* CONFIG_KEYS */
@@@ -1552,12 -1568,15 +1552,12 @@@ int security_capget(struct task_struct 
                    kernel_cap_t *effective,
                    kernel_cap_t *inheritable,
                    kernel_cap_t *permitted);
 -int security_capset_check(struct task_struct *target,
 -                        kernel_cap_t *effective,
 -                        kernel_cap_t *inheritable,
 -                        kernel_cap_t *permitted);
 -void security_capset_set(struct task_struct *target,
 -                       kernel_cap_t *effective,
 -                       kernel_cap_t *inheritable,
 -                       kernel_cap_t *permitted);
 +int security_capset(struct cred *new, const struct cred *old,
 +                  const kernel_cap_t *effective,
 +                  const kernel_cap_t *inheritable,
 +                  const kernel_cap_t *permitted);
  int security_capable(struct task_struct *tsk, int cap);
 +int security_capable_noaudit(struct task_struct *tsk, int cap);
  int security_acct(struct file *file);
  int security_sysctl(struct ctl_table *table, int op);
  int security_quotactl(int cmds, int type, int id, struct super_block *sb);
@@@ -1567,10 -1586,12 +1567,10 @@@ int security_settime(struct timespec *t
  int security_vm_enough_memory(long pages);
  int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
  int security_vm_enough_memory_kern(long pages);
 -int security_bprm_alloc(struct linux_binprm *bprm);
 -void security_bprm_free(struct linux_binprm *bprm);
 -void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe);
 -void security_bprm_post_apply_creds(struct linux_binprm *bprm);
 -int security_bprm_set(struct linux_binprm *bprm);
 +int security_bprm_set_creds(struct linux_binprm *bprm);
  int security_bprm_check(struct linux_binprm *bprm);
 +void security_bprm_committing_creds(struct linux_binprm *bprm);
 +void security_bprm_committed_creds(struct linux_binprm *bprm);
  int security_bprm_secureexec(struct linux_binprm *bprm);
  int security_sb_alloc(struct super_block *sb);
  void security_sb_free(struct super_block *sb);
@@@ -1642,16 -1663,13 +1642,16 @@@ int security_file_set_fowner(struct fil
  int security_file_send_sigiotask(struct task_struct *tsk,
                                 struct fown_struct *fown, int sig);
  int security_file_receive(struct file *file);
 -int security_dentry_open(struct file *file);
 +int security_dentry_open(struct file *file, const struct cred *cred);
  int security_task_create(unsigned long clone_flags);
 -int security_task_alloc(struct task_struct *p);
 -void security_task_free(struct task_struct *p);
 +void security_cred_free(struct cred *cred);
 +int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
 +void security_commit_creds(struct cred *new, const struct cred *old);
 +int security_kernel_act_as(struct cred *new, u32 secid);
 +int security_kernel_create_files_as(struct cred *new, struct inode *inode);
  int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags);
 -int security_task_post_setuid(uid_t old_ruid, uid_t old_euid,
 -                            uid_t old_suid, int flags);
 +int security_task_fix_setuid(struct cred *new, const struct cred *old,
 +                           int flags);
  int security_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags);
  int security_task_setpgid(struct task_struct *p, pid_t pgid);
  int security_task_getpgid(struct task_struct *p);
@@@ -1670,7 -1688,8 +1670,7 @@@ int security_task_kill(struct task_stru
                        int sig, u32 secid);
  int security_task_wait(struct task_struct *p);
  int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
 -                       unsigned long arg4, unsigned long arg5, long *rc_p);
 -void security_task_reparent_to_init(struct task_struct *p);
 +                      unsigned long arg4, unsigned long arg5);
  void security_task_to_inode(struct task_struct *p, struct inode *inode);
  int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag);
  void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid);
@@@ -1745,23 -1764,25 +1745,23 @@@ static inline int security_capget(struc
        return cap_capget(target, effective, inheritable, permitted);
  }
  
 -static inline int security_capset_check(struct task_struct *target,
 -                                       kernel_cap_t *effective,
 -                                       kernel_cap_t *inheritable,
 -                                       kernel_cap_t *permitted)
 +static inline int security_capset(struct cred *new,
 +                                 const struct cred *old,
 +                                 const kernel_cap_t *effective,
 +                                 const kernel_cap_t *inheritable,
 +                                 const kernel_cap_t *permitted)
  {
 -      return cap_capset_check(target, effective, inheritable, permitted);
 +      return cap_capset(new, old, effective, inheritable, permitted);
  }
  
 -static inline void security_capset_set(struct task_struct *target,
 -                                      kernel_cap_t *effective,
 -                                      kernel_cap_t *inheritable,
 -                                      kernel_cap_t *permitted)
 +static inline int security_capable(struct task_struct *tsk, int cap)
  {
 -      cap_capset_set(target, effective, inheritable, permitted);
 +      return cap_capable(tsk, cap, SECURITY_CAP_AUDIT);
  }
  
 -static inline int security_capable(struct task_struct *tsk, int cap)
 +static inline int security_capable_noaudit(struct task_struct *tsk, int cap)
  {
 -      return cap_capable(tsk, cap);
 +      return cap_capable(tsk, cap, SECURITY_CAP_NOAUDIT);
  }
  
  static inline int security_acct(struct file *file)
@@@ -1797,35 -1818,49 +1797,39 @@@ static inline int security_settime(stru
  
  static inline int security_vm_enough_memory(long pages)
  {
+       WARN_ON(current->mm == NULL);
        return cap_vm_enough_memory(current->mm, pages);
  }
  
- static inline int security_vm_enough_memory_kern(long pages)
+ static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
  {
-       return cap_vm_enough_memory(current->mm, pages);
+       WARN_ON(mm == NULL);
+       return cap_vm_enough_memory(mm, pages);
  }
  
- static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
+ static inline int security_vm_enough_memory_kern(long pages)
  {
-       return cap_vm_enough_memory(mm, pages);
+       /* If current->mm is a kernel thread then we will pass NULL,
+          for this specific case that is fine */
+       return cap_vm_enough_memory(current->mm, pages);
  }
  
 -static inline int security_bprm_alloc(struct linux_binprm *bprm)
 -{
 -      return 0;
 -}
 -
 -static inline void security_bprm_free(struct linux_binprm *bprm)
 -{ }
 -
 -static inline void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
 +static inline int security_bprm_set_creds(struct linux_binprm *bprm)
  {
 -      cap_bprm_apply_creds(bprm, unsafe);
 +      return cap_bprm_set_creds(bprm);
  }
  
 -static inline void security_bprm_post_apply_creds(struct linux_binprm *bprm)
 +static inline int security_bprm_check(struct linux_binprm *bprm)
  {
 -      return;
 +      return 0;
  }
  
 -static inline int security_bprm_set(struct linux_binprm *bprm)
 +static inline void security_bprm_committing_creds(struct linux_binprm *bprm)
  {
 -      return cap_bprm_set_security(bprm);
  }
  
 -static inline int security_bprm_check(struct linux_binprm *bprm)
 +static inline void security_bprm_committed_creds(struct linux_binprm *bprm)
  {
 -      return 0;
  }
  
  static inline int security_bprm_secureexec(struct linux_binprm *bprm)
@@@ -2142,8 -2177,7 +2146,8 @@@ static inline int security_file_receive
        return 0;
  }
  
 -static inline int security_dentry_open(struct file *file)
 +static inline int security_dentry_open(struct file *file,
 +                                     const struct cred *cred)
  {
        return 0;
  }
@@@ -2153,31 -2187,13 +2157,31 @@@ static inline int security_task_create(
        return 0;
  }
  
 -static inline int security_task_alloc(struct task_struct *p)
 +static inline void security_cred_free(struct cred *cred)
 +{ }
 +
 +static inline int security_prepare_creds(struct cred *new,
 +                                       const struct cred *old,
 +                                       gfp_t gfp)
  {
        return 0;
  }
  
 -static inline void security_task_free(struct task_struct *p)
 -{ }
 +static inline void security_commit_creds(struct cred *new,
 +                                       const struct cred *old)
 +{
 +}
 +
 +static inline int security_kernel_act_as(struct cred *cred, u32 secid)
 +{
 +      return 0;
 +}
 +
 +static inline int security_kernel_create_files_as(struct cred *cred,
 +                                                struct inode *inode)
 +{
 +      return 0;
 +}
  
  static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2,
                                       int flags)
        return 0;
  }
  
 -static inline int security_task_post_setuid(uid_t old_ruid, uid_t old_euid,
 -                                          uid_t old_suid, int flags)
 +static inline int security_task_fix_setuid(struct cred *new,
 +                                         const struct cred *old,
 +                                         int flags)
  {
 -      return cap_task_post_setuid(old_ruid, old_euid, old_suid, flags);
 +      return cap_task_fix_setuid(new, old, flags);
  }
  
  static inline int security_task_setgid(gid_t id0, gid_t id1, gid_t id2,
@@@ -2276,9 -2291,14 +2280,9 @@@ static inline int security_task_wait(st
  static inline int security_task_prctl(int option, unsigned long arg2,
                                      unsigned long arg3,
                                      unsigned long arg4,
 -                                    unsigned long arg5, long *rc_p)
 -{
 -      return cap_task_prctl(option, arg2, arg3, arg3, arg5, rc_p);
 -}
 -
 -static inline void security_task_reparent_to_init(struct task_struct *p)
 +                                    unsigned long arg5)
  {
 -      cap_task_reparent_to_init(p);
 +      return cap_task_prctl(option, arg2, arg3, arg3, arg5);
  }
  
  static inline void security_task_to_inode(struct task_struct *p, struct inode *inode)
@@@ -2704,16 -2724,16 +2708,16 @@@ static inline void security_skb_classif
  #ifdef CONFIG_KEYS
  #ifdef CONFIG_SECURITY
  
 -int security_key_alloc(struct key *key, struct task_struct *tsk, unsigned long flags);
 +int security_key_alloc(struct key *key, const struct cred *cred, unsigned long flags);
  void security_key_free(struct key *key);
  int security_key_permission(key_ref_t key_ref,
 -                          struct task_struct *context, key_perm_t perm);
 +                          const struct cred *cred, key_perm_t perm);
  int security_key_getsecurity(struct key *key, char **_buffer);
  
  #else
  
  static inline int security_key_alloc(struct key *key,
 -                                   struct task_struct *tsk,
 +                                   const struct cred *cred,
                                     unsigned long flags)
  {
        return 0;
@@@ -2724,7 -2744,7 +2728,7 @@@ static inline void security_key_free(st
  }
  
  static inline int security_key_permission(key_ref_t key_ref,
 -                                        struct task_struct *context,
 +                                        const struct cred *cred,
                                          key_perm_t perm)
  {
        return 0;
diff --combined ipc/util.c
index c8a76701b6c957f595d08ede271773c3b8e5b435,361fd1c96fcf31b92475882803dc927f281a8718..5a1808c774a2f238746c9234ca40822eaff47fd9
@@@ -258,8 -258,6 +258,8 @@@ int ipc_get_maxid(struct ipc_ids *ids
   
  int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
  {
 +      uid_t euid;
 +      gid_t egid;
        int id, err;
  
        if (size > IPCMNI)
        if (ids->in_use >= size)
                return -ENOSPC;
  
+       spin_lock_init(&new->lock);
+       new->deleted = 0;
+       rcu_read_lock();
+       spin_lock(&new->lock);
        err = idr_get_new(&ids->ipcs_idr, new, &id);
-       if (err)
+       if (err) {
+               spin_unlock(&new->lock);
+               rcu_read_unlock();
                return err;
+       }
  
        ids->in_use++;
  
 -      new->cuid = new->uid = current->euid;
 -      new->gid = new->cgid = current->egid;
 +      current_euid_egid(&euid, &egid);
 +      new->cuid = new->uid = euid;
 +      new->gid = new->cgid = egid;
  
        new->seq = ids->seq++;
        if(ids->seq > ids->seq_max)
                ids->seq = 0;
  
        new->id = ipc_buildid(id, new->seq);
-       spin_lock_init(&new->lock);
-       new->deleted = 0;
-       rcu_read_lock();
-       spin_lock(&new->lock);
        return id;
  }
  
@@@ -619,15 -620,13 +623,15 @@@ void ipc_rcu_putref(void *ptr
   
  int ipcperms (struct kern_ipc_perm *ipcp, short flag)
  {     /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
 +      uid_t euid = current_euid();
        int requested_mode, granted_mode, err;
  
        if (unlikely((err = audit_ipc_obj(ipcp))))
                return err;
        requested_mode = (flag >> 6) | (flag >> 3) | flag;
        granted_mode = ipcp->mode;
 -      if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
 +      if (euid == ipcp->cuid ||
 +          euid == ipcp->uid)
                granted_mode >>= 6;
        else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
                granted_mode >>= 3;
@@@ -789,7 -788,6 +793,7 @@@ struct kern_ipc_perm *ipcctl_pre_down(s
                                      struct ipc64_perm *perm, int extra_perm)
  {
        struct kern_ipc_perm *ipcp;
 +      uid_t euid;
        int err;
  
        down_write(&ids->rw_mutex);
                if (err)
                        goto out_unlock;
        }
 -      if (current->euid == ipcp->cuid ||
 -          current->euid == ipcp->uid || capable(CAP_SYS_ADMIN))
 +
 +      euid = current_euid();
 +      if (euid == ipcp->cuid ||
 +          euid == ipcp->uid  || capable(CAP_SYS_ADMIN))
                return ipcp;
  
        err = -EPERM;
diff --combined kernel/cgroup.c
index 8fe8c0cb137bb4e38073df7c1a0c03d72c25afa3,fe00b3b983a86387332234703217abb1d28ca202..dee025f2f2868a93babf4883b44370d57496530a
@@@ -571,8 -571,8 +571,8 @@@ static struct inode *cgroup_new_inode(m
  
        if (inode) {
                inode->i_mode = mode;
 -              inode->i_uid = current->fsuid;
 -              inode->i_gid = current->fsgid;
 +              inode->i_uid = current_fsuid();
 +              inode->i_gid = current_fsgid();
                inode->i_blocks = 0;
                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
                inode->i_mapping->backing_dev_info = &cgroup_backing_dev_info;
@@@ -1279,7 -1279,6 +1279,7 @@@ int cgroup_attach_task(struct cgroup *c
  static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
  {
        struct task_struct *tsk;
 +      const struct cred *cred = current_cred(), *tcred;
        int ret;
  
        if (pid) {
                        rcu_read_unlock();
                        return -ESRCH;
                }
 -              get_task_struct(tsk);
 -              rcu_read_unlock();
  
 -              if ((current->euid) && (current->euid != tsk->uid)
 -                  && (current->euid != tsk->suid)) {
 -                      put_task_struct(tsk);
 +              tcred = __task_cred(tsk);
 +              if (cred->euid &&
 +                  cred->euid != tcred->uid &&
 +                  cred->euid != tcred->suid) {
 +                      rcu_read_unlock();
                        return -EACCES;
                }
 +              get_task_struct(tsk);
 +              rcu_read_unlock();
        } else {
                tsk = current;
                get_task_struct(tsk);
@@@ -2042,10 -2039,13 +2042,13 @@@ int cgroupstats_build(struct cgroupstat
        struct cgroup *cgrp;
        struct cgroup_iter it;
        struct task_struct *tsk;
        /*
-        * Validate dentry by checking the superblock operations
+        * Validate dentry by checking the superblock operations,
+        * and make sure it's a directory.
         */
-       if (dentry->d_sb->s_op != &cgroup_ops)
+       if (dentry->d_sb->s_op != &cgroup_ops ||
+           !S_ISDIR(dentry->d_inode->i_mode))
                 goto err;
  
        ret = 0;
@@@ -2475,10 -2475,7 +2478,7 @@@ static int cgroup_rmdir(struct inode *u
                mutex_unlock(&cgroup_mutex);
                return -EBUSY;
        }
-       parent = cgrp->parent;
-       root = cgrp->root;
-       sb = root->sb;
+       mutex_unlock(&cgroup_mutex);
  
        /*
         * Call pre_destroy handlers of subsys. Notify subsystems
         */
        cgroup_call_pre_destroy(cgrp);
  
-       if (cgroup_has_css_refs(cgrp)) {
+       mutex_lock(&cgroup_mutex);
+       parent = cgrp->parent;
+       root = cgrp->root;
+       sb = root->sb;
+       if (atomic_read(&cgrp->count)
+           || !list_empty(&cgrp->children)
+           || cgroup_has_css_refs(cgrp)) {
                mutex_unlock(&cgroup_mutex);
                return -EBUSY;
        }
diff --combined kernel/ptrace.c
index f764b88069555856cf265e7354ca1f10a38e95d3,4c8bcd7dd8e0831aa7a66e5c200324cff682721f..ca2df68faf7631439f276983d7f6e28e5b0771ed
@@@ -115,8 -115,6 +115,8 @@@ int ptrace_check_attach(struct task_str
  
  int __ptrace_may_access(struct task_struct *task, unsigned int mode)
  {
 +      const struct cred *cred = current_cred(), *tcred;
 +
        /* May we inspect the given task?
         * This check is used both for attaching with ptrace
         * and for allowing access to sensitive information in /proc.
        /* Don't let security modules deny introspection */
        if (task == current)
                return 0;
 -      if (((current->uid != task->euid) ||
 -           (current->uid != task->suid) ||
 -           (current->uid != task->uid) ||
 -           (current->gid != task->egid) ||
 -           (current->gid != task->sgid) ||
 -           (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
 +      rcu_read_lock();
 +      tcred = __task_cred(task);
 +      if ((cred->uid != tcred->euid ||
 +           cred->uid != tcred->suid ||
 +           cred->uid != tcred->uid  ||
 +           cred->gid != tcred->egid ||
 +           cred->gid != tcred->sgid ||
 +           cred->gid != tcred->gid) &&
 +          !capable(CAP_SYS_PTRACE)) {
 +              rcu_read_unlock();
                return -EPERM;
 +      }
 +      rcu_read_unlock();
        smp_rmb();
        if (task->mm)
                dumpable = get_dumpable(task->mm);
@@@ -171,14 -163,6 +171,14 @@@ int ptrace_attach(struct task_struct *t
        if (same_thread_group(task, current))
                goto out;
  
 +      /* Protect exec's credential calculations against our interference;
 +       * SUID, SGID and LSM creds get determined differently under ptrace.
 +       */
 +      retval = mutex_lock_interruptible(&current->cred_exec_mutex);
 +      if (retval  < 0)
 +              goto out;
 +
 +      retval = -EPERM;
  repeat:
        /*
         * Nasty, nasty.
  bad:
        write_unlock_irqrestore(&tasklist_lock, flags);
        task_unlock(task);
 +      mutex_unlock(&current->cred_exec_mutex);
  out:
        return retval;
  }
@@@ -629,7 -612,7 +629,7 @@@ int generic_ptrace_pokedata(struct task
        return (copied == sizeof(data)) ? 0 : -EIO;
  }
  
- #if defined CONFIG_COMPAT && defined __ARCH_WANT_COMPAT_SYS_PTRACE
+ #if defined CONFIG_COMPAT
  #include <linux/compat.h>
  
  int compat_ptrace_request(struct task_struct *child, compat_long_t request,
@@@ -726,4 -709,4 +726,4 @@@ asmlinkage long compat_sys_ptrace(compa
        unlock_kernel();
        return ret;
  }
- #endif        /* CONFIG_COMPAT && __ARCH_WANT_COMPAT_SYS_PTRACE */
+ #endif        /* CONFIG_COMPAT */
diff --combined kernel/sched.c
index 204d0662b438a5831fa1578bab3ea119050c45bc,b7480fb5c3dc21a7bf6513a978cf0ed2e8c19a8f..993bc74a290cd4ef32af5e76730e63ab4928739f
@@@ -345,9 -345,7 +345,9 @@@ static inline struct task_group *task_g
        struct task_group *tg;
  
  #ifdef CONFIG_USER_SCHED
 -      tg = p->user->tg;
 +      rcu_read_lock();
 +      tg = __task_cred(p)->user->tg;
 +      rcu_read_unlock();
  #elif defined(CONFIG_CGROUP_SCHED)
        tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id),
                                struct task_group, css);
@@@ -1455,9 -1453,10 +1455,10 @@@ static int task_hot(struct task_struct 
  static unsigned long cpu_avg_load_per_task(int cpu)
  {
        struct rq *rq = cpu_rq(cpu);
+       unsigned long nr_running = ACCESS_ONCE(rq->nr_running);
  
-       if (rq->nr_running)
-               rq->avg_load_per_task = rq->load.weight / rq->nr_running;
+       if (nr_running)
+               rq->avg_load_per_task = rq->load.weight / nr_running;
        else
                rq->avg_load_per_task = 0;
  
@@@ -5135,22 -5134,6 +5136,22 @@@ __setscheduler(struct rq *rq, struct ta
        set_load_weight(p);
  }
  
 +/*
 + * check the target process has a UID that matches the current process's
 + */
 +static bool check_same_owner(struct task_struct *p)
 +{
 +      const struct cred *cred = current_cred(), *pcred;
 +      bool match;
 +
 +      rcu_read_lock();
 +      pcred = __task_cred(p);
 +      match = (cred->euid == pcred->euid ||
 +               cred->euid == pcred->uid);
 +      rcu_read_unlock();
 +      return match;
 +}
 +
  static int __sched_setscheduler(struct task_struct *p, int policy,
                                struct sched_param *param, bool user)
  {
@@@ -5210,7 -5193,8 +5211,7 @@@ recheck
                        return -EPERM;
  
                /* can't change other user's priorities */
 -              if ((current->euid != p->euid) &&
 -                  (current->euid != p->uid))
 +              if (!check_same_owner(p))
                        return -EPERM;
        }
  
@@@ -5442,7 -5426,8 +5443,7 @@@ long sched_setaffinity(pid_t pid, cons
        read_unlock(&tasklist_lock);
  
        retval = -EPERM;
 -      if ((current->euid != p->euid) && (current->euid != p->uid) &&
 -                      !capable(CAP_SYS_NICE))
 +      if (!check_same_owner(p) && !capable(CAP_SYS_NICE))
                goto out_unlock;
  
        retval = security_task_setscheduler(p, 0, NULL);
@@@ -7805,13 -7790,14 +7806,14 @@@ static int dattrs_equal(struct sched_do
   *
   * The passed in 'doms_new' should be kmalloc'd. This routine takes
   * ownership of it and will kfree it when done with it. If the caller
-  * failed the kmalloc call, then it can pass in doms_new == NULL,
-  * and partition_sched_domains() will fallback to the single partition
-  * 'fallback_doms', it also forces the domains to be rebuilt.
+  * failed the kmalloc call, then it can pass in doms_new == NULL &&
+  * ndoms_new == 1, and partition_sched_domains() will fallback to
+  * the single partition 'fallback_doms', it also forces the domains
+  * to be rebuilt.
   *
-  * If doms_new==NULL it will be replaced with cpu_online_map.
-  * ndoms_new==0 is a special case for destroying existing domains.
-  * It will not create the default domain.
+  * If doms_new == NULL it will be replaced with cpu_online_map.
+  * ndoms_new == 0 is a special case for destroying existing domains,
+  * and it will not create the default domain.
   *
   * Call with hotplug lock held
   */
diff --combined kernel/sysctl.c
index 511031381c330f91ffebb59b2ab14466ddb1fd26,3d56fe7570daede300fe01f2e6571416107b081b..9d52b57310af1fe953a8f86bdaf35d9ca88acbb7
@@@ -176,6 -176,9 +176,9 @@@ extern struct ctl_table random_table[]
  #ifdef CONFIG_INOTIFY_USER
  extern struct ctl_table inotify_table[];
  #endif
+ #ifdef CONFIG_EPOLL
+ extern struct ctl_table epoll_table[];
+ #endif
  
  #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
  int sysctl_legacy_va_layout;
@@@ -1325,6 -1328,13 +1328,13 @@@ static struct ctl_table fs_table[] = 
                .child          = inotify_table,
        },
  #endif        
+ #ifdef CONFIG_EPOLL
+       {
+               .procname       = "epoll",
+               .mode           = 0555,
+               .child          = epoll_table,
+       },
+ #endif
  #endif
        {
                .ctl_name       = KERN_SETUID_DUMPABLE,
@@@ -1641,7 -1651,7 +1651,7 @@@ out
  
  static int test_perm(int mode, int op)
  {
 -      if (!current->euid)
 +      if (!current_euid())
                mode >>= 6;
        else if (in_egroup_p(0))
                mode >>= 3;
diff --combined kernel/trace/trace.c
index ffe7c96fa09be9f11a8b995b7acb0822f6e83cda,d86e3252f3000024cfaf31c63ffbee765dafac53..1ee9e4e454a0cded40ffc8f66d799c2e1ef1a2bf
@@@ -246,7 -246,7 +246,7 @@@ __update_max_tr(struct trace_array *tr
  
        memcpy(data->comm, tsk->comm, TASK_COMM_LEN);
        data->pid = tsk->pid;
 -      data->uid = tsk->uid;
 +      data->uid = task_uid(tsk);
        data->nice = tsk->static_prio - 20 - MAX_RT_PRIO;
        data->policy = tsk->policy;
        data->rt_priority = tsk->rt_priority;
@@@ -1936,6 -1936,7 +1936,7 @@@ __tracing_open(struct inode *inode, str
                        ring_buffer_read_finish(iter->buffer_iter[cpu]);
        }
        mutex_unlock(&trace_types_lock);
+       kfree(iter);
  
        return ERR_PTR(-ENOMEM);
  }
diff --combined mm/migrate.c
index 9dd10da1cc23f34c026ce2822bf5f23416576bc0,1e0d6b237f4418c2f8b8ca50e88d85a787adc0a7..0461fc6c961cb841d4cce06287704cc9d3858a58
@@@ -522,15 -522,12 +522,12 @@@ static int writeout(struct address_spac
        remove_migration_ptes(page, page);
  
        rc = mapping->a_ops->writepage(page, &wbc);
-       if (rc < 0)
-               /* I/O Error writing */
-               return -EIO;
  
        if (rc != AOP_WRITEPAGE_ACTIVATE)
                /* unlocked. Relock */
                lock_page(page);
  
-       return -EAGAIN;
+       return (rc < 0) ? -EIO : -EAGAIN;
  }
  
  /*
@@@ -1045,7 -1042,6 +1042,7 @@@ asmlinkage long sys_move_pages(pid_t pi
                        const int __user *nodes,
                        int __user *status, int flags)
  {
 +      const struct cred *cred = current_cred(), *tcred;
        struct task_struct *task;
        struct mm_struct *mm;
        int err;
         * capabilities, superuser privileges or the same
         * userid as the target process.
         */
 -      if ((current->euid != task->suid) && (current->euid != task->uid) &&
 -          (current->uid != task->suid) && (current->uid != task->uid) &&
 +      rcu_read_lock();
 +      tcred = __task_cred(task);
 +      if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
 +          cred->uid  != tcred->suid && cred->uid  != tcred->uid &&
            !capable(CAP_SYS_NICE)) {
 +              rcu_read_unlock();
                err = -EPERM;
                goto out;
        }
 +      rcu_read_unlock();
  
        err = security_task_movememory(task);
        if (err)
diff --combined net/rose/af_rose.c
index d902e2da27824e4631be8cc03b82204acc380dc7,0c1cc76128006e81d39b663f994de9e78f8539f5..01392649b4626d930eaba64175a5e50f1dc1f57c
@@@ -690,7 -690,7 +690,7 @@@ static int rose_bind(struct socket *soc
  
        source = &addr->srose_call;
  
 -      user = ax25_findbyuid(current->euid);
 +      user = ax25_findbyuid(current_euid());
        if (user) {
                rose->source_call = user->call;
                ax25_uid_put(user);
@@@ -791,7 -791,7 +791,7 @@@ static int rose_connect(struct socket *
                        goto out_release;
                }
  
 -              user = ax25_findbyuid(current->euid);
 +              user = ax25_findbyuid(current_euid());
                if (!user) {
                        err = -EINVAL;
                        goto out_release;
@@@ -1072,6 -1072,10 +1072,10 @@@ static int rose_sendmsg(struct kiocb *i
        unsigned char *asmptr;
        int n, size, qbit = 0;
  
+       /* ROSE empty frame has no meaning : don't send */
+       if (len == 0)
+               return 0;
        if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
                return -EINVAL;
  
@@@ -1265,6 -1269,12 +1269,12 @@@ static int rose_recvmsg(struct kiocb *i
        skb_reset_transport_header(skb);
        copied     = skb->len;
  
+       /* ROSE empty frame has no meaning : ignore it */
+       if (copied == 0) {
+               skb_free_datagram(sk, skb);
+               return copied;
+       }
        if (copied > size) {
                copied = size;
                msg->msg_flags |= MSG_TRUNC;
diff --combined net/socket.c
index 62c7729527ff916447623a40d4966f7ba24663f1,92764d836891833e1cb7f8255a38edacad1f3b7f..b7a562e655e9c01dc2780fbe1aeb0c6245b49c7c
@@@ -491,8 -491,8 +491,8 @@@ static struct socket *sock_alloc(void
        sock = SOCKET_I(inode);
  
        inode->i_mode = S_IFSOCK | S_IRWXUGO;
 -      inode->i_uid = current->fsuid;
 -      inode->i_gid = current->fsgid;
 +      inode->i_uid = current_fsuid();
 +      inode->i_gid = current_fsgid();
  
        get_cpu_var(sockets_in_use)++;
        put_cpu_var(sockets_in_use);
@@@ -1426,8 -1426,8 +1426,8 @@@ asmlinkage long sys_listen(int fd, int 
   *    clean when we restucture accept also.
   */
  
long do_accept(int fd, struct sockaddr __user *upeer_sockaddr,
-              int __user *upeer_addrlen, int flags)
asmlinkage long sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
+                           int __user *upeer_addrlen, int flags)
  {
        struct socket *sock, *newsock;
        struct file *newfile;
@@@ -1510,66 -1510,10 +1510,10 @@@ out_fd
        goto out_put;
  }
  
- #if 0
- #ifdef HAVE_SET_RESTORE_SIGMASK
- asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
-                           int __user *upeer_addrlen,
-                           const sigset_t __user *sigmask,
-                           size_t sigsetsize, int flags)
- {
-       sigset_t ksigmask, sigsaved;
-       int ret;
-       if (sigmask) {
-               /* XXX: Don't preclude handling different sized sigset_t's.  */
-               if (sigsetsize != sizeof(sigset_t))
-                       return -EINVAL;
-               if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
-                       return -EFAULT;
-               sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
-               sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
-         }
-       ret = do_accept(fd, upeer_sockaddr, upeer_addrlen, flags);
-       if (ret < 0 && signal_pending(current)) {
-               /*
-                * Don't restore the signal mask yet. Let do_signal() deliver
-                * the signal on the way back to userspace, before the signal
-                * mask is restored.
-                */
-               if (sigmask) {
-                       memcpy(&current->saved_sigmask, &sigsaved,
-                              sizeof(sigsaved));
-                       set_restore_sigmask();
-               }
-       } else if (sigmask)
-               sigprocmask(SIG_SETMASK, &sigsaved, NULL);
-       return ret;
- }
- #else
- asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
-                           int __user *upeer_addrlen,
-                           const sigset_t __user *sigmask,
-                           size_t sigsetsize, int flags)
- {
-       /* The platform does not support restoring the signal mask in the
-        * return path.  So we do not allow using paccept() with a signal
-        * mask.  */
-       if (sigmask)
-               return -EINVAL;
-       return do_accept(fd, upeer_sockaddr, upeer_addrlen, flags);
- }
- #endif
- #endif
  asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
                           int __user *upeer_addrlen)
  {
-       return do_accept(fd, upeer_sockaddr, upeer_addrlen, 0);
+       return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
  }
  
  /*
@@@ -2096,7 -2040,7 +2040,7 @@@ static const unsigned char nargs[19]=
        AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
        AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
        AL(6),AL(2),AL(5),AL(5),AL(3),AL(3),
-       AL(6)
+       AL(4)
  };
  
  #undef AL
@@@ -2115,7 -2059,7 +2059,7 @@@ asmlinkage long sys_socketcall(int call
        unsigned long a0, a1;
        int err;
  
-       if (call < 1 || call > SYS_PACCEPT)
+       if (call < 1 || call > SYS_ACCEPT4)
                return -EINVAL;
  
        /* copy_from_user should be SMP safe. */
                err = sys_listen(a0, a1);
                break;
        case SYS_ACCEPT:
-               err =
-                   do_accept(a0, (struct sockaddr __user *)a1,
-                             (int __user *)a[2], 0);
+               err = sys_accept4(a0, (struct sockaddr __user *)a1,
+                                 (int __user *)a[2], 0);
                break;
        case SYS_GETSOCKNAME:
                err =
        case SYS_RECVMSG:
                err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
                break;
-       case SYS_PACCEPT:
-               err =
-                   sys_paccept(a0, (struct sockaddr __user *)a1,
-                               (int __user *)a[2],
-                               (const sigset_t __user *) a[3],
-                               a[4], a[5]);
+       case SYS_ACCEPT4:
+               err = sys_accept4(a0, (struct sockaddr __user *)a1,
+                                 (int __user *)a[2], a[3]);
                break;
        default:
                err = -EINVAL;
diff --combined net/unix/af_unix.c
index 2775acbca199c9a4482d1ffa8df7c4dc59083038,66d5ac4773abac12f517c84b25916dc078cda007..b152e2b9b9888792700a0a1daf784f232a75aa6c
@@@ -467,7 -467,8 +467,7 @@@ static int unix_listen(struct socket *s
        sk->sk_state            = TCP_LISTEN;
        /* set credentials so connect can copy them */
        sk->sk_peercred.pid     = task_tgid_vnr(current);
 -      sk->sk_peercred.uid     = current->euid;
 -      sk->sk_peercred.gid     = current->egid;
 +      current_euid_egid(&sk->sk_peercred.uid, &sk->sk_peercred.gid);
        err = 0;
  
  out_unlock:
@@@ -1125,7 -1126,8 +1125,7 @@@ restart
        newsk->sk_state         = TCP_ESTABLISHED;
        newsk->sk_type          = sk->sk_type;
        newsk->sk_peercred.pid  = task_tgid_vnr(current);
 -      newsk->sk_peercred.uid  = current->euid;
 -      newsk->sk_peercred.gid  = current->egid;
 +      current_euid_egid(&newsk->sk_peercred.uid, &newsk->sk_peercred.gid);
        newu = unix_sk(newsk);
        newsk->sk_sleep         = &newu->peer_wait;
        otheru = unix_sk(other);
@@@ -1185,9 -1187,8 +1185,9 @@@ static int unix_socketpair(struct socke
        unix_peer(ska)=skb;
        unix_peer(skb)=ska;
        ska->sk_peercred.pid = skb->sk_peercred.pid = task_tgid_vnr(current);
 -      ska->sk_peercred.uid = skb->sk_peercred.uid = current->euid;
 -      ska->sk_peercred.gid = skb->sk_peercred.gid = current->egid;
 +      current_euid_egid(&skb->sk_peercred.uid, &skb->sk_peercred.gid);
 +      ska->sk_peercred.uid = skb->sk_peercred.uid;
 +      ska->sk_peercred.gid = skb->sk_peercred.gid;
  
        if (ska->sk_type != SOCK_DGRAM) {
                ska->sk_state = TCP_ESTABLISHED;
@@@ -1342,6 -1343,7 +1342,7 @@@ static int unix_dgram_sendmsg(struct ki
  
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
+       wait_for_unix_gc();
        err = scm_send(sock, msg, siocb->scm);
        if (err < 0)
                return err;
@@@ -1492,6 -1494,7 +1493,7 @@@ static int unix_stream_sendmsg(struct k
  
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
+       wait_for_unix_gc();
        err = scm_send(sock, msg, siocb->scm);
        if (err < 0)
                return err;