bprm->cred->euid = current_euid();
        bprm->cred->egid = current_egid();
  
 -      if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) {
 +      if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) &&
 +          !current->no_new_privs) {
                /* Set-uid? */
                if (mode & S_ISUID) {
+                       if (!kuid_has_mapping(bprm->cred->user_ns, inode->i_uid))
+                               return -EPERM;
                        bprm->per_clear |= PER_CLEAR_ON_SETID;
                        bprm->cred->euid = inode->i_uid;
+ 
                }
  
                /* Set-gid? */
 
  {
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        const struct mount_opts *m;
+       kuid_t uid;
+       kgid_t gid;
        int arg = 0;
  
 +#ifdef CONFIG_QUOTA
 +      if (token == Opt_usrjquota)
 +              return set_qf_name(sb, USRQUOTA, &args[0]);
 +      else if (token == Opt_grpjquota)
 +              return set_qf_name(sb, GRPQUOTA, &args[0]);
 +      else if (token == Opt_offusrjquota)
 +              return clear_qf_name(sb, USRQUOTA);
 +      else if (token == Opt_offgrpjquota)
 +              return clear_qf_name(sb, GRPQUOTA);
 +#endif
        if (args->from && match_int(args, &arg))
                return -1;
        switch (token) {
 
                                        inode->i_gid = cred->egid;
                                        rcu_read_unlock();
                                } else {
-                                       inode->i_uid = 0;
-                                       inode->i_gid = 0;
+                                       inode->i_uid = GLOBAL_ROOT_UID;
+                                       inode->i_gid = GLOBAL_ROOT_GID;
                                }
 -                              inode->i_mode &= ~(S_ISUID | S_ISGID);
 +
 +                              i_mode = S_IFLNK;
 +                              if (f_mode & FMODE_READ)
 +                                      i_mode |= S_IRUSR | S_IXUSR;
 +                              if (f_mode & FMODE_WRITE)
 +                                      i_mode |= S_IWUSR | S_IXUSR;
 +                              inode->i_mode = i_mode;
 +
                                security_task_to_inode(task, inode);
                                put_task_struct(task);
                                return 1;
 
        tmp.st_nlink = stat->nlink;
        if (tmp.st_nlink != stat->nlink)
                return -EOVERFLOW;
-       SET_UID(tmp.st_uid, stat->uid);
-       SET_GID(tmp.st_gid, stat->gid);
+       SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
+       SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
 -#if BITS_PER_LONG == 32
 -      tmp.st_rdev = old_encode_dev(stat->rdev);
 -#else
 -      tmp.st_rdev = new_encode_dev(stat->rdev);
 -#endif
 -#if BITS_PER_LONG == 32
 -      if (stat->size > MAX_NON_LFS)
 -              return -EOVERFLOW;
 -#endif        
 +      tmp.st_rdev = encode_dev(stat->rdev);
        tmp.st_size = stat->size;
        tmp.st_atime = stat->atime.tv_sec;
        tmp.st_mtime = stat->mtime.tv_sec;
 
        }
  skip:
  
 +      /* if we have fs caps, clear dangerous personality flags */
 +      if (!cap_issubset(new->cap_permitted, old->cap_permitted))
 +              bprm->per_clear |= PER_CLEAR_ON_SETID;
 +
 +
        /* Don't let someone trace a set[ug]id/setpcap binary with the revised
 -       * credentials unless they have the appropriate permit
 +       * credentials unless they have the appropriate permit.
 +       *
 +       * In addition, if NO_NEW_PRIVS, then ensure we get no new privs.
         */
-       if ((new->euid != old->uid ||
-            new->egid != old->gid ||
+       if ((!uid_eq(new->euid, old->uid) ||
+            !gid_eq(new->egid, old->gid) ||
             !cap_issubset(new->cap_permitted, old->cap_permitted)) &&
            bprm->unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
                /* downgrade; they get no more than they had, and maybe less */