Merge branch 'stable-3.2' into pandora-3.2
authorGrazvydas Ignotas <notasas@gmail.com>
Sat, 16 Sep 2017 19:23:33 +0000 (22:23 +0300)
committerGrazvydas Ignotas <notasas@gmail.com>
Sat, 16 Sep 2017 19:23:33 +0000 (22:23 +0300)
1  2 
drivers/usb/gadget/f_mass_storage.c
fs/autofs4/dev-ioctl.c
fs/cifs/cifssmb.c
fs/proc/base.c
kernel/signal.c
security/commoncap.c

@@@ -512,7 -512,11 +512,11 @@@ static int fsg_set_halt(struct fsg_dev 
  /* Caller must hold fsg->lock */
  static void wakeup_thread(struct fsg_common *common)
  {
-       smp_wmb();      /* ensure the write of bh->state is complete */
+       /*
+        * Ensure the reading of thread_wakeup_needed
+        * and the writing of bh->state are completed
+        */
+       smp_mb();
        /* Tell the main thread that something has happened */
        common->thread_wakeup_needed = 1;
        if (common->thread_task)
@@@ -732,7 -736,12 +736,12 @@@ static int sleep_thread(struct fsg_comm
        }
        __set_current_state(TASK_RUNNING);
        common->thread_wakeup_needed = 0;
-       smp_rmb();      /* ensure the latest bh->state is visible */
+       /*
+        * Ensure the writing of thread_wakeup_needed
+        * and the reading of bh->state are completed
+        */
+       smp_mb();
        return rc;
  }
  
@@@ -3113,15 -3122,15 +3122,15 @@@ fsg_add(struct usb_composite_dev *cdev
  
  struct fsg_module_parameters {
        char            *file[FSG_MAX_LUNS];
 -      int             ro[FSG_MAX_LUNS];
 -      int             removable[FSG_MAX_LUNS];
 -      int             cdrom[FSG_MAX_LUNS];
 -      int             nofua[FSG_MAX_LUNS];
 +      bool            ro[FSG_MAX_LUNS];
 +      bool            removable[FSG_MAX_LUNS];
 +      bool            cdrom[FSG_MAX_LUNS];
 +      bool            nofua[FSG_MAX_LUNS];
  
        unsigned int    file_count, ro_count, removable_count, cdrom_count;
        unsigned int    nofua_count;
        unsigned int    luns;   /* nluns */
 -      int             stall;  /* can_stall */
 +      bool            stall;  /* can_stall */
  };
  
  #define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc)     \
diff --combined fs/autofs4/dev-ioctl.c
@@@ -237,7 -237,7 +237,7 @@@ static void autofs_dev_ioctl_fd_install
        fdt = files_fdtable(files);
        BUG_ON(fdt->fd[fd] != NULL);
        rcu_assign_pointer(fdt->fd[fd], file);
 -      FD_SET(fd, fdt->close_on_exec);
 +      __set_close_on_exec(fd, fdt);
        spin_unlock(&files->file_lock);
  }
  
@@@ -345,7 -345,7 +345,7 @@@ static int autofs_dev_ioctl_fail(struc
        int status;
  
        token = (autofs_wqt_t) param->fail.token;
-       status = param->fail.status ? param->fail.status : -ENOENT;
+       status = param->fail.status < 0 ? param->fail.status : -ENOENT;
        return autofs4_wait_release(sbi, token, status);
  }
  
diff --combined fs/cifs/cifssmb.c
@@@ -764,6 -764,9 +764,9 @@@ CIFSSMBEcho(struct TCP_Server_Info *ser
        if (rc)
                return rc;
  
+       if (server->capabilities & CAP_UNICODE)
+               smb->hdr.Flags2 |= SMBFLG2_UNICODE;
        /* set up echo request */
        smb->hdr.Tid = 0xffff;
        smb->hdr.WordCount = 1;
@@@ -3906,12 -3909,13 +3909,12 @@@ CIFSSMBSetCIFSACL(const int xid, struc
        int rc = 0;
        int bytes_returned = 0;
        SET_SEC_DESC_REQ *pSMB = NULL;
 -      NTRANSACT_RSP *pSMBr = NULL;
 +      void *pSMBr;
  
  setCifsAclRetry:
 -      rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB,
 -                      (void **) &pSMBr);
 +      rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
        if (rc)
 -                      return (rc);
 +              return rc;
  
        pSMB->MaxSetupCount = 0;
        pSMB->Reserved = 0;
        pSMB->AclFlags = cpu_to_le32(aclflag);
  
        if (pntsd && acllen) {
 -              memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
 -                      (char *) pntsd,
 -                      acllen);
 +              memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
 +                              data_offset, pntsd, acllen);
                inc_rfc1001_len(pSMB, byte_count + data_count);
        } else
                inc_rfc1001_len(pSMB, byte_count);
@@@ -5719,8 -5724,7 +5722,8 @@@ CIFSSMBSetFileInfo(const int xid, struc
        param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
        offset = param_offset + params;
  
 -      data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
 +      data_offset = (char *)pSMB +
 +                      offsetof(struct smb_hdr, Protocol) + offset;
  
        count = sizeof(FILE_BASIC_INFO);
        pSMB->MaxParameterCount = cpu_to_le16(2);
@@@ -5989,7 -5993,7 +5992,7 @@@ CIFSSMBUnixSetFileInfo(const int xid, s
                       u16 fid, u32 pid_of_opener)
  {
        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
 -      FILE_UNIX_BASIC_INFO *data_offset;
 +      char *data_offset;
        int rc = 0;
        u16 params, param_offset, offset, byte_count, count;
  
        param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
        offset = param_offset + params;
  
 -      data_offset = (FILE_UNIX_BASIC_INFO *)
 -                              ((char *)(&pSMB->hdr.Protocol) + offset);
 +      data_offset = (char *)pSMB +
 +                      offsetof(struct smb_hdr, Protocol) + offset;
 +
        count = sizeof(FILE_UNIX_BASIC_INFO);
  
        pSMB->MaxParameterCount = cpu_to_le16(2);
        inc_rfc1001_len(pSMB, byte_count);
        pSMB->ByteCount = cpu_to_le16(byte_count);
  
 -      cifs_fill_unix_set_info(data_offset, args);
 +      cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
  
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        if (rc)
diff --combined fs/proc/base.c
@@@ -216,7 -216,7 +216,7 @@@ static struct mm_struct *mm_access(stru
  
  struct mm_struct *mm_for_maps(struct task_struct *task)
  {
-       return mm_access(task, PTRACE_MODE_READ);
+       return mm_access(task, PTRACE_MODE_READ_FSCREDS);
  }
  
  static int proc_pid_cmdline(struct task_struct *task, char * buffer)
@@@ -288,7 -288,7 +288,7 @@@ static int proc_pid_wchan(struct task_s
        wchan = get_wchan(task);
  
        if (lookup_symbol_name(wchan, symname) < 0)
-               if (!ptrace_may_access(task, PTRACE_MODE_READ))
+               if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
                        return 0;
                else
                        return sprintf(buffer, "%lu", wchan);
@@@ -302,7 -302,7 +302,7 @@@ static int lock_trace(struct task_struc
        int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
        if (err)
                return err;
-       if (!ptrace_may_access(task, PTRACE_MODE_ATTACH)) {
+       if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
                mutex_unlock(&task->signal->cred_guard_mutex);
                return -EPERM;
        }
@@@ -544,7 -544,7 +544,7 @@@ static int proc_fd_access_allowed(struc
         */
        task = get_proc_task(inode);
        if (task) {
-               allowed = ptrace_may_access(task, PTRACE_MODE_READ);
+               allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
                put_task_struct(task);
        }
        return allowed;
@@@ -769,7 -769,7 +769,7 @@@ static int mem_open(struct inode* inode
        if (!task)
                return -ESRCH;
  
-       mm = mm_access(task, PTRACE_MODE_ATTACH);
+       mm = mm_access(task, PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS);
        put_task_struct(task);
  
        if (IS_ERR(mm))
@@@ -1831,7 -1831,7 +1831,7 @@@ static int proc_fd_info(struct inode *i
  
                        fdt = files_fdtable(files);
                        f_flags = file->f_flags & ~O_CLOEXEC;
 -                      if (FD_ISSET(fd, fdt->close_on_exec))
 +                      if (close_on_exec(fd, fdt))
                                f_flags |= O_CLOEXEC;
  
                        if (path) {
@@@ -2627,7 -2627,7 +2627,7 @@@ static int do_io_accounting(struct task
        if (result)
                return result;
  
-       if (!ptrace_may_access(task, PTRACE_MODE_READ)) {
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
                result = -EACCES;
                goto out_unlock;
        }
@@@ -2716,7 -2716,6 +2716,7 @@@ static const struct pid_entry tgid_base
        ONE("stat",       S_IRUGO, proc_tgid_stat),
        ONE("statm",      S_IRUGO, proc_pid_statm),
        REG("maps",       S_IRUGO, proc_maps_operations),
 +      REG("arm_maps",   S_IRUGO, proc_armv7_maps_operations),
  #ifdef CONFIG_NUMA
        REG("numa_maps",  S_IRUGO, proc_numa_maps_operations),
  #endif
@@@ -3063,7 -3062,6 +3063,7 @@@ static const struct pid_entry tid_base_
        ONE("stat",      S_IRUGO, proc_tid_stat),
        ONE("statm",     S_IRUGO, proc_pid_statm),
        REG("maps",      S_IRUGO, proc_maps_operations),
 +      REG("arm_maps",  S_IRUGO, proc_armv7_maps_operations),
  #ifdef CONFIG_NUMA
        REG("numa_maps", S_IRUGO, proc_numa_maps_operations),
  #endif
diff --combined kernel/signal.c
@@@ -535,7 -535,8 +535,8 @@@ unblock_all_signals(void
        spin_unlock_irqrestore(&current->sighand->siglock, flags);
  }
  
- static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
+ static void collect_signal(int sig, struct sigpending *list, siginfo_t *info,
+                          bool *resched_timer)
  {
        struct sigqueue *q, *first = NULL;
  
  still_pending:
                list_del_init(&first->list);
                copy_siginfo(info, &first->info);
+               *resched_timer =
+                       (first->flags & SIGQUEUE_PREALLOC) &&
+                       (info->si_code == SI_TIMER) &&
+                       (info->si_sys_private);
                __sigqueue_free(first);
        } else {
                /*
  }
  
  static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
-                       siginfo_t *info)
+                       siginfo_t *info, bool *resched_timer)
  {
        int sig = next_signal(pending, mask);
  
                        }
                }
  
-               collect_signal(sig, pending, info);
+               collect_signal(sig, pending, info, resched_timer);
        }
  
        return sig;
   */
  int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
  {
+       bool resched_timer = false;
        int signr;
  
        /* We only dequeue private signals from ourselves, we don't let
         * signalfd steal them
         */
-       signr = __dequeue_signal(&tsk->pending, mask, info);
+       signr = __dequeue_signal(&tsk->pending, mask, info, &resched_timer);
        if (!signr) {
                signr = __dequeue_signal(&tsk->signal->shared_pending,
-                                        mask, info);
+                                        mask, info, &resched_timer);
                /*
                 * itimer signal ?
                 *
                 */
                current->jobctl |= JOBCTL_STOP_DEQUEUED;
        }
-       if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) {
+       if (resched_timer) {
                /*
                 * Release the siglock to ensure proper locking order
                 * of timer locks outside of siglocks.  Note, we leave
@@@ -1270,7 -1278,6 +1278,7 @@@ struct sighand_struct *__lock_task_sigh
  
        return sighand;
  }
 +EXPORT_SYMBOL_GPL(__lock_task_sighand);
  
  /*
   * send signal info to all the members of a group
diff --combined security/commoncap.c
@@@ -141,12 -141,17 +141,17 @@@ int cap_ptrace_access_check(struct task
  {
        int ret = 0;
        const struct cred *cred, *child_cred;
+       const kernel_cap_t *caller_caps;
  
        rcu_read_lock();
        cred = current_cred();
        child_cred = __task_cred(child);
+       if (mode & PTRACE_MODE_FSCREDS)
+               caller_caps = &cred->cap_effective;
+       else
+               caller_caps = &cred->cap_permitted;
        if (cred->user->user_ns == child_cred->user->user_ns &&
-           cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
+           cap_issubset(child_cred->cap_permitted, *caller_caps))
                goto out;
        if (ns_capable(child_cred->user->user_ns, CAP_SYS_PTRACE))
                goto out;
@@@ -981,4 -986,3 +986,4 @@@ int cap_file_mmap(struct file *file, un
        }
        return ret;
  }
 +EXPORT_SYMBOL(cap_file_mmap);