This is the start of the stable review cycle for the 3.16.64 release. There are 16 patches in this series, which will be posted as responses to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon Mar 25 18:00:00 UTC 2019. Anything received after that time might be too late.
All the patches have also been committed to the linux-3.16.y-rc branch of https://git.kernel.org/pub/scm/linux/kernel/git/bwh/linux-stable-rc.git . A shortlog and diffstat can be found below.
Ben.
-------------
Brian Foster (1): xfs: don't BUG() on mixed direct and mapped I/O [04197b341f23b908193308b8d63d17ff23232598]
Christoffer Dall (2): KVM: PPC: Move xics_debugfs_init out of create [023e9fddc3616b005c3753fc1bb6526388cd7a30] KVM: Protect device ops->create and list_add with kvm->lock [a28ebea2adc4a2bef5989a5a181ec238f59fbcad]
Dan Carpenter (1): KVM: use after free in kvm_ioctl_create_device() [a0f1d21c1ccb1da66629627a74059dd7f5ac9c61]
Hui Peng (1): USB: hso: Fix OOB memory access in hso_probe/hso_get_config_data [5146f95df782b0ac61abde36567e718692725c89]
Jann Horn (1): kvm: fix kvm_ioctl_create_device() reference counting (CVE-2019-6974) [cfa39381173d5f969daf43582c95ad679189cbc9]
Jiri Kosina (1): HID: debug: fix error handling in hid_debug_events_read() [8fec02a73e31407e14986fca67dab48d4f777f0e]
Kees Cook (1): swiotlb: clean up reporting [7d63fb3af87aa67aa7d24466e792f9d7c57d8e79]
Oliver Hartkopp (1): can: gw: ensure DLC boundaries after CAN frame modification [0aaa81377c5a01f686bcdb8c7a6929a7bf330c68]
Paolo Bonzini (1): KVM: x86: work around leak of uninitialized stack contents (CVE-2019-7222) [353c0956a618a07ba4bbe7ad00ff29fe70e8412a]
Peter Shier (1): KVM: nVMX: unconditionally cancel preemption timer in free_nested (CVE-2019-7221) [ecec76885bcfe3294685dc363fd1273df0d5d65f]
Rasmus Villemoes (1): HID: debug: improve hid_debug_event() [92529623d242cea4440958d7bcebdf291f4ab15e]
Rohit Vaswani (1): mm: cma: fix incorrect type conversion for size during dma allocation [67a2e213e7e937c41c52ab5bc46bf3f4de469f6e]
Vasily Averin (1): sunrpc: use-after-free in svc_process_common() [d4b09acf924b84bae77cad090a9d108e70b43643]
Vladis Dronov (1): HID: debug: fix the ring buffer implementation [13054abbaa4f1fd4e6f3b4b63439ec033b4c8035]
Willy Tarreau (1): net/appletalk: fix minor pointer leak to userspace in SIOCFINDIPDDPRT [9824dfae5741275473a23a7ed5756c7b6efacc9d]
Makefile | 4 +- arch/arm/kvm/arm.c | 9 ++-- arch/powerpc/kvm/book3s_xics.c | 12 +++-- arch/x86/kvm/vmx.c | 1 + arch/x86/kvm/x86.c | 7 +++ drivers/base/dma-contiguous.c | 4 +- drivers/hid/hid-debug.c | 119 ++++++++++++++++------------------------- drivers/net/appletalk/ipddp.c | 8 ++- drivers/net/usb/hso.c | 18 ++++++- fs/xfs/xfs_aops.c | 21 +++++++- include/linux/dma-contiguous.h | 4 +- include/linux/hid-debug.h | 9 ++-- include/linux/kvm_host.h | 12 +++++ include/linux/sunrpc/svc.h | 5 +- lib/swiotlb.c | 18 +++---- net/can/gw.c | 30 +++++++++-- net/sunrpc/svc.c | 10 ++-- net/sunrpc/svc_xprt.c | 5 +- net/sunrpc/svcsock.c | 2 +- virt/kvm/arm/vgic.c | 11 +--- virt/kvm/kvm_main.c | 19 ++++++- 21 files changed, 202 insertions(+), 126 deletions(-)
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp socketcan@hartkopp.net
commit 0aaa81377c5a01f686bcdb8c7a6929a7bf330c68 upstream.
Muyu Yu provided a POC where user root with CAP_NET_ADMIN can create a CAN frame modification rule that makes the data length code a higher value than the available CAN frame data size. In combination with a configured checksum calculation where the result is stored relatively to the end of the data (e.g. cgw_csum_xor_rel) the tail of the skb (e.g. frag_list pointer in skb_shared_info) can be rewritten which finally can cause a system crash.
Michael Kubecek suggested to drop frames that have a DLC exceeding the available space after the modification process and provided a patch that can handle CAN FD frames too. Within this patch we also limit the length for the checksum calculations to the maximum of Classic CAN data length (8).
CAN frames that are dropped by these additional checks are counted with the CGW_DELETED counter which indicates misconfigurations in can-gw rules.
This fixes CVE-2019-3701.
Reported-by: Muyu Yu ieatmuttonchuan@gmail.com Reported-by: Marcus Meissner meissner@suse.de Suggested-by: Michal Kubecek mkubecek@suse.cz Tested-by: Muyu Yu ieatmuttonchuan@gmail.com Tested-by: Oliver Hartkopp socketcan@hartkopp.net Signed-off-by: Oliver Hartkopp socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/can/gw.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-)
--- a/net/can/gw.c +++ b/net/can/gw.c @@ -417,13 +417,29 @@ static void can_can_gw_rcv(struct sk_buf while (modidx < MAX_MODFUNCTIONS && gwj->mod.modfunc[modidx]) (*gwj->mod.modfunc[modidx++])(cf, &gwj->mod);
- /* check for checksum updates when the CAN frame has been modified */ + /* Has the CAN frame been modified? */ if (modidx) { - if (gwj->mod.csumfunc.crc8) + /* get available space for the processed CAN frame type */ + int max_len = nskb->len - offsetof(struct can_frame, data); + + /* dlc may have changed, make sure it fits to the CAN frame */ + if (cf->can_dlc > max_len) + goto out_delete; + + /* check for checksum updates in classic CAN length only */ + if (gwj->mod.csumfunc.crc8) { + if (cf->can_dlc > 8) + goto out_delete; + (*gwj->mod.csumfunc.crc8)(cf, &gwj->mod.csum.crc8); + } + + if (gwj->mod.csumfunc.xor) { + if (cf->can_dlc > 8) + goto out_delete;
- if (gwj->mod.csumfunc.xor) (*gwj->mod.csumfunc.xor)(cf, &gwj->mod.csum.xor); + } }
/* clear the skb timestamp if not configured the other way */ @@ -435,6 +451,14 @@ static void can_can_gw_rcv(struct sk_buf gwj->dropped_frames++; else gwj->handled_frames++; + + return; + + out_delete: + /* delete frame due to misconfiguration */ + gwj->deleted_frames++; + kfree_skb(nskb); + return; }
static inline int cgw_register_filter(struct cgw_job *gwj)
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Brian Foster bfoster@redhat.com
commit 04197b341f23b908193308b8d63d17ff23232598 upstream.
We've had reports of generic/095 causing XFS to BUG() in __xfs_get_blocks() due to the existence of delalloc blocks on a direct I/O read. generic/095 issues a mix of various types of I/O, including direct and memory mapped I/O to a single file. This is clearly not supported behavior and is known to lead to such problems. E.g., the lack of exclusion between the direct I/O and write fault paths means that a write fault can allocate delalloc blocks in a region of a file that was previously a hole after the direct read has attempted to flush/inval the file range, but before it actually reads the block mapping. In turn, the direct read discovers a delalloc extent and cannot proceed.
While the appropriate solution here is to not mix direct and memory mapped I/O to the same regions of the same file, the current BUG_ON() behavior is probably overkill as it can crash the entire system. Instead, localize the failure to the I/O in question by returning an error for a direct I/O that cannot be handled safely due to delalloc blocks. Be careful to allow the case of a direct write to post-eof delalloc blocks. This can occur due to speculative preallocation and is safe as post-eof blocks are not accompanied by dirty pages in pagecache (conversely, preallocation within eof must have been zeroed, and thus dirtied, before the inode size could have been increased beyond said blocks).
Finally, provide an additional warning if a direct I/O write occurs while the file is memory mapped. This may not catch all problematic scenarios, but provides a hint that some known-to-be-problematic I/O methods are in use.
Signed-off-by: Brian Foster bfoster@redhat.com Reviewed-by: Dave Chinner dchinner@redhat.com Signed-off-by: Dave Chinner david@fromorbit.com [bwh: Backported to 3.16: - Assign positive error code to error variable - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/xfs/xfs_aops.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
--- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1300,6 +1300,26 @@ __xfs_get_blocks( if (error) goto out_unlock;
+ /* + * The only time we can ever safely find delalloc blocks on direct I/O + * is a dio write to post-eof speculative preallocation. All other + * scenarios are indicative of a problem or misuse (such as mixing + * direct and mapped I/O). + * + * The file may be unmapped by the time we get here so we cannot + * reliably fail the I/O based on mapping. Instead, fail the I/O if this + * is a read or a write within eof. Otherwise, carry on but warn as a + * precuation if the file happens to be mapped. + */ + if (direct && imap.br_startblock == DELAYSTARTBLOCK) { + if (!create || offset < i_size_read(VFS_I(ip))) { + WARN_ON_ONCE(1); + error = EIO; + goto out_unlock; + } + WARN_ON_ONCE(mapping_mapped(VFS_I(ip)->i_mapping)); + } + if (create && (!nimaps || (imap.br_startblock == HOLESTARTBLOCK || @@ -1383,7 +1403,6 @@ __xfs_get_blocks( set_buffer_new(bh_result);
if (imap.br_startblock == DELAYSTARTBLOCK) { - BUG_ON(direct); if (create) { set_buffer_uptodate(bh_result); set_buffer_mapped(bh_result);
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Willy Tarreau w@1wt.eu
commit 9824dfae5741275473a23a7ed5756c7b6efacc9d upstream.
Fields ->dev and ->next of struct ipddp_route may be copied to userspace on the SIOCFINDIPDDPRT ioctl. This is only accessible to CAP_NET_ADMIN though. Let's manually copy the relevant fields instead of using memcpy().
BugLink: http://blog.infosectcbr.com.au/2018/09/linux-kernel-infoleaks.html Cc: Jann Horn jannh@google.com Signed-off-by: Willy Tarreau w@1wt.eu Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/net/appletalk/ipddp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/net/appletalk/ipddp.c +++ b/drivers/net/appletalk/ipddp.c @@ -284,8 +284,12 @@ static int ipddp_ioctl(struct net_device case SIOCFINDIPDDPRT: spin_lock_bh(&ipddp_route_lock); rp = __ipddp_find_route(&rcp); - if (rp) - memcpy(&rcp2, rp, sizeof(rcp2)); + if (rp) { + memset(&rcp2, 0, sizeof(rcp2)); + rcp2.ip = rp->ip; + rcp2.at = rp->at; + rcp2.flags = rp->flags; + } spin_unlock_bh(&ipddp_route_lock);
if (rp) {
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Kosina jkosina@suse.cz
commit 8fec02a73e31407e14986fca67dab48d4f777f0e upstream.
In the unlikely case of hdev vanishing while hid_debug_events_read() was sleeping, we can't really break out of the case switch as with other cases, as on the way out we'll try to remove ourselves from the hdev waitqueue.
Fix this by taking a shortcut exit path and avoiding cleanup that doesn't make sense in case hdev doesn't exist any more anyway.
Reported-by: Jiri Slaby jslaby@suse.cz Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/hid/hid-debug.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -1127,7 +1127,8 @@ static ssize_t hid_debug_events_read(str
if (!list->hdev || !list->hdev->debug) { ret = -EIO; - break; + set_current_state(TASK_RUNNING); + goto out; }
/* allow O_NONBLOCK from other threads */
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Vasily Averin vvs@virtuozzo.com
commit d4b09acf924b84bae77cad090a9d108e70b43643 upstream.
if node have NFSv41+ mounts inside several net namespaces it can lead to use-after-free in svc_process_common()
svc_process_common() /* Setup reply header */ rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); <<< HERE
svc_process_common() can use incorrect rqstp->rq_xprt, its caller function bc_svc_process() takes it from serv->sv_bc_xprt. The problem is that serv is global structure but sv_bc_xprt is assigned per-netnamespace.
According to Trond, the whole "let's set up rqstp->rq_xprt for the back channel" is nothing but a giant hack in order to work around the fact that svc_process_common() uses it to find the xpt_ops, and perform a couple of (meaningless for the back channel) tests of xpt_flags.
All we really need in svc_process_common() is to be able to run rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr()
Bruce J Fields points that this xpo_prep_reply_hdr() call is an awfully roundabout way just to do "svc_putnl(resv, 0);" in the tcp case.
This patch does not initialiuze rqstp->rq_xprt in bc_svc_process(), now it calls svc_process_common() with rqstp->rq_xprt = NULL.
To adjust reply header svc_process_common() just check rqstp->rq_prot and calls svc_tcp_prep_reply_hdr() for tcp case.
To handle rqstp->rq_xprt = NULL case in functions called from svc_process_common() patch intruduces net namespace pointer svc_rqst->rq_bc_net and adjust SVC_NET() definition. Some other function was also adopted to properly handle described case.
Signed-off-by: Vasily Averin vvs@virtuozzo.com Fixes: 23c20ecd4475 ("NFS: callback up - users counting cleanup") Signed-off-by: J. Bruce Fields bfields@redhat.com v2: - added lost extern svc_tcp_prep_reply_hdr() - context changes in svc_process_common() - dropped trace_svc_process() changes Signed-off-by: Vasily Averin vvs@virtuozzo.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- include/linux/sunrpc/svc.h | 5 ++++- net/sunrpc/svc.c | 10 +++++++--- net/sunrpc/svc_xprt.c | 5 +++-- net/sunrpc/svcsock.c | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-)
--- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -282,9 +282,12 @@ struct svc_rqst { * cache pages */ wait_queue_head_t rq_wait; /* synchronization */ struct task_struct *rq_task; /* service thread */ + struct net *rq_bc_net; /* pointer to backchannel's + * net namespace + */ };
-#define SVC_NET(svc_rqst) (svc_rqst->rq_xprt->xpt_net) +#define SVC_NET(rqst) (rqst->rq_xprt ? rqst->rq_xprt->xpt_net : rqst->rq_bc_net)
/* * Rigorous type checking on sockaddr type conversions --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -1063,6 +1063,8 @@ void svc_printk(struct svc_rqst *rqstp, static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) {} #endif
+extern void svc_tcp_prep_reply_hdr(struct svc_rqst *); + /* * Common routine for processing the RPC request. */ @@ -1092,7 +1094,8 @@ svc_process_common(struct svc_rqst *rqst rqstp->rq_dropme = false;
/* Setup reply header */ - rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); + if (rqstp->rq_prot == IPPROTO_TCP) + svc_tcp_prep_reply_hdr(rqstp);
svc_putu32(resv, rqstp->rq_xid);
@@ -1139,7 +1142,8 @@ svc_process_common(struct svc_rqst *rqst case SVC_DENIED: goto err_bad_auth; case SVC_CLOSE: - if (test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags)) + if (rqstp->rq_xprt && + test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags)) svc_close_xprt(rqstp->rq_xprt); case SVC_DROP: goto dropit; @@ -1354,10 +1358,10 @@ bc_svc_process(struct svc_serv *serv, st struct kvec *resv = &rqstp->rq_res.head[0];
/* Build the svc_rqst used by the common processing routine */ - rqstp->rq_xprt = serv->sv_bc_xprt; rqstp->rq_xid = req->rq_xid; rqstp->rq_prot = req->rq_xprt->prot; rqstp->rq_server = serv; + rqstp->rq_bc_net = req->rq_xprt->xprt_net;
rqstp->rq_addrlen = sizeof(req->rq_xprt->addr); memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen); --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -432,10 +432,11 @@ static struct svc_xprt *svc_xprt_dequeue */ void svc_reserve(struct svc_rqst *rqstp, int space) { + struct svc_xprt *xprt = rqstp->rq_xprt; + space += rqstp->rq_res.head[0].iov_len;
- if (space < rqstp->rq_reserved) { - struct svc_xprt *xprt = rqstp->rq_xprt; + if (xprt && space < rqstp->rq_reserved) { atomic_sub((rqstp->rq_reserved - space), &xprt->xpt_reserved); rqstp->rq_reserved = space;
--- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1195,7 +1195,7 @@ static int svc_tcp_sendto(struct svc_rqs /* * Setup response header. TCP has a 4B record length field. */ -static void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp) +void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp) { struct kvec *resv = &rqstp->rq_res.head[0];
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Christoffer Dall christoffer.dall@linaro.org
commit a28ebea2adc4a2bef5989a5a181ec238f59fbcad upstream.
KVM devices were manipulating list data structures without any form of synchronization, and some implementations of the create operations also suffered from a lack of synchronization.
Now when we've split the xics create operation into create and init, we can hold the kvm->lock mutex while calling the create operation and when manipulating the devices list.
The error path in the generic code gets slightly ugly because we have to take the mutex again and delete the device from the list, but holding the mutex during anon_inode_getfd or releasing/locking the mutex in the common non-error path seemed wrong.
Signed-off-by: Christoffer Dall christoffer.dall@linaro.org Reviewed-by: Paolo Bonzini pbonzini@redhat.com Acked-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Radim Krčmář rkrcmar@redhat.com [bwh: Backported to 3.16: - Drop change to a failure path that doesn't exist in kvm_vgic_create() - Adjust filename, context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -799,10 +799,13 @@ long kvm_arch_vm_ioctl(struct file *filp
switch (ioctl) { case KVM_CREATE_IRQCHIP: { - if (vgic_present) - return kvm_vgic_create(kvm); - else + int ret; + if (!vgic_present) return -ENXIO; + mutex_lock(&kvm->lock); + ret = kvm_vgic_create(kvm); + mutex_unlock(&kvm->lock); + return ret; } case KVM_ARM_SET_DEVICE_ADDR: { struct kvm_arm_device_addr dev_addr; --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c @@ -1239,12 +1239,10 @@ static int kvmppc_xics_create(struct kvm xics->kvm = kvm;
/* Already there ? */ - mutex_lock(&kvm->lock); if (kvm->arch.xics) ret = -EEXIST; else kvm->arch.xics = xics; - mutex_unlock(&kvm->lock);
if (ret) { kfree(xics); --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1059,6 +1059,12 @@ struct kvm_device { /* create, destroy, and name are mandatory */ struct kvm_device_ops { const char *name; + + /* + * create is called holding kvm->lock and any operations not suitable + * to do while holding the lock should be deferred to init (see + * below). + */ int (*create)(struct kvm_device *dev, u32 type);
/* --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -1624,12 +1624,8 @@ int kvm_vgic_create(struct kvm *kvm) int i, vcpu_lock_idx = -1, ret; struct kvm_vcpu *vcpu;
- mutex_lock(&kvm->lock); - - if (kvm->arch.vgic.vctrl_base) { - ret = -EEXIST; - goto out; - } + if (kvm->arch.vgic.vctrl_base) + return -EEXIST;
/* * Any time a vcpu is run, vcpu_load is called which tries to grab the @@ -1659,9 +1655,6 @@ out_unlock: vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx); mutex_unlock(&vcpu->mutex); } - -out: - mutex_unlock(&kvm->lock); return ret; }
--- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -587,6 +587,11 @@ static void kvm_destroy_devices(struct k { struct list_head *node, *tmp;
+ /* + * We do not need to take the kvm->lock here, because nobody else + * has a reference to the struct kvm at this point and therefore + * cannot access the devices list anyhow. + */ list_for_each_safe(node, tmp, &kvm->devices) { struct kvm_device *dev = list_entry(node, struct kvm_device, vm_node); @@ -2322,11 +2327,15 @@ static int kvm_ioctl_create_device(struc dev->ops = ops; dev->kvm = kvm;
+ mutex_lock(&kvm->lock); ret = ops->create(dev, cd->type); if (ret < 0) { + mutex_unlock(&kvm->lock); kfree(dev); return ret; } + list_add(&dev->vm_node, &kvm->devices); + mutex_unlock(&kvm->lock);
if (ops->init) ops->init(dev); @@ -2334,10 +2343,12 @@ static int kvm_ioctl_create_device(struc ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC); if (ret < 0) { ops->destroy(dev); + mutex_lock(&kvm->lock); + list_del(&dev->vm_node); + mutex_unlock(&kvm->lock); return ret; }
- list_add(&dev->vm_node, &kvm->devices); kvm_get_kvm(kvm); cd->fd = ret; return 0;
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Rasmus Villemoes linux@rasmusvillemoes.dk
commit 92529623d242cea4440958d7bcebdf291f4ab15e upstream.
The code in hid_debug_event() causes horrible code generation. First, we do a strlen() call for every byte we copy (we're doing a store to global memory, so gcc has no way of proving that strlen(buf) doesn't change). Second, since both i, list->tail and HID_DEBUG_BUFSIZE have signed type, the modulo computation has to take into account the possibility that list->tail+i is negative, so it's not just a simple and.
Fix the former by simply not doing strlen() at all (we have to load buf[i] anyway, so testing it is almost free) and the latter by changing i to unsigned. This cuts 29% (69 bytes) of the size of the function.
Signed-off-by: Rasmus Villemoes linux@rasmusvillemoes.dk Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/hid/hid-debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -658,13 +658,13 @@ EXPORT_SYMBOL_GPL(hid_dump_device); /* enqueue string to 'events' ring buffer */ void hid_debug_event(struct hid_device *hdev, char *buf) { - int i; + unsigned i; struct hid_debug_list *list; unsigned long flags;
spin_lock_irqsave(&hdev->debug_list_lock, flags); list_for_each_entry(list, &hdev->debug_list, node) { - for (i = 0; i < strlen(buf); i++) + for (i = 0; buf[i]; i++) list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] = buf[i]; list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE;
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn jannh@google.com
commit cfa39381173d5f969daf43582c95ad679189cbc9 upstream.
kvm_ioctl_create_device() does the following:
1. creates a device that holds a reference to the VM object (with a borrowed reference, the VM's refcount has not been bumped yet) 2. initializes the device 3. transfers the reference to the device to the caller's file descriptor table 4. calls kvm_get_kvm() to turn the borrowed reference to the VM into a real reference
The ownership transfer in step 3 must not happen before the reference to the VM becomes a proper, non-borrowed reference, which only happens in step 4. After step 3, an attacker can close the file descriptor and drop the borrowed reference, which can cause the refcount of the kvm object to drop to zero.
This means that we need to grab a reference for the device before anon_inode_getfd(), otherwise the VM can disappear from under us.
Fixes: 852b6d57dc7f ("kvm: add device control API") Signed-off-by: Jann Horn jannh@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- virt/kvm/kvm_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2340,8 +2340,10 @@ static int kvm_ioctl_create_device(struc if (ops->init) ops->init(dev);
+ kvm_get_kvm(kvm); ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC); if (ret < 0) { + kvm_put_kvm(kvm); mutex_lock(&kvm->lock); list_del(&dev->vm_node); mutex_unlock(&kvm->lock); @@ -2349,7 +2351,6 @@ static int kvm_ioctl_create_device(struc return ret; }
- kvm_get_kvm(kvm); cd->fd = ret; return 0; }
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Hui Peng benquike@gmail.com
commit 5146f95df782b0ac61abde36567e718692725c89 upstream.
The function hso_probe reads if_num from the USB device (as an u8) and uses it without a length check to index an array, resulting in an OOB memory read in hso_probe or hso_get_config_data.
Add a length check for both locations and updated hso_probe to bail on error.
This issue has been assigned CVE-2018-19985.
Reported-by: Hui Peng benquike@gmail.com Reported-by: Mathias Payer mathias.payer@nebelwelt.net Signed-off-by: Hui Peng benquike@gmail.com Signed-off-by: Mathias Payer mathias.payer@nebelwelt.net Reviewed-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/net/usb/hso.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
--- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2812,6 +2812,12 @@ static int hso_get_config_data(struct us return -EIO; }
+ /* check if we have a valid interface */ + if (if_num > 16) { + kfree(config_data); + return -EINVAL; + } + switch (config_data[if_num]) { case 0x0: result = 0; @@ -2882,10 +2888,18 @@ static int hso_probe(struct usb_interfac
/* Get the interface/port specification from either driver_info or from * the device itself */ - if (id->driver_info) + if (id->driver_info) { + /* if_num is controlled by the device, driver_info is a 0 terminated + * array. Make sure, the access is in bounds! */ + for (i = 0; i <= if_num; ++i) + if (((u32 *)(id->driver_info))[i] == 0) + goto exit; port_spec = ((u32 *)(id->driver_info))[if_num]; - else + } else { port_spec = hso_get_config_data(interface); + if (port_spec < 0) + goto exit; + }
/* Check if we need to switch to alt interfaces prior to port * configuration */
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook keescook@chromium.org
commit 7d63fb3af87aa67aa7d24466e792f9d7c57d8e79 upstream.
This removes needless use of '%p', and refactors the printk calls to use pr_*() helpers instead.
Signed-off-by: Kees Cook keescook@chromium.org Reviewed-by: Konrad Rzeszutek Wilk konrad.wilk@oracle.com Signed-off-by: Christoph Hellwig hch@lst.de [bwh: Backported to 3.16: adjust filename] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- lib/swiotlb.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
--- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -17,6 +17,8 @@ * 08/12/11 beckyb Add highmem support */
+#define pr_fmt(fmt) "software IO TLB: " fmt + #include <linux/cache.h> #include <linux/dma-mapping.h> #include <linux/mm.h> @@ -143,20 +145,16 @@ static bool no_iotlb_memory; void swiotlb_print_info(void) { unsigned long bytes = io_tlb_nslabs << IO_TLB_SHIFT; - unsigned char *vstart, *vend;
if (no_iotlb_memory) { - pr_warn("software IO TLB: No low mem\n"); + pr_warn("No low mem\n"); return; }
- vstart = phys_to_virt(io_tlb_start); - vend = phys_to_virt(io_tlb_end); - - printk(KERN_INFO "software IO TLB [mem %#010llx-%#010llx] (%luMB) mapped at [%p-%p]\n", + pr_info("mapped [mem %#010llx-%#010llx] (%luMB)\n", (unsigned long long)io_tlb_start, (unsigned long long)io_tlb_end, - bytes >> 20, vstart, vend - 1); + bytes >> 20); }
int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) @@ -230,7 +228,7 @@ swiotlb_init(int verbose) if (io_tlb_start) memblock_free_early(io_tlb_start, PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); - pr_warn("Cannot allocate SWIOTLB buffer"); + pr_warn("Cannot allocate buffer"); no_iotlb_memory = true; }
@@ -272,8 +270,8 @@ swiotlb_late_init_with_default_size(size return -ENOMEM; } if (order != get_order(bytes)) { - printk(KERN_WARNING "Warning: only able to allocate %ld MB " - "for software IO TLB\n", (PAGE_SIZE << order) >> 20); + pr_warn("only able to allocate %ld MB\n", + (PAGE_SIZE << order) >> 20); io_tlb_nslabs = SLABS_PER_PAGE << order; } rc = swiotlb_late_init_with_tbl(vstart, io_tlb_nslabs);
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Bonzini pbonzini@redhat.com
commit 353c0956a618a07ba4bbe7ad00ff29fe70e8412a upstream.
Bugzilla: 1671930
Emulation of certain instructions (VMXON, VMCLEAR, VMPTRLD, VMWRITE with memory operand, INVEPT, INVVPID) can incorrectly inject a page fault when passed an operand that points to an MMIO address. The page fault will use uninitialized kernel stack memory as the CR2 and error code.
The right behavior would be to abort the VM with a KVM_EXIT_INTERNAL_ERROR exit to userspace; however, it is not an easy fix, so for now just ensure that the error code and CR2 are zero.
Embargoed until Feb 7th 2019.
Reported-by: Felix Wilhelm fwilhelm@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/kvm/x86.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4208,6 +4208,13 @@ int kvm_read_guest_virt(struct kvm_vcpu { u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+ /* + * FIXME: this should call handle_emulation_failure if X86EMUL_IO_NEEDED + * is returned, but our callers are not ready for that and they blindly + * call kvm_inject_page_fault. Ensure that they at least do not leak + * uninitialized kernel stack memory into cr2 and error code. + */ + memset(exception, 0, sizeof(*exception)); return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, exception); }
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter dan.carpenter@oracle.com
commit a0f1d21c1ccb1da66629627a74059dd7f5ac9c61 upstream.
We should move the ops->destroy(dev) after the list_del(&dev->vm_node) so that we don't use "dev" after freeing it.
Fixes: a28ebea2adc4 ("KVM: Protect device ops->create and list_add with kvm->lock") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: David Hildenbrand david@redhat.com Signed-off-by: Radim Krčmář rkrcmar@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- virt/kvm/kvm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2342,10 +2342,10 @@ static int kvm_ioctl_create_device(struc
ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC); if (ret < 0) { - ops->destroy(dev); mutex_lock(&kvm->lock); list_del(&dev->vm_node); mutex_unlock(&kvm->lock); + ops->destroy(dev); return ret; }
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Christoffer Dall christoffer.dall@linaro.org
commit 023e9fddc3616b005c3753fc1bb6526388cd7a30 upstream.
As we are about to hold the kvm->lock during the create operation on KVM devices, we should move the call to xics_debugfs_init into its own function, since holding a mutex over extended amounts of time might not be a good idea.
Introduce an init operation on the kvm_device_ops struct which cannot fail and call this, if configured, after the device has been created.
Signed-off-by: Christoffer Dall christoffer.dall@linaro.org Reviewed-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Radim Krčmář rkrcmar@redhat.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/powerpc/kvm/book3s_xics.c | 10 ++++++++-- include/linux/kvm_host.h | 6 ++++++ virt/kvm/kvm_main.c | 3 +++ 3 files changed, 17 insertions(+), 2 deletions(-)
--- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c @@ -1251,8 +1251,6 @@ static int kvmppc_xics_create(struct kvm return ret; }
- xics_debugfs_init(xics); - #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE if (cpu_has_feature(CPU_FTR_ARCH_206)) { /* Enable real mode support */ @@ -1264,9 +1262,17 @@ static int kvmppc_xics_create(struct kvm return 0; }
+static void kvmppc_xics_init(struct kvm_device *dev) +{ + struct kvmppc_xics *xics = (struct kvmppc_xics *)dev->private; + + xics_debugfs_init(xics); +} + struct kvm_device_ops kvm_xics_ops = { .name = "kvm-xics", .create = kvmppc_xics_create, + .init = kvmppc_xics_init, .destroy = kvmppc_xics_free, .set_attr = xics_set_attr, .get_attr = xics_get_attr, --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1062,6 +1062,12 @@ struct kvm_device_ops { int (*create)(struct kvm_device *dev, u32 type);
/* + * init is called after create if create is successful and is called + * outside of holding kvm->lock. + */ + void (*init)(struct kvm_device *dev); + + /* * Destroy is responsible for freeing dev. * * Destroy may be called before or after destructors are called --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2328,6 +2328,9 @@ static int kvm_ioctl_create_device(struc return ret; }
+ if (ops->init) + ops->init(dev); + ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC); if (ret < 0) { ops->destroy(dev);
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Rohit Vaswani rvaswani@codeaurora.org
commit 67a2e213e7e937c41c52ab5bc46bf3f4de469f6e upstream.
This was found during userspace fuzzing test when a large size dma cma allocation is made by driver(like ion) through userspace.
show_stack+0x10/0x1c dump_stack+0x74/0xc8 kasan_report_error+0x2b0/0x408 kasan_report+0x34/0x40 __asan_storeN+0x15c/0x168 memset+0x20/0x44 __dma_alloc_coherent+0x114/0x18c
Signed-off-by: Rohit Vaswani rvaswani@codeaurora.org Acked-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Marek Szyprowski m.szyprowski@samsung.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org [bwh: Backported to 3.16: cma_alloc() does not exist so only dma_alloc_from_contiguous() needs to be changed] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c @@ -313,7 +313,7 @@ static void clear_cma_bitmap(struct cma * global one. Requires architecture specific dev_get_cma_area() helper * function. */ -struct page *dma_alloc_from_contiguous(struct device *dev, int count, +struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, unsigned int align) { unsigned long mask, pfn, pageno, start = 0; @@ -327,7 +327,7 @@ struct page *dma_alloc_from_contiguous(s if (align > CONFIG_CMA_ALIGNMENT) align = CONFIG_CMA_ALIGNMENT;
- pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma, + pr_debug("%s(cma %p, count %zu, align %d)\n", __func__, (void *)cma, count, align);
if (!count) --- a/include/linux/dma-contiguous.h +++ b/include/linux/dma-contiguous.h @@ -116,7 +116,7 @@ static inline int dma_declare_contiguous return ret; }
-struct page *dma_alloc_from_contiguous(struct device *dev, int count, +struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, unsigned int order); bool dma_release_from_contiguous(struct device *dev, struct page *pages, int count); @@ -151,7 +151,7 @@ int dma_declare_contiguous(struct device }
static inline -struct page *dma_alloc_from_contiguous(struct device *dev, int count, +struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, unsigned int order) { return NULL;
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Peter Shier pshier@google.com
commit ecec76885bcfe3294685dc363fd1273df0d5d65f upstream.
Bugzilla: 1671904
There are multiple code paths where an hrtimer may have been started to emulate an L1 VMX preemption timer that can result in a call to free_nested without an intervening L2 exit where the hrtimer is normally cancelled. Unconditionally cancel in free_nested to cover all cases.
Embargoed until Feb 7th 2019.
Signed-off-by: Peter Shier pshier@google.com Reported-by: Jim Mattson jmattson@google.com Reviewed-by: Jim Mattson jmattson@google.com Reported-by: Felix Wilhelm fwilhelm@google.com Message-Id: 20181011184646.154065-1-pshier@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com [bwh: Backported to 3.16: adjust filename, context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/kvm/vmx.c | 1 + 1 file changed, 1 insertion(+)
--- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -6169,6 +6169,7 @@ static void free_nested(struct vcpu_vmx { if (!vmx->nested.vmxon) return; + hrtimer_cancel(&vmx->nested.preemption_timer); vmx->nested.vmxon = false; if (vmx->nested.current_vmptr != -1ull) { nested_release_vmcs12(vmx);
3.16.64-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Vladis Dronov vdronov@redhat.com
commit 13054abbaa4f1fd4e6f3b4b63439ec033b4c8035 upstream.
Ring buffer implementation in hid_debug_event() and hid_debug_events_read() is strange allowing lost or corrupted data. After commit 717adfdaf147 ("HID: debug: check length before copy_to_user()") it is possible to enter an infinite loop in hid_debug_events_read() by providing 0 as count, this locks up a system. Fix this by rewriting the ring buffer implementation with kfifo and simplify the code.
This fixes CVE-2019-3819.
v2: fix an execution logic and add a comment v3: use __set_current_state() instead of set_current_state()
Link: https://bugzilla.redhat.com/show_bug.cgi?id=1669187 Fixes: cd667ce24796 ("HID: use debugfs for events/reports dumping") Fixes: 717adfdaf147 ("HID: debug: check length before copy_to_user()") Signed-off-by: Vladis Dronov vdronov@redhat.com Reviewed-by: Oleg Nesterov oleg@redhat.com Signed-off-by: Benjamin Tissoires benjamin.tissoires@redhat.com [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/hid/hid-debug.c | 120 +++++++++++++++----------------------- include/linux/hid-debug.h | 9 ++- 2 files changed, 51 insertions(+), 78 deletions(-)
--- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -30,6 +30,7 @@
#include <linux/debugfs.h> #include <linux/seq_file.h> +#include <linux/kfifo.h> #include <linux/sched.h> #include <linux/export.h> #include <linux/slab.h> @@ -658,17 +659,12 @@ EXPORT_SYMBOL_GPL(hid_dump_device); /* enqueue string to 'events' ring buffer */ void hid_debug_event(struct hid_device *hdev, char *buf) { - unsigned i; struct hid_debug_list *list; unsigned long flags;
spin_lock_irqsave(&hdev->debug_list_lock, flags); - list_for_each_entry(list, &hdev->debug_list, node) { - for (i = 0; buf[i]; i++) - list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] = - buf[i]; - list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE; - } + list_for_each_entry(list, &hdev->debug_list, node) + kfifo_in(&list->hid_debug_fifo, buf, strlen(buf)); spin_unlock_irqrestore(&hdev->debug_list_lock, flags);
wake_up_interruptible(&hdev->debug_wait); @@ -719,8 +715,7 @@ void hid_dump_input(struct hid_device *h hid_debug_event(hdev, buf);
kfree(buf); - wake_up_interruptible(&hdev->debug_wait); - + wake_up_interruptible(&hdev->debug_wait); } EXPORT_SYMBOL_GPL(hid_dump_input);
@@ -1085,8 +1080,8 @@ static int hid_debug_events_open(struct goto out; }
- if (!(list->hid_debug_buf = kzalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_KERNEL))) { - err = -ENOMEM; + err = kfifo_alloc(&list->hid_debug_fifo, HID_DEBUG_FIFOSIZE, GFP_KERNEL); + if (err) { kfree(list); goto out; } @@ -1106,77 +1101,57 @@ static ssize_t hid_debug_events_read(str size_t count, loff_t *ppos) { struct hid_debug_list *list = file->private_data; - int ret = 0, len; + int ret = 0, copied; DECLARE_WAITQUEUE(wait, current);
mutex_lock(&list->read_mutex); - while (ret == 0) { - if (list->head == list->tail) { - add_wait_queue(&list->hdev->debug_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); - - while (list->head == list->tail) { - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - - if (!list->hdev || !list->hdev->debug) { - ret = -EIO; - set_current_state(TASK_RUNNING); - goto out; - } - - /* allow O_NONBLOCK from other threads */ - mutex_unlock(&list->read_mutex); - schedule(); - mutex_lock(&list->read_mutex); - set_current_state(TASK_INTERRUPTIBLE); + if (kfifo_is_empty(&list->hid_debug_fifo)) { + add_wait_queue(&list->hdev->debug_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + while (kfifo_is_empty(&list->hid_debug_fifo)) { + if (file->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + break; }
- set_current_state(TASK_RUNNING); - remove_wait_queue(&list->hdev->debug_wait, &wait); - } - - if (ret) - goto out; - - /* pass the ringbuffer contents to userspace */ -copy_rest: - if (list->tail == list->head) - goto out; - if (list->tail > list->head) { - len = list->tail - list->head; - if (len > count) - len = count; - - if (copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) { - ret = -EFAULT; - goto out; + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; } - ret += len; - list->head += len; - } else { - len = HID_DEBUG_BUFSIZE - list->head; - if (len > count) - len = count;
- if (copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) { - ret = -EFAULT; + /* if list->hdev is NULL we cannot remove_wait_queue(). + * if list->hdev->debug is 0 then hid_debug_unregister() + * was already called and list->hdev is being destroyed. + * if we add remove_wait_queue() here we can hit a race. + */ + if (!list->hdev || !list->hdev->debug) { + ret = -EIO; + set_current_state(TASK_RUNNING); goto out; } - list->head = 0; - ret += len; - count -= len; - if (count > 0) - goto copy_rest; + + /* allow O_NONBLOCK from other threads */ + mutex_unlock(&list->read_mutex); + schedule(); + mutex_lock(&list->read_mutex); + set_current_state(TASK_INTERRUPTIBLE); }
+ __set_current_state(TASK_RUNNING); + remove_wait_queue(&list->hdev->debug_wait, &wait); + + if (ret) + goto out; } + + /* pass the fifo content to userspace, locking is not needed with only + * one concurrent reader and one concurrent writer + */ + ret = kfifo_to_user(&list->hid_debug_fifo, buffer, count, &copied); + if (ret) + goto out; + ret = copied; out: mutex_unlock(&list->read_mutex); return ret; @@ -1187,7 +1162,7 @@ static unsigned int hid_debug_events_pol struct hid_debug_list *list = file->private_data;
poll_wait(file, &list->hdev->debug_wait, wait); - if (list->head != list->tail) + if (!kfifo_is_empty(&list->hid_debug_fifo)) return POLLIN | POLLRDNORM; if (!list->hdev->debug) return POLLERR | POLLHUP; @@ -1202,7 +1177,7 @@ static int hid_debug_events_release(stru spin_lock_irqsave(&list->hdev->debug_list_lock, flags); list_del(&list->node); spin_unlock_irqrestore(&list->hdev->debug_list_lock, flags); - kfree(list->hid_debug_buf); + kfifo_free(&list->hid_debug_fifo); kfree(list);
return 0; @@ -1253,4 +1228,3 @@ void hid_debug_exit(void) { debugfs_remove_recursive(hid_debug_root); } - --- a/include/linux/hid-debug.h +++ b/include/linux/hid-debug.h @@ -24,7 +24,10 @@
#ifdef CONFIG_DEBUG_FS
+#include <linux/kfifo.h> + #define HID_DEBUG_BUFSIZE 512 +#define HID_DEBUG_FIFOSIZE 512
void hid_dump_input(struct hid_device *, struct hid_usage *, __s32); void hid_dump_report(struct hid_device *, int , u8 *, int); @@ -37,11 +40,8 @@ void hid_debug_init(void); void hid_debug_exit(void); void hid_debug_event(struct hid_device *, char *);
- struct hid_debug_list { - char *hid_debug_buf; - int head; - int tail; + DECLARE_KFIFO_PTR(hid_debug_fifo, char); struct fasync_struct *fasync; struct hid_device *hdev; struct list_head node; @@ -64,4 +64,3 @@ struct hid_debug_list { #endif
#endif -
On 3/21/19 10:20 PM, Ben Hutchings wrote:
This is the start of the stable review cycle for the 3.16.64 release. There are 16 patches in this series, which will be posted as responses to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon Mar 25 18:00:00 UTC 2019. Anything received after that time might be too late.
Build results: total: 137 pass: 136 fail: 1 Failed builds: i386:tools/perf Qemu test results: total: 222 pass: 221 fail: 1 Failed tests: arm:midway:multi_v7_defconfig:mem2G:ecx-2000:initrd
The failed qemu test simply hangs. The test passes with v3.16.63. I started a bisect.
Guenter
On 3/22/19 6:44 AM, Guenter Roeck wrote:
On 3/21/19 10:20 PM, Ben Hutchings wrote:
This is the start of the stable review cycle for the 3.16.64 release. There are 16 patches in this series, which will be posted as responses to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon Mar 25 18:00:00 UTC 2019. Anything received after that time might be too late.
Build results: total: 137 pass: 136 fail: 1 Failed builds: i386:tools/perf Qemu test results: total: 222 pass: 221 fail: 1 Failed tests: arm:midway:multi_v7_defconfig:mem2G:ecx-2000:initrd
The failed qemu test simply hangs. The test passes with v3.16.63. I started a bisect.
False positive.
Sorry for the noise.
Guenter
On Fri, 2019-03-22 at 21:43 -0700, Guenter Roeck wrote:
On 3/22/19 6:44 AM, Guenter Roeck wrote:
On 3/21/19 10:20 PM, Ben Hutchings wrote:
This is the start of the stable review cycle for the 3.16.64 release. There are 16 patches in this series, which will be posted as responses to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon Mar 25 18:00:00 UTC 2019. Anything received after that time might be too late.
Build results: total: 137 pass: 136 fail: 1 Failed builds: i386:tools/perf Qemu test results: total: 222 pass: 221 fail: 1 Failed tests: arm:midway:multi_v7_defconfig:mem2G:ecx-2000:initrd
The failed qemu test simply hangs. The test passes with v3.16.63. I started a bisect.
False positive.
Sorry for the noise.
Thanks a lot for testing.
Ben.
linux-stable-mirror@lists.linaro.org