Commit 8371e5a0 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'char-misc-4.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc fixes from Greg KH:
 "Here are six small fixes of some of the char/misc drivers that have
  been sent in to resolve reported issues.

  Nothing major, a binder use-after-free fix, some thunderbolt bugfixes,
  a hyper-v bugfix, and an nvmem driver fix. All of these have been in
  linux-next with no reported issues for a while"

* tag 'char-misc-4.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  nvmem: meson-mx-efuse: fix reading from an offset other than 0
  binder: fix proc->files use-after-free
  vmbus: unregister device_obj->channels_kset
  thunderbolt: Mask ring interrupt properly when polling starts
  MAINTAINERS: Add thunderbolt.rst to the Thunderbolt driver entry
  thunderbolt: Make pathname to force_power shorter
parents 4288e6b4 8a42d3fc
...@@ -230,7 +230,7 @@ If supported by your machine this will be exposed by the WMI bus with ...@@ -230,7 +230,7 @@ If supported by your machine this will be exposed by the WMI bus with
a sysfs attribute called "force_power". a sysfs attribute called "force_power".
For example the intel-wmi-thunderbolt driver exposes this attribute in: For example the intel-wmi-thunderbolt driver exposes this attribute in:
/sys/devices/platform/PNP0C14:00/wmi_bus/wmi_bus-PNP0C14:00/86CCFD48-205E-4A77-9C48-2021CBEDE341/force_power /sys/bus/wmi/devices/86CCFD48-205E-4A77-9C48-2021CBEDE341/force_power
To force the power to on, write 1 to this attribute file. To force the power to on, write 1 to this attribute file.
To disable force power, write 0 to this attribute file. To disable force power, write 0 to this attribute file.
......
...@@ -13491,6 +13491,7 @@ M: Mika Westerberg <mika.westerberg@linux.intel.com> ...@@ -13491,6 +13491,7 @@ M: Mika Westerberg <mika.westerberg@linux.intel.com>
M: Yehezkel Bernat <yehezkel.bernat@intel.com> M: Yehezkel Bernat <yehezkel.bernat@intel.com>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git
S: Maintained S: Maintained
F: Documentation/admin-guide/thunderbolt.rst
F: drivers/thunderbolt/ F: drivers/thunderbolt/
F: include/linux/thunderbolt.h F: include/linux/thunderbolt.h
......
...@@ -482,7 +482,8 @@ enum binder_deferred_state { ...@@ -482,7 +482,8 @@ enum binder_deferred_state {
* @tsk task_struct for group_leader of process * @tsk task_struct for group_leader of process
* (invariant after initialized) * (invariant after initialized)
* @files files_struct for process * @files files_struct for process
* (invariant after initialized) * (protected by @files_lock)
* @files_lock mutex to protect @files
* @deferred_work_node: element for binder_deferred_list * @deferred_work_node: element for binder_deferred_list
* (protected by binder_deferred_lock) * (protected by binder_deferred_lock)
* @deferred_work: bitmap of deferred work to perform * @deferred_work: bitmap of deferred work to perform
...@@ -530,6 +531,7 @@ struct binder_proc { ...@@ -530,6 +531,7 @@ struct binder_proc {
int pid; int pid;
struct task_struct *tsk; struct task_struct *tsk;
struct files_struct *files; struct files_struct *files;
struct mutex files_lock;
struct hlist_node deferred_work_node; struct hlist_node deferred_work_node;
int deferred_work; int deferred_work;
bool is_dead; bool is_dead;
...@@ -877,20 +879,26 @@ static void binder_inc_node_tmpref_ilocked(struct binder_node *node); ...@@ -877,20 +879,26 @@ static void binder_inc_node_tmpref_ilocked(struct binder_node *node);
static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
{ {
struct files_struct *files = proc->files;
unsigned long rlim_cur; unsigned long rlim_cur;
unsigned long irqs; unsigned long irqs;
int ret;
if (files == NULL) mutex_lock(&proc->files_lock);
return -ESRCH; if (proc->files == NULL) {
ret = -ESRCH;
if (!lock_task_sighand(proc->tsk, &irqs)) goto err;
return -EMFILE; }
if (!lock_task_sighand(proc->tsk, &irqs)) {
ret = -EMFILE;
goto err;
}
rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE); rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE);
unlock_task_sighand(proc->tsk, &irqs); unlock_task_sighand(proc->tsk, &irqs);
return __alloc_fd(files, 0, rlim_cur, flags); ret = __alloc_fd(proc->files, 0, rlim_cur, flags);
err:
mutex_unlock(&proc->files_lock);
return ret;
} }
/* /*
...@@ -899,8 +907,10 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) ...@@ -899,8 +907,10 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
static void task_fd_install( static void task_fd_install(
struct binder_proc *proc, unsigned int fd, struct file *file) struct binder_proc *proc, unsigned int fd, struct file *file)
{ {
mutex_lock(&proc->files_lock);
if (proc->files) if (proc->files)
__fd_install(proc->files, fd, file); __fd_install(proc->files, fd, file);
mutex_unlock(&proc->files_lock);
} }
/* /*
...@@ -910,9 +920,11 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd) ...@@ -910,9 +920,11 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd)
{ {
int retval; int retval;
if (proc->files == NULL) mutex_lock(&proc->files_lock);
return -ESRCH; if (proc->files == NULL) {
retval = -ESRCH;
goto err;
}
retval = __close_fd(proc->files, fd); retval = __close_fd(proc->files, fd);
/* can't restart close syscall because file table entry was cleared */ /* can't restart close syscall because file table entry was cleared */
if (unlikely(retval == -ERESTARTSYS || if (unlikely(retval == -ERESTARTSYS ||
...@@ -920,7 +932,8 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd) ...@@ -920,7 +932,8 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd)
retval == -ERESTARTNOHAND || retval == -ERESTARTNOHAND ||
retval == -ERESTART_RESTARTBLOCK)) retval == -ERESTART_RESTARTBLOCK))
retval = -EINTR; retval = -EINTR;
err:
mutex_unlock(&proc->files_lock);
return retval; return retval;
} }
...@@ -4627,7 +4640,9 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -4627,7 +4640,9 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
ret = binder_alloc_mmap_handler(&proc->alloc, vma); ret = binder_alloc_mmap_handler(&proc->alloc, vma);
if (ret) if (ret)
return ret; return ret;
mutex_lock(&proc->files_lock);
proc->files = get_files_struct(current); proc->files = get_files_struct(current);
mutex_unlock(&proc->files_lock);
return 0; return 0;
err_bad_arg: err_bad_arg:
...@@ -4651,6 +4666,7 @@ static int binder_open(struct inode *nodp, struct file *filp) ...@@ -4651,6 +4666,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
spin_lock_init(&proc->outer_lock); spin_lock_init(&proc->outer_lock);
get_task_struct(current->group_leader); get_task_struct(current->group_leader);
proc->tsk = current->group_leader; proc->tsk = current->group_leader;
mutex_init(&proc->files_lock);
INIT_LIST_HEAD(&proc->todo); INIT_LIST_HEAD(&proc->todo);
proc->default_priority = task_nice(current); proc->default_priority = task_nice(current);
binder_dev = container_of(filp->private_data, struct binder_device, binder_dev = container_of(filp->private_data, struct binder_device,
...@@ -4903,9 +4919,11 @@ static void binder_deferred_func(struct work_struct *work) ...@@ -4903,9 +4919,11 @@ static void binder_deferred_func(struct work_struct *work)
files = NULL; files = NULL;
if (defer & BINDER_DEFERRED_PUT_FILES) { if (defer & BINDER_DEFERRED_PUT_FILES) {
mutex_lock(&proc->files_lock);
files = proc->files; files = proc->files;
if (files) if (files)
proc->files = NULL; proc->files = NULL;
mutex_unlock(&proc->files_lock);
} }
if (defer & BINDER_DEFERRED_FLUSH) if (defer & BINDER_DEFERRED_FLUSH)
......
...@@ -1378,6 +1378,8 @@ void vmbus_device_unregister(struct hv_device *device_obj) ...@@ -1378,6 +1378,8 @@ void vmbus_device_unregister(struct hv_device *device_obj)
pr_debug("child device %s unregistered\n", pr_debug("child device %s unregistered\n",
dev_name(&device_obj->device)); dev_name(&device_obj->device));
kset_unregister(device_obj->channels_kset);
/* /*
* Kick off the process of unregistering the device. * Kick off the process of unregistering the device.
* This will call vmbus_remove() and eventually vmbus_device_release() * This will call vmbus_remove() and eventually vmbus_device_release()
......
...@@ -156,8 +156,8 @@ static int meson_mx_efuse_read(void *context, unsigned int offset, ...@@ -156,8 +156,8 @@ static int meson_mx_efuse_read(void *context, unsigned int offset,
MESON_MX_EFUSE_CNTL1_AUTO_RD_ENABLE, MESON_MX_EFUSE_CNTL1_AUTO_RD_ENABLE,
MESON_MX_EFUSE_CNTL1_AUTO_RD_ENABLE); MESON_MX_EFUSE_CNTL1_AUTO_RD_ENABLE);
for (i = offset; i < offset + bytes; i += efuse->config.word_size) { for (i = 0; i < bytes; i += efuse->config.word_size) {
addr = i / efuse->config.word_size; addr = (offset + i) / efuse->config.word_size;
err = meson_mx_efuse_read_addr(efuse, addr, &tmp); err = meson_mx_efuse_read_addr(efuse, addr, &tmp);
if (err) if (err)
......
...@@ -339,7 +339,7 @@ static void __ring_interrupt(struct tb_ring *ring) ...@@ -339,7 +339,7 @@ static void __ring_interrupt(struct tb_ring *ring)
return; return;
if (ring->start_poll) { if (ring->start_poll) {
__ring_interrupt_mask(ring, false); __ring_interrupt_mask(ring, true);
ring->start_poll(ring->poll_data); ring->start_poll(ring->poll_data);
} else { } else {
schedule_work(&ring->work); schedule_work(&ring->work);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment