Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

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

All of them are simple, resolving reported problems in a few drivers.
Full details are in the shortlog.

All of these have been in linux-next with no reported issues"

* tag 'char-misc-4.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
firmware: Fix security issue with request_firmware_into_buf()
vmbus: don't return values for uninitalized channels
fpga: dfl: fme: fix return value check in in pr_mgmt_init()
misc: hmc6352: fix potential Spectre v1
Tools: hv: Fix a bug in the key delete code
misc: ibmvsm: Fix wrong assignment of return code
android: binder: fix the race mmap and alloc_new_buf_locked
mei: bus: need to unlink client before freeing
mei: bus: fix hw module get/put balance
mei: fix use-after-free in mei_cl_write
mei: ignore not found client in the enumeration

+73 -34
+35 -8
drivers/android/binder_alloc.c
··· 332 332 return vma ? -ENOMEM : -ESRCH; 333 333 } 334 334 335 + 336 + static inline void binder_alloc_set_vma(struct binder_alloc *alloc, 337 + struct vm_area_struct *vma) 338 + { 339 + if (vma) 340 + alloc->vma_vm_mm = vma->vm_mm; 341 + /* 342 + * If we see alloc->vma is not NULL, buffer data structures set up 343 + * completely. Look at smp_rmb side binder_alloc_get_vma. 344 + * We also want to guarantee new alloc->vma_vm_mm is always visible 345 + * if alloc->vma is set. 346 + */ 347 + smp_wmb(); 348 + alloc->vma = vma; 349 + } 350 + 351 + static inline struct vm_area_struct *binder_alloc_get_vma( 352 + struct binder_alloc *alloc) 353 + { 354 + struct vm_area_struct *vma = NULL; 355 + 356 + if (alloc->vma) { 357 + /* Look at description in binder_alloc_set_vma */ 358 + smp_rmb(); 359 + vma = alloc->vma; 360 + } 361 + return vma; 362 + } 363 + 335 364 static struct binder_buffer *binder_alloc_new_buf_locked( 336 365 struct binder_alloc *alloc, 337 366 size_t data_size, ··· 377 348 size_t size, data_offsets_size; 378 349 int ret; 379 350 380 - if (alloc->vma == NULL) { 351 + if (!binder_alloc_get_vma(alloc)) { 381 352 binder_alloc_debug(BINDER_DEBUG_USER_ERROR, 382 353 "%d: binder_alloc_buf, no vma\n", 383 354 alloc->pid); ··· 752 723 buffer->free = 1; 753 724 binder_insert_free_buffer(alloc, buffer); 754 725 alloc->free_async_space = alloc->buffer_size / 2; 755 - barrier(); 756 - alloc->vma = vma; 757 - alloc->vma_vm_mm = vma->vm_mm; 726 + binder_alloc_set_vma(alloc, vma); 758 727 mmgrab(alloc->vma_vm_mm); 759 728 760 729 return 0; ··· 781 754 int buffers, page_count; 782 755 struct binder_buffer *buffer; 783 756 784 - BUG_ON(alloc->vma); 785 - 786 757 buffers = 0; 787 758 mutex_lock(&alloc->mutex); 759 + BUG_ON(alloc->vma); 760 + 788 761 while ((n = rb_first(&alloc->allocated_buffers))) { 789 762 buffer = rb_entry(n, struct binder_buffer, rb_node); 790 763 ··· 927 900 */ 928 901 void binder_alloc_vma_close(struct binder_alloc *alloc) 929 902 { 930 - WRITE_ONCE(alloc->vma, NULL); 903 + binder_alloc_set_vma(alloc, NULL); 931 904 } 932 905 933 906 /** ··· 962 935 963 936 index = page - alloc->pages; 964 937 page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; 965 - vma = alloc->vma; 938 + vma = binder_alloc_get_vma(alloc); 966 939 if (vma) { 967 940 if (!mmget_not_zero(alloc->vma_vm_mm)) 968 941 goto err_mmget;
+18 -12
drivers/base/firmware_loader/main.c
··· 209 209 static int alloc_lookup_fw_priv(const char *fw_name, 210 210 struct firmware_cache *fwc, 211 211 struct fw_priv **fw_priv, void *dbuf, 212 - size_t size) 212 + size_t size, enum fw_opt opt_flags) 213 213 { 214 214 struct fw_priv *tmp; 215 215 216 216 spin_lock(&fwc->lock); 217 - tmp = __lookup_fw_priv(fw_name); 218 - if (tmp) { 219 - kref_get(&tmp->ref); 220 - spin_unlock(&fwc->lock); 221 - *fw_priv = tmp; 222 - pr_debug("batched request - sharing the same struct fw_priv and lookup for multiple requests\n"); 223 - return 1; 217 + if (!(opt_flags & FW_OPT_NOCACHE)) { 218 + tmp = __lookup_fw_priv(fw_name); 219 + if (tmp) { 220 + kref_get(&tmp->ref); 221 + spin_unlock(&fwc->lock); 222 + *fw_priv = tmp; 223 + pr_debug("batched request - sharing the same struct fw_priv and lookup for multiple requests\n"); 224 + return 1; 225 + } 224 226 } 227 + 225 228 tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size); 226 - if (tmp) 229 + if (tmp && !(opt_flags & FW_OPT_NOCACHE)) 227 230 list_add(&tmp->list, &fwc->head); 228 231 spin_unlock(&fwc->lock); 229 232 ··· 496 493 */ 497 494 static int 498 495 _request_firmware_prepare(struct firmware **firmware_p, const char *name, 499 - struct device *device, void *dbuf, size_t size) 496 + struct device *device, void *dbuf, size_t size, 497 + enum fw_opt opt_flags) 500 498 { 501 499 struct firmware *firmware; 502 500 struct fw_priv *fw_priv; ··· 515 511 return 0; /* assigned */ 516 512 } 517 513 518 - ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size); 514 + ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size, 515 + opt_flags); 519 516 520 517 /* 521 518 * bind with 'priv' now to avoid warning in failure path ··· 576 571 goto out; 577 572 } 578 573 579 - ret = _request_firmware_prepare(&fw, name, device, buf, size); 574 + ret = _request_firmware_prepare(&fw, name, device, buf, size, 575 + opt_flags); 580 576 if (ret <= 0) /* error or already assigned */ 581 577 goto out; 582 578
+1 -1
drivers/fpga/dfl-fme-pr.c
··· 420 420 /* Create region for each port */ 421 421 fme_region = dfl_fme_create_region(pdata, mgr, 422 422 fme_br->br, i); 423 - if (!fme_region) { 423 + if (IS_ERR(fme_region)) { 424 424 ret = PTR_ERR(fme_region); 425 425 goto destroy_region; 426 426 }
+3
drivers/hv/vmbus_drv.c
··· 1291 1291 if (!attribute->show) 1292 1292 return -EIO; 1293 1293 1294 + if (chan->state != CHANNEL_OPENED_STATE) 1295 + return -EINVAL; 1296 + 1294 1297 return attribute->show(chan, buf); 1295 1298 } 1296 1299
+2
drivers/misc/hmc6352.c
··· 27 27 #include <linux/err.h> 28 28 #include <linux/delay.h> 29 29 #include <linux/sysfs.h> 30 + #include <linux/nospec.h> 30 31 31 32 static DEFINE_MUTEX(compass_mutex); 32 33 ··· 51 50 return ret; 52 51 if (val >= strlen(map)) 53 52 return -EINVAL; 53 + val = array_index_nospec(val, strlen(map)); 54 54 mutex_lock(&compass_mutex); 55 55 ret = compass_command(c, map[val]); 56 56 mutex_unlock(&compass_mutex);
+1 -1
drivers/misc/ibmvmc.c
··· 2131 2131 retrc = plpar_hcall_norets(H_REG_CRQ, 2132 2132 vdev->unit_address, 2133 2133 queue->msg_token, PAGE_SIZE); 2134 - retrc = rc; 2134 + rc = retrc; 2135 2135 2136 2136 if (rc == H_RESOURCE) 2137 2137 rc = ibmvmc_reset_crq_queue(adapter);
+5 -7
drivers/misc/mei/bus.c
··· 521 521 522 522 cl = cldev->cl; 523 523 524 + mutex_lock(&bus->device_lock); 524 525 if (cl->state == MEI_FILE_UNINITIALIZED) { 525 - mutex_lock(&bus->device_lock); 526 526 ret = mei_cl_link(cl); 527 - mutex_unlock(&bus->device_lock); 528 527 if (ret) 529 - return ret; 528 + goto out; 530 529 /* update pointers */ 531 530 cl->cldev = cldev; 532 531 } 533 532 534 - mutex_lock(&bus->device_lock); 535 533 if (mei_cl_is_connected(cl)) { 536 534 ret = 0; 537 535 goto out; ··· 614 616 if (err < 0) 615 617 dev_err(bus->dev, "Could not disconnect from the ME client\n"); 616 618 617 - out: 618 619 mei_cl_bus_module_put(cldev); 619 - 620 + out: 620 621 /* Flush queues and remove any pending read */ 621 622 mei_cl_flush_queues(cl, NULL); 622 623 mei_cl_unlink(cl); ··· 873 876 874 877 mei_me_cl_put(cldev->me_cl); 875 878 mei_dev_bus_put(cldev->bus); 879 + mei_cl_unlink(cldev->cl); 876 880 kfree(cldev->cl); 877 881 kfree(cldev); 878 882 } 879 883 880 884 static const struct device_type mei_cl_device_type = { 881 - .release = mei_cl_bus_dev_release, 885 + .release = mei_cl_bus_dev_release, 882 886 }; 883 887 884 888 /**
+1 -1
drivers/misc/mei/client.c
··· 1767 1767 } 1768 1768 } 1769 1769 1770 - rets = buf->size; 1770 + rets = len; 1771 1771 err: 1772 1772 cl_dbg(dev, cl, "rpm: autosuspend\n"); 1773 1773 pm_runtime_mark_last_busy(dev->dev);
+6 -3
drivers/misc/mei/hbm.c
··· 1161 1161 1162 1162 props_res = (struct hbm_props_response *)mei_msg; 1163 1163 1164 - if (props_res->status) { 1164 + if (props_res->status == MEI_HBMS_CLIENT_NOT_FOUND) { 1165 + dev_dbg(dev->dev, "hbm: properties response: %d CLIENT_NOT_FOUND\n", 1166 + props_res->me_addr); 1167 + } else if (props_res->status) { 1165 1168 dev_err(dev->dev, "hbm: properties response: wrong status = %d %s\n", 1166 1169 props_res->status, 1167 1170 mei_hbm_status_str(props_res->status)); 1168 1171 return -EPROTO; 1172 + } else { 1173 + mei_hbm_me_cl_add(dev, props_res); 1169 1174 } 1170 - 1171 - mei_hbm_me_cl_add(dev, props_res); 1172 1175 1173 1176 /* request property for the next client */ 1174 1177 if (mei_hbm_prop_req(dev, props_res->me_addr + 1))
+1 -1
tools/hv/hv_kvp_daemon.c
··· 286 286 * Found a match; just move the remaining 287 287 * entries up. 288 288 */ 289 - if (i == num_records) { 289 + if (i == (num_records - 1)) { 290 290 kvp_file_info[pool].num_records--; 291 291 kvp_update_file(pool); 292 292 return 0;