Commit 3a98be09 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull char/misc fixes from Greg KH:
 "Here are a handful of char/misc driver fixes for 4.14-rc4.

  Nothing major, some binder fixups, hyperv fixes, and other tiny
  things.

  All of these have been sitting in my tree for way too long, sorry for
  the delay in getting them to you. All have been in linux-next for a
  few weeks, and despite some people's feeling about if linux-next
  actually tests things, I think it's a good "soak test" for patches"

* tag 'char-misc-4.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  Drivers: hv: fcopy: restore correct transfer length
  vmbus: don't acquire the mutex in vmbus_hvsock_device_unregister()
  intel_th: pci: Add Lewisburg PCH support
  intel_th: pci: Add Cedar Fork PCH support
  stm class: Fix a use-after-free
  nvmem: add missing of_node_put() in of_nvmem_cell_get()
  nvmem: core: return EFBIG on out-of-range write
  auxdisplay: charlcd: properly restore atomic counter on error path
  binder: fix memory corruption in binder_transaction binder
  binder: fix an ret value override
  android: binder: fix type mismatch warning
parents 9e66317d 549e658a
...@@ -2217,7 +2217,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, ...@@ -2217,7 +2217,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
debug_id, (u64)fda->num_fds); debug_id, (u64)fda->num_fds);
continue; continue;
} }
fd_array = (u32 *)(parent_buffer + fda->parent_offset); fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset);
for (fd_index = 0; fd_index < fda->num_fds; fd_index++) for (fd_index = 0; fd_index < fda->num_fds; fd_index++)
task_close_fd(proc, fd_array[fd_index]); task_close_fd(proc, fd_array[fd_index]);
} break; } break;
...@@ -2326,7 +2326,6 @@ static int binder_translate_handle(struct flat_binder_object *fp, ...@@ -2326,7 +2326,6 @@ static int binder_translate_handle(struct flat_binder_object *fp,
(u64)node->ptr); (u64)node->ptr);
binder_node_unlock(node); binder_node_unlock(node);
} else { } else {
int ret;
struct binder_ref_data dest_rdata; struct binder_ref_data dest_rdata;
binder_node_unlock(node); binder_node_unlock(node);
...@@ -2442,7 +2441,7 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda, ...@@ -2442,7 +2441,7 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
*/ */
parent_buffer = parent->buffer - parent_buffer = parent->buffer -
binder_alloc_get_user_buffer_offset(&target_proc->alloc); binder_alloc_get_user_buffer_offset(&target_proc->alloc);
fd_array = (u32 *)(parent_buffer + fda->parent_offset); fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset);
if (!IS_ALIGNED((unsigned long)fd_array, sizeof(u32))) { if (!IS_ALIGNED((unsigned long)fd_array, sizeof(u32))) {
binder_user_error("%d:%d parent offset not aligned correctly.\n", binder_user_error("%d:%d parent offset not aligned correctly.\n",
proc->pid, thread->pid); proc->pid, thread->pid);
...@@ -2508,7 +2507,7 @@ static int binder_fixup_parent(struct binder_transaction *t, ...@@ -2508,7 +2507,7 @@ static int binder_fixup_parent(struct binder_transaction *t,
proc->pid, thread->pid); proc->pid, thread->pid);
return -EINVAL; return -EINVAL;
} }
parent_buffer = (u8 *)(parent->buffer - parent_buffer = (u8 *)((uintptr_t)parent->buffer -
binder_alloc_get_user_buffer_offset( binder_alloc_get_user_buffer_offset(
&target_proc->alloc)); &target_proc->alloc));
*(binder_uintptr_t *)(parent_buffer + bp->parent_offset) = bp->buffer; *(binder_uintptr_t *)(parent_buffer + bp->parent_offset) = bp->buffer;
...@@ -3083,6 +3082,7 @@ static void binder_transaction(struct binder_proc *proc, ...@@ -3083,6 +3082,7 @@ static void binder_transaction(struct binder_proc *proc,
err_dead_proc_or_thread: err_dead_proc_or_thread:
return_error = BR_DEAD_REPLY; return_error = BR_DEAD_REPLY;
return_error_line = __LINE__; return_error_line = __LINE__;
binder_dequeue_work(proc, tcomplete);
err_translate_failed: err_translate_failed:
err_bad_object_type: err_bad_object_type:
err_bad_offset: err_bad_offset:
......
...@@ -647,18 +647,25 @@ static ssize_t charlcd_write(struct file *file, const char __user *buf, ...@@ -647,18 +647,25 @@ static ssize_t charlcd_write(struct file *file, const char __user *buf,
static int charlcd_open(struct inode *inode, struct file *file) static int charlcd_open(struct inode *inode, struct file *file)
{ {
struct charlcd_priv *priv = to_priv(the_charlcd); struct charlcd_priv *priv = to_priv(the_charlcd);
int ret;
ret = -EBUSY;
if (!atomic_dec_and_test(&charlcd_available)) if (!atomic_dec_and_test(&charlcd_available))
return -EBUSY; /* open only once at a time */ goto fail; /* open only once at a time */
ret = -EPERM;
if (file->f_mode & FMODE_READ) /* device is write-only */ if (file->f_mode & FMODE_READ) /* device is write-only */
return -EPERM; goto fail;
if (priv->must_clear) { if (priv->must_clear) {
charlcd_clear_display(&priv->lcd); charlcd_clear_display(&priv->lcd);
priv->must_clear = false; priv->must_clear = false;
} }
return nonseekable_open(inode, file); return nonseekable_open(inode, file);
fail:
atomic_inc(&charlcd_available);
return ret;
} }
static int charlcd_release(struct inode *inode, struct file *file) static int charlcd_release(struct inode *inode, struct file *file)
......
...@@ -1105,14 +1105,21 @@ static ssize_t keypad_read(struct file *file, ...@@ -1105,14 +1105,21 @@ static ssize_t keypad_read(struct file *file,
static int keypad_open(struct inode *inode, struct file *file) static int keypad_open(struct inode *inode, struct file *file)
{ {
int ret;
ret = -EBUSY;
if (!atomic_dec_and_test(&keypad_available)) if (!atomic_dec_and_test(&keypad_available))
return -EBUSY; /* open only once at a time */ goto fail; /* open only once at a time */
ret = -EPERM;
if (file->f_mode & FMODE_WRITE) /* device is read-only */ if (file->f_mode & FMODE_WRITE) /* device is read-only */
return -EPERM; goto fail;
keypad_buflen = 0; /* flush the buffer on opening */ keypad_buflen = 0; /* flush the buffer on opening */
return 0; return 0;
fail:
atomic_inc(&keypad_available);
return ret;
} }
static int keypad_release(struct inode *inode, struct file *file) static int keypad_release(struct inode *inode, struct file *file)
......
...@@ -936,14 +936,10 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) ...@@ -936,14 +936,10 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
void vmbus_hvsock_device_unregister(struct vmbus_channel *channel) void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
{ {
mutex_lock(&vmbus_connection.channel_mutex);
BUG_ON(!is_hvsock_channel(channel)); BUG_ON(!is_hvsock_channel(channel));
channel->rescind = true; channel->rescind = true;
vmbus_device_unregister(channel->device_obj); vmbus_device_unregister(channel->device_obj);
mutex_unlock(&vmbus_connection.channel_mutex);
} }
EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister); EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
......
...@@ -170,6 +170,10 @@ static void fcopy_send_data(struct work_struct *dummy) ...@@ -170,6 +170,10 @@ static void fcopy_send_data(struct work_struct *dummy)
out_src = smsg_out; out_src = smsg_out;
break; break;
case WRITE_TO_FILE:
out_src = fcopy_transaction.fcopy_msg;
out_len = sizeof(struct hv_do_fcopy);
break;
default: default:
out_src = fcopy_transaction.fcopy_msg; out_src = fcopy_transaction.fcopy_msg;
out_len = fcopy_transaction.recv_len; out_len = fcopy_transaction.recv_len;
......
...@@ -143,6 +143,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { ...@@ -143,6 +143,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1), PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1),
.driver_data = (kernel_ulong_t)0, .driver_data = (kernel_ulong_t)0,
}, },
{
/* Lewisburg PCH */
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6),
.driver_data = (kernel_ulong_t)0,
},
{ {
/* Gemini Lake */ /* Gemini Lake */
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),
...@@ -158,6 +163,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { ...@@ -158,6 +163,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6), PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6),
.driver_data = (kernel_ulong_t)&intel_th_2x, .driver_data = (kernel_ulong_t)&intel_th_2x,
}, },
{
/* Cedar Fork PCH */
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1),
.driver_data = (kernel_ulong_t)&intel_th_2x,
},
{ 0 }, { 0 },
}; };
......
...@@ -1119,7 +1119,7 @@ void stm_source_unregister_device(struct stm_source_data *data) ...@@ -1119,7 +1119,7 @@ void stm_source_unregister_device(struct stm_source_data *data)
stm_source_link_drop(src); stm_source_link_drop(src);
device_destroy(&stm_source_class, src->dev.devt); device_unregister(&src->dev);
} }
EXPORT_SYMBOL_GPL(stm_source_unregister_device); EXPORT_SYMBOL_GPL(stm_source_unregister_device);
......
...@@ -135,7 +135,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj, ...@@ -135,7 +135,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
/* Stop the user from writing */ /* Stop the user from writing */
if (pos >= nvmem->size) if (pos >= nvmem->size)
return 0; return -EFBIG;
if (count < nvmem->word_size) if (count < nvmem->word_size)
return -EINVAL; return -EINVAL;
...@@ -789,6 +789,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, ...@@ -789,6 +789,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
nvmem = __nvmem_device_get(nvmem_np, NULL, NULL); nvmem = __nvmem_device_get(nvmem_np, NULL, NULL);
of_node_put(nvmem_np);
if (IS_ERR(nvmem)) if (IS_ERR(nvmem))
return ERR_CAST(nvmem); return ERR_CAST(nvmem);
......
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