已合并
CVE修复: kernel_linux_6.6 master (55 个安全补丁) - 2026-05-22 #384
何京晶创建于 5月22日
CVE修复: kernel_linux_6.6 master (55 个安全补丁) - 2026-05-22 #384
已合并
共 74 个文件变更+480-204
| @@ -133,7 +133,8 @@ raw_copy_to_user(void __user *dst, const void *src, unsigned long size) | |||
| 133 | return copy_user_generic((__force void *)dst, src, size); | 133 | return copy_user_generic((__force void *)dst, src, size); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | -extern long __copy_user_nocache(void *dst, const void __user *src, unsigned size); | 136 | +#define copy_to_nontemporal copy_to_nontemporal |
| 137 | +extern size_t copy_to_nontemporal(void *dst, const void *src, size_t size); | ||
| 137 | extern long __copy_user_flushcache(void *dst, const void __user *src, unsigned size); | 138 | extern long __copy_user_flushcache(void *dst, const void __user *src, unsigned size); |
| 138 | 139 | ||
| 139 | static inline int | 140 | static inline int |
| @@ -143,7 +144,7 @@ __copy_from_user_inatomic_nocache(void *dst, const void __user *src, | |||
| 143 | long ret; | 144 | long ret; |
| 144 | kasan_check_write(dst, size); | 145 | kasan_check_write(dst, size); |
| 145 | stac(); | 146 | stac(); |
| 146 | - ret = __copy_user_nocache(dst, src, size); | 147 | + ret = copy_to_nontemporal(dst, (__force const void *)src, size); |
| 147 | clac(); | 148 | clac(); |
| 148 | return ret; | 149 | return ret; |
| 149 | } | 150 | } |
| @@ -26,7 +26,7 @@ | |||
| 26 | * Output: | 26 | * Output: |
| 27 | * rax uncopied bytes or 0 if successful. | 27 | * rax uncopied bytes or 0 if successful. |
| 28 | */ | 28 | */ |
| 29 | -SYM_FUNC_START(__copy_user_nocache) | 29 | +SYM_FUNC_START(copy_to_nontemporal) |
| 30 | /* If destination is not 7-byte aligned, we'll have to align it */ | 30 | /* If destination is not 7-byte aligned, we'll have to align it */ |
| 31 | testb $7,%dil | 31 | testb $7,%dil |
| 32 | jne .Lalign | 32 | jne .Lalign |
| @@ -238,5 +238,5 @@ _ASM_EXTABLE_UA(95b, .Ldone) | |||
| 238 | _ASM_EXTABLE_UA(52b, .Ldone0) | 238 | _ASM_EXTABLE_UA(52b, .Ldone0) |
| 239 | _ASM_EXTABLE_UA(53b, .Ldone0) | 239 | _ASM_EXTABLE_UA(53b, .Ldone0) |
| 240 | 240 | ||
| 241 | -SYM_FUNC_END(__copy_user_nocache) | 241 | +SYM_FUNC_END(copy_to_nontemporal) |
| 242 | -EXPORT_SYMBOL(__copy_user_nocache) | 242 | +EXPORT_SYMBOL(copy_to_nontemporal) |
| @@ -49,11 +49,11 @@ long __copy_user_flushcache(void *dst, const void __user *src, unsigned size) | |||
| 49 | long rc; | 49 | long rc; |
| 50 | 50 | ||
| 51 | stac(); | 51 | stac(); |
| 52 | - rc = __copy_user_nocache(dst, src, size); | 52 | + rc = copy_to_nontemporal(dst, (__force const void *)src, size); |
| 53 | clac(); | 53 | clac(); |
| 54 | 54 | ||
| 55 | /* | 55 | /* |
| 56 | - * __copy_user_nocache() uses non-temporal stores for the bulk | 56 | + * copy_to_nontemporal() uses non-temporal stores for the bulk |
| 57 | * of the transfer, but we need to manually flush if the | 57 | * of the transfer, but we need to manually flush if the |
| 58 | * transfer is unaligned. A cached memory copy is used when | 58 | * transfer is unaligned. A cached memory copy is used when |
| 59 | * destination or size is not naturally aligned. That is: | 59 | * destination or size is not naturally aligned. That is: |
| @@ -170,7 +170,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, | |||
| 170 | if (usedpages < outlen) { | 170 | if (usedpages < outlen) { |
| 171 | size_t less = outlen - usedpages; | 171 | size_t less = outlen - usedpages; |
| 172 | 172 | ||
| 173 | - if (used < less) { | 173 | + if (used < less + (ctx->enc ? 0 : as)) { |
| 174 | err = -EINVAL; | 174 | err = -EINVAL; |
| 175 | goto free; | 175 | goto free; |
| 176 | } | 176 | } |
| @@ -3325,9 +3325,10 @@ static int ahash_setkey(struct crypto_ahash *ahash, const u8 *key, | |||
| 3325 | if (aligned_len < keylen) | 3325 | if (aligned_len < keylen) |
| 3326 | return -EOVERFLOW; | 3326 | return -EOVERFLOW; |
| 3327 | 3327 | ||
| 3328 | - hashed_key = kmemdup(key, aligned_len, GFP_KERNEL); | 3328 | + hashed_key = kmalloc(aligned_len, GFP_KERNEL); |
| 3329 | if (!hashed_key) | 3329 | if (!hashed_key) |
| 3330 | return -ENOMEM; | 3330 | return -ENOMEM; |
| 3331 | + memcpy(hashed_key, key, keylen); | ||
| 3331 | ret = hash_digest_key(ctx, &keylen, hashed_key, digestsize); | 3332 | ret = hash_digest_key(ctx, &keylen, hashed_key, digestsize); |
| 3332 | if (ret) | 3333 | if (ret) |
| 3333 | goto bad_free_key; | 3334 | goto bad_free_key; |
| @@ -4334,7 +4334,7 @@ static int hidpp_get_report_length(struct hid_device *hdev, int id) | |||
| 4334 | 4334 | ||
| 4335 | re = &(hdev->report_enum[HID_OUTPUT_REPORT]); | 4335 | re = &(hdev->report_enum[HID_OUTPUT_REPORT]); |
| 4336 | report = re->report_id_hash[id]; | 4336 | report = re->report_id_hash[id]; |
| 4337 | - if (!report) | 4337 | + if (!report || !report->maxfield) |
| 4338 | return 0; | 4338 | return 0; |
| 4339 | 4339 | ||
| 4340 | return report->field[0]->report_count + 1; | 4340 | return report->field[0]->report_count + 1; |
| @@ -207,6 +207,7 @@ static int i3c_hci_send_ccc_cmd(struct i3c_master_controller *m, | |||
| 207 | return -ENOMEM; | 207 | return -ENOMEM; |
| 208 | 208 | ||
| 209 | if (prefixed) { | 209 | if (prefixed) { |
| 210 | + mutex_init(&hci->control_mutex); | ||
| 210 | xfer->data = NULL; | 211 | xfer->data = NULL; |
| 211 | xfer->data_len = 0; | 212 | xfer->data_len = 0; |
| 212 | xfer->rnw = false; | 213 | xfer->rnw = false; |
| @@ -449,6 +449,8 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci, | |||
| 449 | unsigned int i; | 449 | unsigned int i; |
| 450 | bool did_unqueue = false; | 450 | bool did_unqueue = false; |
| 451 | 451 | ||
| 452 | + guard(mutex)(&hci->control_mutex); | ||
| 453 | + | ||
| 452 | /* stop the ring */ | 454 | /* stop the ring */ |
| 453 | rh_reg_write(RING_CONTROL, RING_CTRL_ABORT); | 455 | rh_reg_write(RING_CONTROL, RING_CTRL_ABORT); |
| 454 | if (wait_for_completion_timeout(&rh->op_done, HZ) == 0) { | 456 | if (wait_for_completion_timeout(&rh->op_done, HZ) == 0) { |
| @@ -44,6 +44,7 @@ struct i3c_hci { | |||
| 44 | void *io_data; | 44 | void *io_data; |
| 45 | const struct hci_cmd_ops *cmd; | 45 | const struct hci_cmd_ops *cmd; |
| 46 | atomic_t next_cmd_tid; | 46 | atomic_t next_cmd_tid; |
| 47 | + struct mutex control_mutex; | ||
| 47 | u32 caps; | 48 | u32 caps; |
| 48 | unsigned int quirks; | 49 | unsigned int quirks; |
| 49 | unsigned int DAT_entries; | 50 | unsigned int DAT_entries; |
| @@ -205,13 +205,11 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device, | |||
| 205 | 205 | ||
| 206 | err = ib_umem_dmabuf_map_pages(umem_dmabuf); | 206 | err = ib_umem_dmabuf_map_pages(umem_dmabuf); |
| 207 | if (err) | 207 | if (err) |
| 208 | - goto err_unpin; | 208 | + goto err_release; |
| 209 | dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv); | 209 | dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv); |
| 210 | 210 | ||
| 211 | return umem_dmabuf; | 211 | return umem_dmabuf; |
| 212 | 212 | ||
| 213 | -err_unpin: | ||
| 214 | - dma_buf_unpin(umem_dmabuf->attach); | ||
| 215 | err_release: | 213 | err_release: |
| 216 | dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv); | 214 | dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv); |
| 217 | ib_umem_release(&umem_dmabuf->umem); | 215 | ib_umem_release(&umem_dmabuf->umem); |
| @@ -92,12 +92,10 @@ static int rvt_wss_llc_size(void) | |||
| 92 | static void cacheless_memcpy(void *dst, void *src, size_t n) | 92 | static void cacheless_memcpy(void *dst, void *src, size_t n) |
| 93 | { | 93 | { |
| 94 | /* | 94 | /* |
| 95 | - * Use the only available X64 cacheless copy. Add a __user cast | 95 | + * Use the only available X64 cacheless copy. |
| 96 | - * to quiet sparse. The src agument is already in the kernel so | 96 | + * The extra fault recovery machinery is not invoked. |
| 97 | - * there are no security issues. The extra fault recovery machinery | ||
| 98 | - * is not invoked. | ||
| 99 | */ | 97 | */ |
| 100 | - __copy_user_nocache(dst, (void __user *)src, n); | 98 | + copy_to_nontemporal(dst, src, n); |
| 101 | } | 99 | } |
| 102 | 100 | ||
| 103 | void rvt_wss_exit(struct rvt_dev_info *rdi) | 101 | void rvt_wss_exit(struct rvt_dev_info *rdi) |
| @@ -428,7 +428,15 @@ devtlb_invalidation_with_pasid(struct intel_iommu *iommu, | |||
| 428 | if (!info || !info->ats_enabled) | 428 | if (!info || !info->ats_enabled) |
| 429 | return; | 429 | return; |
| 430 | 430 | ||
| 431 | - if (pci_dev_is_disconnected(to_pci_dev(dev))) | 431 | + if (!pci_device_is_present(to_pci_dev(dev))) |
| 432 | + return; | ||
| 433 | + | ||
| 434 | + /* | ||
| 435 | + * Skip dev-IOTLB flush for inaccessible PCIe devices to prevent the | ||
| 436 | + * Intel IOMMU from waiting indefinitely for an ATS invalidation that | ||
| 437 | + * cannot complete. | ||
| 438 | + */ | ||
| 439 | + if (!pci_device_is_present(to_pci_dev(info->dev))) | ||
| 432 | return; | 440 | return; |
| 433 | 441 | ||
| 434 | sid = info->bus << 8 | info->devfn; | 442 | sid = info->bus << 8 | info->devfn; |
| @@ -509,12 +509,10 @@ static struct mbox_chan * | |||
| 509 | of_mbox_index_xlate(struct mbox_controller *mbox, | 509 | of_mbox_index_xlate(struct mbox_controller *mbox, |
| 510 | const struct of_phandle_args *sp) | 510 | const struct of_phandle_args *sp) |
| 511 | { | 511 | { |
| 512 | - int ind = sp->args[0]; | 512 | + if (sp->args_count < 1 || sp->args[0] >= mbox->num_chans) |
| 513 | - | ||
| 514 | - if (ind >= mbox->num_chans) | ||
| 515 | return ERR_PTR(-EINVAL); | 513 | return ERR_PTR(-EINVAL); |
| 516 | 514 | ||
| 517 | - return &mbox->chans[ind]; | 515 | + return &mbox->chans[sp->args[0]]; |
| 518 | } | 516 | } |
| 519 | 517 | ||
| 520 | /** | 518 | /** |
| @@ -6308,13 +6308,15 @@ static void __md_stop_writes(struct mddev *mddev) | |||
| 6308 | 6308 | ||
| 6309 | del_timer_sync(&mddev->safemode_timer); | 6309 | del_timer_sync(&mddev->safemode_timer); |
| 6310 | 6310 | ||
| 6311 | - if (mddev->pers && mddev->pers->quiesce) { | 6311 | + if (md_is_rdwr(mddev) || !mddev_is_dm(mddev)) { |
| 6312 | - mddev->pers->quiesce(mddev, 1); | 6312 | + if (mddev->pers && mddev->pers->quiesce) { |
| 6313 | - mddev->pers->quiesce(mddev, 0); | 6313 | + mddev->pers->quiesce(mddev, 1); |
| 6314 | - } | 6314 | + mddev->pers->quiesce(mddev, 0); |
| 6315 | - md_bitmap_flush(mddev); | 6315 | + } |
| 6316 | 6316 | ||
| 6317 | - if (md_is_rdwr(mddev) && | 6317 | + if (md_bitmap_enabled(mddev, true)) |
| 6318 | + mddev->bitmap_ops->flush(mddev); | ||
| 6319 | + } | ||
| 6318 | ((!mddev->in_sync && !mddev_is_clustered(mddev)) || | 6320 | ((!mddev->in_sync && !mddev_is_clustered(mddev)) || |
| 6319 | mddev->sb_flags)) { | 6321 | mddev->sb_flags)) { |
| 6320 | /* mark array as shutdown cleanly */ | 6322 | /* mark array as shutdown cleanly */ |
| @@ -77,6 +77,7 @@ struct hantro_irq { | |||
| 77 | * @double_buffer: core needs double buffering | 77 | * @double_buffer: core needs double buffering |
| 78 | * @legacy_regs: core uses legacy register set | 78 | * @legacy_regs: core uses legacy register set |
| 79 | * @late_postproc: postproc must be set up at the end of the job | 79 | * @late_postproc: postproc must be set up at the end of the job |
| 80 | + * @shared_devices: an array of device ids that cannot run concurrently | ||
| 80 | */ | 81 | */ |
| 81 | struct hantro_variant { | 82 | struct hantro_variant { |
| 82 | unsigned int enc_offset; | 83 | unsigned int enc_offset; |
| @@ -101,6 +102,7 @@ struct hantro_variant { | |||
| 101 | unsigned int double_buffer : 1; | 102 | unsigned int double_buffer : 1; |
| 102 | unsigned int legacy_regs : 1; | 103 | unsigned int legacy_regs : 1; |
| 103 | unsigned int late_postproc : 1; | 104 | unsigned int late_postproc : 1; |
| 105 | + const struct of_device_id *shared_devices; | ||
| 104 | }; | 106 | }; |
| 105 | 107 | ||
| 106 | /** | 108 | /** |
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | + | ||
| 16 | 17 | ||
| 17 | 18 | ||
| 18 | 19 | ||
| @@ -985,6 +986,41 @@ static const struct media_device_ops hantro_m2m_media_ops = { | |||
| 985 | .req_queue = v4l2_m2m_request_queue, | 986 | .req_queue = v4l2_m2m_request_queue, |
| 986 | }; | 987 | }; |
| 987 | 988 | ||
| 989 | +static struct v4l2_m2m_dev *hantro_get_v4l2_m2m_dev(struct hantro_dev *vpu) | ||
| 990 | +{ | ||
| 991 | + struct device_node *node; | ||
| 992 | + struct hantro_dev *shared_vpu; | ||
| 993 | + | ||
| 994 | + if (!vpu->variant || !vpu->variant->shared_devices) | ||
| 995 | + goto init_new_m2m_dev; | ||
| 996 | + | ||
| 997 | + for_each_matching_node(node, vpu->variant->shared_devices) { | ||
| 998 | + struct platform_device *pdev; | ||
| 999 | + struct v4l2_m2m_dev *m2m_dev; | ||
| 1000 | + | ||
| 1001 | + pdev = of_find_device_by_node(node); | ||
| 1002 | + if (!pdev) | ||
| 1003 | + continue; | ||
| 1004 | + | ||
| 1005 | + shared_vpu = platform_get_drvdata(pdev); | ||
| 1006 | + if (IS_ERR_OR_NULL(shared_vpu) || shared_vpu == vpu) { | ||
| 1007 | + platform_device_put(pdev); | ||
| 1008 | + continue; | ||
| 1009 | + } | ||
| 1010 | + | ||
| 1011 | + v4l2_m2m_get(shared_vpu->m2m_dev); | ||
| 1012 | + m2m_dev = shared_vpu->m2m_dev; | ||
| 1013 | + platform_device_put(pdev); | ||
| 1014 | + | ||
| 1015 | + of_node_put(node); | ||
| 1016 | + | ||
| 1017 | + return m2m_dev; | ||
| 1018 | + } | ||
| 1019 | + | ||
| 1020 | +init_new_m2m_dev: | ||
| 1021 | + return v4l2_m2m_init(&vpu_m2m_ops); | ||
| 1022 | +} | ||
| 1023 | + | ||
| 988 | static int hantro_probe(struct platform_device *pdev) | 1024 | static int hantro_probe(struct platform_device *pdev) |
| 989 | { | 1025 | { |
| 990 | const struct of_device_id *match; | 1026 | const struct of_device_id *match; |
| @@ -1132,7 +1168,7 @@ static int hantro_probe(struct platform_device *pdev) | |||
| 1132 | } | 1168 | } |
| 1133 | platform_set_drvdata(pdev, vpu); | 1169 | platform_set_drvdata(pdev, vpu); |
| 1134 | 1170 | ||
| 1135 | - vpu->m2m_dev = v4l2_m2m_init(&vpu_m2m_ops); | 1171 | + vpu->m2m_dev = hantro_get_v4l2_m2m_dev(vpu); |
| 1136 | if (IS_ERR(vpu->m2m_dev)) { | 1172 | if (IS_ERR(vpu->m2m_dev)) { |
| 1137 | v4l2_err(&vpu->v4l2_dev, "Failed to init mem2mem device\n"); | 1173 | v4l2_err(&vpu->v4l2_dev, "Failed to init mem2mem device\n"); |
| 1138 | ret = PTR_ERR(vpu->m2m_dev); | 1174 | ret = PTR_ERR(vpu->m2m_dev); |
| @@ -1171,7 +1207,7 @@ static int hantro_probe(struct platform_device *pdev) | |||
| 1171 | hantro_remove_enc_func(vpu); | 1207 | hantro_remove_enc_func(vpu); |
| 1172 | err_m2m_rel: | 1208 | err_m2m_rel: |
| 1173 | media_device_cleanup(&vpu->mdev); | 1209 | media_device_cleanup(&vpu->mdev); |
| 1174 | - v4l2_m2m_release(vpu->m2m_dev); | 1210 | + v4l2_m2m_put(vpu->m2m_dev); |
| 1175 | err_v4l2_unreg: | 1211 | err_v4l2_unreg: |
| 1176 | v4l2_device_unregister(&vpu->v4l2_dev); | 1212 | v4l2_device_unregister(&vpu->v4l2_dev); |
| 1177 | err_clk_unprepare: | 1213 | err_clk_unprepare: |
| @@ -1194,7 +1230,7 @@ static void hantro_remove(struct platform_device *pdev) | |||
| 1194 | hantro_remove_dec_func(vpu); | 1230 | hantro_remove_dec_func(vpu); |
| 1195 | hantro_remove_enc_func(vpu); | 1231 | hantro_remove_enc_func(vpu); |
| 1196 | media_device_cleanup(&vpu->mdev); | 1232 | media_device_cleanup(&vpu->mdev); |
| 1197 | - v4l2_m2m_release(vpu->m2m_dev); | 1233 | + v4l2_m2m_put(vpu->m2m_dev); |
| 1198 | v4l2_device_unregister(&vpu->v4l2_dev); | 1234 | v4l2_device_unregister(&vpu->v4l2_dev); |
| 1199 | clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); | 1235 | clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); |
| 1200 | reset_control_assert(vpu->resets); | 1236 | reset_control_assert(vpu->resets); |
| @@ -359,6 +359,12 @@ const struct hantro_variant imx8mq_vpu_variant = { | |||
| 359 | .num_regs = ARRAY_SIZE(imx8mq_reg_names) | 359 | .num_regs = ARRAY_SIZE(imx8mq_reg_names) |
| 360 | }; | 360 | }; |
| 361 | 361 | ||
| 362 | +static const struct of_device_id imx8mq_vpu_shared_resources[] __initconst = { | ||
| 363 | + { .compatible = "nxp,imx8mq-vpu-g1", }, | ||
| 364 | + { .compatible = "nxp,imx8mq-vpu-g2", }, | ||
| 365 | + { /* sentinel */ } | ||
| 366 | +}; | ||
| 367 | + | ||
| 362 | const struct hantro_variant imx8mq_vpu_g1_variant = { | 368 | const struct hantro_variant imx8mq_vpu_g1_variant = { |
| 363 | .dec_fmts = imx8m_vpu_dec_fmts, | 369 | .dec_fmts = imx8m_vpu_dec_fmts, |
| 364 | .num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts), | 370 | .num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts), |
| @@ -372,6 +378,7 @@ const struct hantro_variant imx8mq_vpu_g1_variant = { | |||
| 372 | .num_irqs = ARRAY_SIZE(imx8mq_irqs), | 378 | .num_irqs = ARRAY_SIZE(imx8mq_irqs), |
| 373 | .clk_names = imx8mq_g1_clk_names, | 379 | .clk_names = imx8mq_g1_clk_names, |
| 374 | .num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names), | 380 | .num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names), |
| 381 | + .shared_devices = imx8mq_vpu_shared_resources, | ||
| 375 | }; | 382 | }; |
| 376 | 383 | ||
| 377 | const struct hantro_variant imx8mq_vpu_g2_variant = { | 384 | const struct hantro_variant imx8mq_vpu_g2_variant = { |
| @@ -387,6 +394,7 @@ const struct hantro_variant imx8mq_vpu_g2_variant = { | |||
| 387 | .num_irqs = ARRAY_SIZE(imx8mq_g2_irqs), | 394 | .num_irqs = ARRAY_SIZE(imx8mq_g2_irqs), |
| 388 | .clk_names = imx8mq_g2_clk_names, | 395 | .clk_names = imx8mq_g2_clk_names, |
| 389 | .num_clocks = ARRAY_SIZE(imx8mq_g2_clk_names), | 396 | .num_clocks = ARRAY_SIZE(imx8mq_g2_clk_names), |
| 397 | + .shared_devices = imx8mq_vpu_shared_resources, | ||
| 390 | }; | 398 | }; |
| 391 | 399 | ||
| 392 | const struct hantro_variant imx8mm_vpu_g1_variant = { | 400 | const struct hantro_variant imx8mm_vpu_g1_variant = { |
| @@ -1541,6 +1541,50 @@ static void bond_compute_features(struct bonding *bond) | |||
| 1541 | netdev_change_features(bond_dev); | 1541 | netdev_change_features(bond_dev); |
| 1542 | } | 1542 | } |
| 1543 | 1543 | ||
| 1544 | +static int bond_header_create(struct sk_buff *skb, struct net_device *bond_dev, | ||
| 1545 | + unsigned short type, const void *daddr, | ||
| 1546 | + const void *saddr, unsigned int len) | ||
| 1547 | +{ | ||
| 1548 | + struct bonding *bond = netdev_priv(bond_dev); | ||
| 1549 | + const struct header_ops *slave_ops; | ||
| 1550 | + struct slave *slave; | ||
| 1551 | + int ret = 0; | ||
| 1552 | + | ||
| 1553 | + rcu_read_lock(); | ||
| 1554 | + slave = rcu_dereference(bond->curr_active_slave); | ||
| 1555 | + if (slave) { | ||
| 1556 | + slave_ops = READ_ONCE(slave->dev->header_ops); | ||
| 1557 | + if (slave_ops && slave_ops->create) | ||
| 1558 | + ret = slave_ops->create(skb, slave->dev, | ||
| 1559 | + type, daddr, saddr, len); | ||
| 1560 | + } | ||
| 1561 | + rcu_read_unlock(); | ||
| 1562 | + return ret; | ||
| 1563 | +} | ||
| 1564 | + | ||
| 1565 | +static int bond_header_parse(const struct sk_buff *skb, unsigned char *haddr) | ||
| 1566 | +{ | ||
| 1567 | + struct bonding *bond = netdev_priv(skb->dev); | ||
| 1568 | + const struct header_ops *slave_ops; | ||
| 1569 | + struct slave *slave; | ||
| 1570 | + int ret = 0; | ||
| 1571 | + | ||
| 1572 | + rcu_read_lock(); | ||
| 1573 | + slave = rcu_dereference(bond->curr_active_slave); | ||
| 1574 | + if (slave) { | ||
| 1575 | + slave_ops = READ_ONCE(slave->dev->header_ops); | ||
| 1576 | + if (slave_ops && slave_ops->parse) | ||
| 1577 | + ret = slave_ops->parse(skb, haddr); | ||
| 1578 | + } | ||
| 1579 | + rcu_read_unlock(); | ||
| 1580 | + return ret; | ||
| 1581 | +} | ||
| 1582 | + | ||
| 1583 | +static const struct header_ops bond_header_ops = { | ||
| 1584 | + .create = bond_header_create, | ||
| 1585 | + .parse = bond_header_parse, | ||
| 1586 | +}; | ||
| 1587 | + | ||
| 1544 | static void bond_setup_by_slave(struct net_device *bond_dev, | 1588 | static void bond_setup_by_slave(struct net_device *bond_dev, |
| 1545 | struct net_device *slave_dev) | 1589 | struct net_device *slave_dev) |
| 1546 | { | 1590 | { |
| @@ -1548,7 +1592,8 @@ static void bond_setup_by_slave(struct net_device *bond_dev, | |||
| 1548 | 1592 | ||
| 1549 | dev_close(bond_dev); | 1593 | dev_close(bond_dev); |
| 1550 | 1594 | ||
| 1551 | - bond_dev->header_ops = slave_dev->header_ops; | 1595 | + bond_dev->header_ops = slave_dev->header_ops ? |
| 1596 | + &bond_header_ops : NULL; | ||
| 1552 | 1597 | ||
| 1553 | bond_dev->type = slave_dev->type; | 1598 | bond_dev->type = slave_dev->type; |
| 1554 | bond_dev->hard_header_len = slave_dev->hard_header_len; | 1599 | bond_dev->hard_header_len = slave_dev->hard_header_len; |
| @@ -3431,7 +3476,7 @@ int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond, | |||
| 3431 | } else if (is_arp) { | 3476 | } else if (is_arp) { |
| 3432 | return bond_arp_rcv(skb, bond, slave); | 3477 | return bond_arp_rcv(skb, bond, slave); |
| 3433 | 3478 | ||
| 3434 | - } else if (is_ipv6) { | 3479 | + } else if (is_ipv6 && likely(ipv6_mod_enabled())) { |
| 3435 | return bond_na_rcv(skb, bond, slave); | 3480 | return bond_na_rcv(skb, bond, slave); |
| 3436 | 3481 | ||
| 3437 | } else { | 3482 | } else { |
| @@ -46,7 +46,6 @@ static void mlx5e_reset_txqsq_cc_pc(struct mlx5e_txqsq *sq) | |||
| 46 | "SQ 0x%x: cc (0x%x) != pc (0x%x)\n", | 46 | "SQ 0x%x: cc (0x%x) != pc (0x%x)\n", |
| 47 | sq->sqn, sq->cc, sq->pc); | 47 | sq->sqn, sq->cc, sq->pc); |
| 48 | sq->cc = 0; | 48 | sq->cc = 0; |
| 49 | - sq->dma_fifo_cc = 0; | ||
| 50 | sq->pc = 0; | 49 | sq->pc = 0; |
| 51 | } | 50 | } |
| 52 | 51 | ||
| @@ -265,7 +265,6 @@ static void mlx5e_ipsec_init_limits(struct mlx5e_ipsec_sa_entry *sa_entry, | |||
| 265 | static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry, | 265 | static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry, |
| 266 | struct mlx5_accel_esp_xfrm_attrs *attrs) | 266 | struct mlx5_accel_esp_xfrm_attrs *attrs) |
| 267 | { | 267 | { |
| 268 | - struct mlx5_core_dev *mdev = mlx5e_ipsec_sa2dev(sa_entry); | ||
| 269 | struct xfrm_state *x = sa_entry->x; | 268 | struct xfrm_state *x = sa_entry->x; |
| 270 | struct net_device *netdev; | 269 | struct net_device *netdev; |
| 271 | struct neighbour *n; | 270 | struct neighbour *n; |
| @@ -278,8 +277,8 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry, | |||
| 278 | return; | 277 | return; |
| 279 | 278 | ||
| 280 | netdev = x->xso.real_dev; | 279 | netdev = x->xso.real_dev; |
| 280 | + ether_addr_copy(addr, netdev->dev_addr); | ||
| 281 | 281 | ||
| 282 | - mlx5_query_mac_address(mdev, addr); | ||
| 283 | switch (attrs->dir) { | 282 | switch (attrs->dir) { |
| 284 | case XFRM_DEV_OFFLOAD_IN: | 283 | case XFRM_DEV_OFFLOAD_IN: |
| 285 | src = attrs->dmac; | 284 | src = attrs->dmac; |
| @@ -1049,10 +1049,11 @@ static void mlx5_eswitch_event_handler_register(struct mlx5_eswitch *esw) | |||
| 1049 | 1049 | ||
| 1050 | static void mlx5_eswitch_event_handler_unregister(struct mlx5_eswitch *esw) | 1050 | static void mlx5_eswitch_event_handler_unregister(struct mlx5_eswitch *esw) |
| 1051 | { | 1051 | { |
| 1052 | - if (esw->mode == MLX5_ESWITCH_OFFLOADS && mlx5_eswitch_is_funcs_handler(esw->dev)) | 1052 | + if (esw->mode == MLX5_ESWITCH_OFFLOADS && |
| 1053 | + mlx5_eswitch_is_funcs_handler(esw->dev)) { | ||
| 1053 | mlx5_eq_notifier_unregister(esw->dev, &esw->esw_funcs.nb); | 1054 | mlx5_eq_notifier_unregister(esw->dev, &esw->esw_funcs.nb); |
| 1054 | - | 1055 | + atomic_inc(&esw->esw_funcs.generation); |
| 1055 | - flush_workqueue(esw->work_queue); | 1056 | + } |
| 1056 | } | 1057 | } |
| 1057 | 1058 | ||
| 1058 | static void mlx5_eswitch_clear_vf_vports_info(struct mlx5_eswitch *esw) | 1059 | static void mlx5_eswitch_clear_vf_vports_info(struct mlx5_eswitch *esw) |
| @@ -311,10 +311,12 @@ struct esw_mc_addr { /* SRIOV only */ | |||
| 311 | struct mlx5_host_work { | 311 | struct mlx5_host_work { |
| 312 | struct work_struct work; | 312 | struct work_struct work; |
| 313 | struct mlx5_eswitch *esw; | 313 | struct mlx5_eswitch *esw; |
| 314 | + int work_gen; | ||
| 314 | }; | 315 | }; |
| 315 | 316 | ||
| 316 | struct mlx5_esw_functions { | 317 | struct mlx5_esw_functions { |
| 317 | struct mlx5_nb nb; | 318 | struct mlx5_nb nb; |
| 319 | + atomic_t generation; | ||
| 318 | u16 num_vfs; | 320 | u16 num_vfs; |
| 319 | u16 num_ec_vfs; | 321 | u16 num_ec_vfs; |
| 320 | }; | 322 | }; |
| @@ -3386,22 +3386,28 @@ static void esw_offloads_steering_cleanup(struct mlx5_eswitch *esw) | |||
| 3386 | } | 3386 | } |
| 3387 | 3387 | ||
| 3388 | static void | 3388 | static void |
| 3389 | -esw_vfs_changed_event_handler(struct mlx5_eswitch *esw, const u32 *out) | 3389 | +esw_vfs_changed_event_handler(struct mlx5_eswitch *esw, int work_gen, |
| 3390 | + const u32 *out) | ||
| 3390 | { | 3391 | { |
| 3391 | struct devlink *devlink; | 3392 | struct devlink *devlink; |
| 3392 | bool host_pf_disabled; | 3393 | bool host_pf_disabled; |
| 3393 | u16 new_num_vfs; | 3394 | u16 new_num_vfs; |
| 3394 | 3395 | ||
| 3396 | + devlink = priv_to_devlink(esw->dev); | ||
| 3397 | + devl_lock(devlink); | ||
| 3398 | + | ||
| 3399 | + /* Stale work from one or more mode changes ago. Bail out. */ | ||
| 3400 | + if (work_gen != atomic_read(&esw->esw_funcs.generation)) | ||
| 3401 | + goto unlock; | ||
| 3402 | + | ||
| 3395 | new_num_vfs = MLX5_GET(query_esw_functions_out, out, | 3403 | new_num_vfs = MLX5_GET(query_esw_functions_out, out, |
| 3396 | host_params_context.host_num_of_vfs); | 3404 | host_params_context.host_num_of_vfs); |
| 3397 | host_pf_disabled = MLX5_GET(query_esw_functions_out, out, | 3405 | host_pf_disabled = MLX5_GET(query_esw_functions_out, out, |
| 3398 | host_params_context.host_pf_disabled); | 3406 | host_params_context.host_pf_disabled); |
| 3399 | 3407 | ||
| 3400 | if (new_num_vfs == esw->esw_funcs.num_vfs || host_pf_disabled) | 3408 | if (new_num_vfs == esw->esw_funcs.num_vfs || host_pf_disabled) |
| 3401 | - return; | 3409 | + goto unlock; |
| 3402 | 3410 | ||
| 3403 | - devlink = priv_to_devlink(esw->dev); | ||
| 3404 | - devl_lock(devlink); | ||
| 3405 | /* Number of VFs can only change from "0 to x" or "x to 0". */ | 3411 | /* Number of VFs can only change from "0 to x" or "x to 0". */ |
| 3406 | if (esw->esw_funcs.num_vfs > 0) { | 3412 | if (esw->esw_funcs.num_vfs > 0) { |
| 3407 | mlx5_eswitch_unload_vf_vports(esw, esw->esw_funcs.num_vfs); | 3413 | mlx5_eswitch_unload_vf_vports(esw, esw->esw_funcs.num_vfs); |
| @@ -3416,6 +3422,7 @@ esw_vfs_changed_event_handler(struct mlx5_eswitch *esw, const u32 *out) | |||
| 3416 | } | 3422 | } |
| 3417 | } | 3423 | } |
| 3418 | esw->esw_funcs.num_vfs = new_num_vfs; | 3424 | esw->esw_funcs.num_vfs = new_num_vfs; |
| 3425 | +unlock: | ||
| 3419 | devl_unlock(devlink); | 3426 | devl_unlock(devlink); |
| 3420 | } | 3427 | } |
| 3421 | 3428 | ||
| @@ -3432,7 +3439,7 @@ static void esw_functions_changed_event_handler(struct work_struct *work) | |||
| 3432 | if (IS_ERR(out)) | 3439 | if (IS_ERR(out)) |
| 3433 | goto out; | 3440 | goto out; |
| 3434 | 3441 | ||
| 3435 | - esw_vfs_changed_event_handler(esw, out); | 3442 | + esw_vfs_changed_event_handler(esw, host_work->work_gen, out); |
| 3436 | kvfree(out); | 3443 | kvfree(out); |
| 3437 | out: | 3444 | out: |
| 3438 | kfree(host_work); | 3445 | kfree(host_work); |
| @@ -3452,6 +3459,7 @@ int mlx5_esw_funcs_changed_handler(struct notifier_block *nb, unsigned long type | |||
| 3452 | esw = container_of(esw_funcs, struct mlx5_eswitch, esw_funcs); | 3459 | esw = container_of(esw_funcs, struct mlx5_eswitch, esw_funcs); |
| 3453 | 3460 | ||
| 3454 | host_work->esw = esw; | 3461 | host_work->esw = esw; |
| 3462 | + host_work->work_gen = atomic_read(&esw_funcs->generation); | ||
| 3455 | 3463 | ||
| 3456 | INIT_WORK(&host_work->work, esw_functions_changed_event_handler); | 3464 | INIT_WORK(&host_work->work, esw_functions_changed_event_handler); |
| 3457 | queue_work(esw->work_queue, &host_work->work); | 3465 | queue_work(esw->work_queue, &host_work->work); |
| @@ -161,10 +161,10 @@ struct txgbe_nodes { | |||
| 161 | char i2c_name[32]; | 161 | char i2c_name[32]; |
| 162 | char sfp_name[32]; | 162 | char sfp_name[32]; |
| 163 | char phylink_name[32]; | 163 | char phylink_name[32]; |
| 164 | - struct property_entry gpio_props[1]; | 164 | + struct property_entry gpio_props[2]; |
| 165 | - struct property_entry i2c_props[3]; | 165 | + struct property_entry i2c_props[4]; |
| 166 | - struct property_entry sfp_props[8]; | 166 | + struct property_entry sfp_props[9]; |
| 167 | - struct property_entry phylink_props[2]; | 167 | + struct property_entry phylink_props[3]; |
| 168 | struct software_node_ref_args i2c_ref[1]; | 168 | struct software_node_ref_args i2c_ref[1]; |
| 169 | struct software_node_ref_args gpio0_ref[1]; | 169 | struct software_node_ref_args gpio0_ref[1]; |
| 170 | struct software_node_ref_args gpio1_ref[1]; | 170 | struct software_node_ref_args gpio1_ref[1]; |
| @@ -765,7 +765,6 @@ static void kaweth_set_rx_mode(struct net_device *net) | |||
| 765 | 765 | ||
| 766 | netdev_dbg(net, "Setting Rx mode to %d\n", packet_filter_bitmap); | 766 | netdev_dbg(net, "Setting Rx mode to %d\n", packet_filter_bitmap); |
| 767 | 767 | ||
| 768 | - netif_stop_queue(net); | ||
| 769 | 768 | ||
| 770 | if (net->flags & IFF_PROMISC) { | 769 | if (net->flags & IFF_PROMISC) { |
| 771 | packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS; | 770 | packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS; |
| @@ -775,7 +774,6 @@ static void kaweth_set_rx_mode(struct net_device *net) | |||
| 775 | } | 774 | } |
| 776 | 775 | ||
| 777 | kaweth->packet_filter_bitmap = packet_filter_bitmap; | 776 | kaweth->packet_filter_bitmap = packet_filter_bitmap; |
| 778 | - netif_wake_queue(net); | ||
| 779 | } | 777 | } |
| 780 | 778 | ||
| 781 | /**************************************************************** | 779 | /**************************************************************** |
| @@ -1800,12 +1800,13 @@ static void ntb_tx_copy_callback(void *data, | |||
| 1800 | 1800 | ||
| 1801 | static void ntb_memcpy_tx(struct ntb_queue_entry *entry, void __iomem *offset) | 1801 | static void ntb_memcpy_tx(struct ntb_queue_entry *entry, void __iomem *offset) |
| 1802 | { | 1802 | { |
| 1803 | -#ifdef ARCH_HAS_NOCACHE_UACCESS | 1803 | +#ifdef copy_to_nontemporal |
| 1804 | /* | 1804 | /* |
| 1805 | * Using non-temporal mov to improve performance on non-cached | 1805 | * Using non-temporal mov to improve performance on non-cached |
| 1806 | - * writes, even though we aren't actually copying from user space. | 1806 | + * writes. This only works if __iomem is strictly memory-like, |
| 1807 | + * but that is the case on x86-64 | ||
| 1807 | */ | 1808 | */ |
| 1808 | - __copy_from_user_inatomic_nocache(offset, entry->buf, entry->len); | 1809 | + copy_to_nontemporal(offset, entry->buf, entry->len); |
| 1809 | 1810 | ||
| 1810 | memcpy_toio(offset, entry->buf, entry->len); | 1811 | memcpy_toio(offset, entry->buf, entry->len); |
| 1811 | 1812 | ||
| @@ -2521,7 +2521,7 @@ int hisi_sas_probe(struct platform_device *pdev, | |||
| 2521 | shost->transportt = hisi_sas_stt; | 2521 | shost->transportt = hisi_sas_stt; |
| 2522 | shost->max_id = HISI_SAS_MAX_DEVICES; | 2522 | shost->max_id = HISI_SAS_MAX_DEVICES; |
| 2523 | shost->max_lun = ~0; | 2523 | shost->max_lun = ~0; |
| 2524 | - shost->max_channel = 1; | 2524 | + shost->max_channel = 0; |
| 2525 | shost->max_cmd_len = 16; | 2525 | shost->max_cmd_len = 16; |
| 2526 | if (hisi_hba->hw->slot_index_alloc) { | 2526 | if (hisi_hba->hw->slot_index_alloc) { |
| 2527 | shost->can_queue = HISI_SAS_MAX_COMMANDS; | 2527 | shost->can_queue = HISI_SAS_MAX_COMMANDS; |
| @@ -5026,7 +5026,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 5026 | shost->transportt = hisi_sas_stt; | 5026 | shost->transportt = hisi_sas_stt; |
| 5027 | shost->max_id = HISI_SAS_MAX_DEVICES; | 5027 | shost->max_id = HISI_SAS_MAX_DEVICES; |
| 5028 | shost->max_lun = ~0; | 5028 | shost->max_lun = ~0; |
| 5029 | - shost->max_channel = 1; | 5029 | + shost->max_channel = 0; |
| 5030 | shost->max_cmd_len = 16; | 5030 | shost->max_cmd_len = 16; |
| 5031 | shost->can_queue = HISI_SAS_UNRESERVED_IPTT; | 5031 | shost->can_queue = HISI_SAS_UNRESERVED_IPTT; |
| 5032 | shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; | 5032 | shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; |
| @@ -1860,8 +1860,9 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) | |||
| 1860 | cmd_request->payload_sz = payload_sz; | 1860 | cmd_request->payload_sz = payload_sz; |
| 1861 | 1861 | ||
| 1862 | /* Invokes the vsc to start an IO */ | 1862 | /* Invokes the vsc to start an IO */ |
| 1863 | - ret = storvsc_do_io(dev, cmd_request, get_cpu()); | 1863 | + migrate_disable(); |
| 1864 | - put_cpu(); | 1864 | + ret = storvsc_do_io(dev, cmd_request, smp_processor_id()); |
| 1865 | + migrate_enable(); | ||
| 1865 | 1866 | ||
| 1866 | if (ret) | 1867 | if (ret) |
| 1867 | scsi_dma_unmap(scmnd); | 1868 | scsi_dma_unmap(scmnd); |
| @@ -74,7 +74,6 @@ struct spidev_data { | |||
| 74 | struct list_head device_entry; | 74 | struct list_head device_entry; |
| 75 | 75 | ||
| 76 | /* TX/RX buffers are NULL unless this device is open (users > 0) */ | 76 | /* TX/RX buffers are NULL unless this device is open (users > 0) */ |
| 77 | - struct mutex buf_lock; | ||
| 78 | unsigned users; | 77 | unsigned users; |
| 79 | u8 *tx_buffer; | 78 | u8 *tx_buffer; |
| 80 | u8 *rx_buffer; | 79 | u8 *rx_buffer; |
| @@ -102,24 +101,6 @@ spidev_sync_unlocked(struct spi_device *spi, struct spi_message *message) | |||
| 102 | return status; | 101 | return status; |
| 103 | } | 102 | } |
| 104 | 103 | ||
| 105 | -static ssize_t | ||
| 106 | -spidev_sync(struct spidev_data *spidev, struct spi_message *message) | ||
| 107 | -{ | ||
| 108 | - ssize_t status; | ||
| 109 | - struct spi_device *spi; | ||
| 110 | - | ||
| 111 | - mutex_lock(&spidev->spi_lock); | ||
| 112 | - spi = spidev->spi; | ||
| 113 | - | ||
| 114 | - if (spi == NULL) | ||
| 115 | - status = -ESHUTDOWN; | ||
| 116 | - else | ||
| 117 | - status = spidev_sync_unlocked(spi, message); | ||
| 118 | - | ||
| 119 | - mutex_unlock(&spidev->spi_lock); | ||
| 120 | - return status; | ||
| 121 | -} | ||
| 122 | - | ||
| 123 | static inline ssize_t | 104 | static inline ssize_t |
| 124 | spidev_sync_write(struct spidev_data *spidev, size_t len) | 105 | spidev_sync_write(struct spidev_data *spidev, size_t len) |
| 125 | { | 106 | { |
| @@ -132,7 +113,8 @@ spidev_sync_write(struct spidev_data *spidev, size_t len) | |||
| 132 | 113 | ||
| 133 | spi_message_init(&m); | 114 | spi_message_init(&m); |
| 134 | spi_message_add_tail(&t, &m); | 115 | spi_message_add_tail(&t, &m); |
| 135 | - return spidev_sync(spidev, &m); | 116 | + |
| 117 | + return spidev_sync_unlocked(spidev->spi, &m); | ||
| 136 | } | 118 | } |
| 137 | 119 | ||
| 138 | static inline ssize_t | 120 | static inline ssize_t |
| @@ -147,7 +129,8 @@ spidev_sync_read(struct spidev_data *spidev, size_t len) | |||
| 147 | 129 | ||
| 148 | spi_message_init(&m); | 130 | spi_message_init(&m); |
| 149 | spi_message_add_tail(&t, &m); | 131 | spi_message_add_tail(&t, &m); |
| 150 | - return spidev_sync(spidev, &m); | 132 | + |
| 133 | + return spidev_sync_unlocked(spidev->spi, &m); | ||
| 151 | } | 134 | } |
| 152 | 135 | ||
| 153 | /*-------------------------------------------------------------------------*/ | 136 | /*-------------------------------------------------------------------------*/ |
| @@ -157,7 +140,7 @@ static ssize_t | |||
| 157 | spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) | 140 | spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) |
| 158 | { | 141 | { |
| 159 | struct spidev_data *spidev; | 142 | struct spidev_data *spidev; |
| 160 | - ssize_t status; | 143 | + ssize_t status = -ESHUTDOWN; |
| 161 | 144 | ||
| 162 | /* chipselect only toggles at start or end of operation */ | 145 | /* chipselect only toggles at start or end of operation */ |
| 163 | if (count > bufsiz) | 146 | if (count > bufsiz) |
| @@ -165,7 +148,11 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) | |||
| 165 | 148 | ||
| 166 | spidev = filp->private_data; | 149 | spidev = filp->private_data; |
| 167 | 150 | ||
| 168 | - mutex_lock(&spidev->buf_lock); | 151 | + mutex_lock(&spidev->spi_lock); |
| 152 | + | ||
| 153 | + if (spidev->spi == NULL) | ||
| 154 | + goto err_spi_removed; | ||
| 155 | + | ||
| 169 | status = spidev_sync_read(spidev, count); | 156 | status = spidev_sync_read(spidev, count); |
| 170 | if (status > 0) { | 157 | if (status > 0) { |
| 171 | unsigned long missing; | 158 | unsigned long missing; |
| @@ -176,7 +163,9 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) | |||
| 176 | else | 163 | else |
| 177 | status = status - missing; | 164 | status = status - missing; |
| 178 | } | 165 | } |
| 179 | - mutex_unlock(&spidev->buf_lock); | 166 | + |
| 167 | +err_spi_removed: | ||
| 168 | + mutex_unlock(&spidev->spi_lock); | ||
| 180 | 169 | ||
| 181 | return status; | 170 | return status; |
| 182 | } | 171 | } |
| @@ -187,7 +176,7 @@ spidev_write(struct file *filp, const char __user *buf, | |||
| 187 | size_t count, loff_t *f_pos) | 176 | size_t count, loff_t *f_pos) |
| 188 | { | 177 | { |
| 189 | struct spidev_data *spidev; | 178 | struct spidev_data *spidev; |
| 190 | - ssize_t status; | 179 | + ssize_t status = -ESHUTDOWN; |
| 191 | unsigned long missing; | 180 | unsigned long missing; |
| 192 | 181 | ||
| 193 | /* chipselect only toggles at start or end of operation */ | 182 | /* chipselect only toggles at start or end of operation */ |
| @@ -196,13 +185,19 @@ spidev_write(struct file *filp, const char __user *buf, | |||
| 196 | 185 | ||
| 197 | spidev = filp->private_data; | 186 | spidev = filp->private_data; |
| 198 | 187 | ||
| 199 | - mutex_lock(&spidev->buf_lock); | 188 | + mutex_lock(&spidev->spi_lock); |
| 189 | + | ||
| 190 | + if (spidev->spi == NULL) | ||
| 191 | + goto err_spi_removed; | ||
| 192 | + | ||
| 200 | missing = copy_from_user(spidev->tx_buffer, buf, count); | 193 | missing = copy_from_user(spidev->tx_buffer, buf, count); |
| 201 | if (missing == 0) | 194 | if (missing == 0) |
| 202 | status = spidev_sync_write(spidev, count); | 195 | status = spidev_sync_write(spidev, count); |
| 203 | else | 196 | else |
| 204 | status = -EFAULT; | 197 | status = -EFAULT; |
| 205 | - mutex_unlock(&spidev->buf_lock); | 198 | + |
| 199 | +err_spi_removed: | ||
| 200 | + mutex_unlock(&spidev->spi_lock); | ||
| 206 | 201 | ||
| 207 | return status; | 202 | return status; |
| 208 | } | 203 | } |
| @@ -376,14 +371,6 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 376 | return -ESHUTDOWN; | 371 | return -ESHUTDOWN; |
| 377 | } | 372 | } |
| 378 | 373 | ||
| 379 | - /* use the buffer lock here for triple duty: | ||
| 380 | - * - prevent I/O (from us) so calling spi_setup() is safe; | ||
| 381 | - * - prevent concurrent SPI_IOC_WR_* from morphing | ||
| 382 | - * data fields while SPI_IOC_RD_* reads them; | ||
| 383 | - * - SPI_IOC_MESSAGE needs the buffer locked "normally". | ||
| 384 | - */ | ||
| 385 | - mutex_lock(&spidev->buf_lock); | ||
| 386 | - | ||
| 387 | switch (cmd) { | 374 | switch (cmd) { |
| 388 | /* read requests */ | 375 | /* read requests */ |
| 389 | case SPI_IOC_RD_MODE: | 376 | case SPI_IOC_RD_MODE: |
| @@ -516,7 +503,6 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 516 | break; | 503 | break; |
| 517 | } | 504 | } |
| 518 | 505 | ||
| 519 | - mutex_unlock(&spidev->buf_lock); | ||
| 520 | spi_dev_put(spi); | 506 | spi_dev_put(spi); |
| 521 | mutex_unlock(&spidev->spi_lock); | 507 | mutex_unlock(&spidev->spi_lock); |
| 522 | return retval; | 508 | return retval; |
| @@ -547,9 +533,6 @@ spidev_compat_ioc_message(struct file *filp, unsigned int cmd, | |||
| 547 | return -ESHUTDOWN; | 533 | return -ESHUTDOWN; |
| 548 | } | 534 | } |
| 549 | 535 | ||
| 550 | - /* SPI_IOC_MESSAGE needs the buffer locked "normally" */ | ||
| 551 | - mutex_lock(&spidev->buf_lock); | ||
| 552 | - | ||
| 553 | /* Check message and copy into scratch area */ | 536 | /* Check message and copy into scratch area */ |
| 554 | ioc = spidev_get_ioc_message(cmd, u_ioc, &n_ioc); | 537 | ioc = spidev_get_ioc_message(cmd, u_ioc, &n_ioc); |
| 555 | if (IS_ERR(ioc)) { | 538 | if (IS_ERR(ioc)) { |
| @@ -570,7 +553,6 @@ spidev_compat_ioc_message(struct file *filp, unsigned int cmd, | |||
| 570 | kfree(ioc); | 553 | kfree(ioc); |
| 571 | 554 | ||
| 572 | done: | 555 | done: |
| 573 | - mutex_unlock(&spidev->buf_lock); | ||
| 574 | spi_dev_put(spi); | 556 | spi_dev_put(spi); |
| 575 | mutex_unlock(&spidev->spi_lock); | 557 | mutex_unlock(&spidev->spi_lock); |
| 576 | return retval; | 558 | return retval; |
| @@ -795,7 +777,6 @@ static int spidev_probe(struct spi_device *spi) | |||
| 795 | /* Initialize the driver data */ | 777 | /* Initialize the driver data */ |
| 796 | spidev->spi = spi; | 778 | spidev->spi = spi; |
| 797 | mutex_init(&spidev->spi_lock); | 779 | mutex_init(&spidev->spi_lock); |
| 798 | - mutex_init(&spidev->buf_lock); | ||
| 799 | 780 | ||
| 800 | INIT_LIST_HEAD(&spidev->device_entry); | 781 | INIT_LIST_HEAD(&spidev->device_entry); |
| 801 | 782 | ||
| @@ -1395,6 +1395,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t | |||
| 1395 | device_del(&tz->device); | 1395 | device_del(&tz->device); |
| 1396 | release_device: | 1396 | release_device: |
| 1397 | put_device(&tz->device); | 1397 | put_device(&tz->device); |
| 1398 | + wait_for_completion(&tz->removal); | ||
| 1398 | remove_id: | 1399 | remove_id: |
| 1399 | ida_free(&thermal_tz_ida, id); | 1400 | ida_free(&thermal_tz_ida, id); |
| 1400 | free_tzp: | 1401 | free_tzp: |
| @@ -331,10 +331,9 @@ struct ulpi *ulpi_register_interface(struct device *dev, | |||
| 331 | ulpi->ops = ops; | 331 | ulpi->ops = ops; |
| 332 | 332 | ||
| 333 | ret = ulpi_register(dev, ulpi); | 333 | ret = ulpi_register(dev, ulpi); |
| 334 | - if (ret) { | 334 | + if (ret) |
| 335 | - kfree(ulpi); | ||
| 336 | return ERR_PTR(ret); | 335 | return ERR_PTR(ret); |
| 337 | - } | 336 | + |
| 338 | 337 | ||
| 339 | return ulpi; | 338 | return ulpi; |
| 340 | } | 339 | } |
| @@ -410,6 +410,12 @@ uvc_function_disconnect(struct uvc_device *uvc) | |||
| 410 | { | 410 | { |
| 411 | int ret; | 411 | int ret; |
| 412 | 412 | ||
| 413 | + guard(mutex)(&uvc->lock); | ||
| 414 | + if (uvc->func_unbound) { | ||
| 415 | + dev_dbg(&uvc->vdev.dev, "skipping function deactivate (unbound)\n"); | ||
| 416 | + return; | ||
| 417 | + } | ||
| 418 | + | ||
| 413 | if ((ret = usb_function_deactivate(&uvc->func)) < 0) | 419 | if ((ret = usb_function_deactivate(&uvc->func)) < 0) |
| 414 | uvcg_info(&uvc->func, "UVC disconnect failed with %d\n", ret); | 420 | uvcg_info(&uvc->func, "UVC disconnect failed with %d\n", ret); |
| 415 | } | 421 | } |
| @@ -428,6 +434,15 @@ static ssize_t function_name_show(struct device *dev, | |||
| 428 | 434 | ||
| 429 | static DEVICE_ATTR_RO(function_name); | 435 | static DEVICE_ATTR_RO(function_name); |
| 430 | 436 | ||
| 437 | +static void uvc_vdev_release(struct video_device *vdev) | ||
| 438 | +{ | ||
| 439 | + struct uvc_device *uvc = video_get_drvdata(vdev); | ||
| 440 | + | ||
| 441 | + /* Signal uvc_function_unbind() that the video device has been released */ | ||
| 442 | + if (uvc->vdev_release_done) | ||
| 443 | + complete(uvc->vdev_release_done); | ||
| 444 | +} | ||
| 445 | + | ||
| 431 | static int | 446 | static int |
| 432 | uvc_register_video(struct uvc_device *uvc) | 447 | uvc_register_video(struct uvc_device *uvc) |
| 433 | { | 448 | { |
| @@ -440,7 +455,7 @@ uvc_register_video(struct uvc_device *uvc) | |||
| 440 | uvc->vdev.v4l2_dev->dev = &cdev->gadget->dev; | 455 | uvc->vdev.v4l2_dev->dev = &cdev->gadget->dev; |
| 441 | uvc->vdev.fops = &uvc_v4l2_fops; | 456 | uvc->vdev.fops = &uvc_v4l2_fops; |
| 442 | uvc->vdev.ioctl_ops = &uvc_v4l2_ioctl_ops; | 457 | uvc->vdev.ioctl_ops = &uvc_v4l2_ioctl_ops; |
| 443 | - uvc->vdev.release = video_device_release_empty; | 458 | + uvc->vdev.release = uvc_vdev_release; |
| 444 | uvc->vdev.vfl_dir = VFL_DIR_TX; | 459 | uvc->vdev.vfl_dir = VFL_DIR_TX; |
| 445 | uvc->vdev.lock = &uvc->video.mutex; | 460 | uvc->vdev.lock = &uvc->video.mutex; |
| 446 | uvc->vdev.device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; | 461 | uvc->vdev.device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; |
| @@ -653,6 +668,8 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) | |||
| 653 | int ret = -EINVAL; | 668 | int ret = -EINVAL; |
| 654 | 669 | ||
| 655 | uvcg_info(f, "%s()\n", __func__); | 670 | uvcg_info(f, "%s()\n", __func__); |
| 671 | + scoped_guard(mutex, &uvc->lock) | ||
| 672 | + uvc->func_unbound = false; | ||
| 656 | 673 | ||
| 657 | opts = fi_to_f_uvc_opts(f->fi); | 674 | opts = fi_to_f_uvc_opts(f->fi); |
| 658 | /* Sanity check the streaming endpoint module parameters. */ | 675 | /* Sanity check the streaming endpoint module parameters. */ |
| @@ -975,12 +992,19 @@ static void uvc_free(struct usb_function *f) | |||
| 975 | static void uvc_function_unbind(struct usb_configuration *c, | 992 | static void uvc_function_unbind(struct usb_configuration *c, |
| 976 | struct usb_function *f) | 993 | struct usb_function *f) |
| 977 | { | 994 | { |
| 995 | + DECLARE_COMPLETION_ONSTACK(vdev_release_done); | ||
| 978 | struct usb_composite_dev *cdev = c->cdev; | 996 | struct usb_composite_dev *cdev = c->cdev; |
| 979 | struct uvc_device *uvc = to_uvc(f); | 997 | struct uvc_device *uvc = to_uvc(f); |
| 980 | struct uvc_video *video = &uvc->video; | 998 | struct uvc_video *video = &uvc->video; |
| 981 | long wait_ret = 1; | 999 | long wait_ret = 1; |
| 1000 | + bool connected; | ||
| 982 | 1001 | ||
| 983 | uvcg_info(f, "%s()\n", __func__); | 1002 | uvcg_info(f, "%s()\n", __func__); |
| 1003 | + scoped_guard(mutex, &uvc->lock) { | ||
| 1004 | + uvc->func_unbound = true; | ||
| 1005 | + uvc->vdev_release_done = &vdev_release_done; | ||
| 1006 | + connected = uvc->func_connected; | ||
| 1007 | + } | ||
| 984 | 1008 | ||
| 985 | if (video->async_wq) | 1009 | if (video->async_wq) |
| 986 | destroy_workqueue(video->async_wq); | 1010 | destroy_workqueue(video->async_wq); |
| @@ -991,7 +1015,7 @@ static void uvc_function_unbind(struct usb_configuration *c, | |||
| 991 | * though the video device removal uevent. Allow some time for the | 1015 | * though the video device removal uevent. Allow some time for the |
| 992 | * application to close out before things get deleted. | 1016 | * application to close out before things get deleted. |
| 993 | */ | 1017 | */ |
| 994 | - if (uvc->func_connected) { | 1018 | + if (connected) { |
| 995 | uvcg_dbg(f, "waiting for clean disconnect\n"); | 1019 | uvcg_dbg(f, "waiting for clean disconnect\n"); |
| 996 | wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue, | 1020 | wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue, |
| 997 | uvc->func_connected == false, msecs_to_jiffies(500)); | 1021 | uvc->func_connected == false, msecs_to_jiffies(500)); |
| @@ -1002,7 +1026,10 @@ static void uvc_function_unbind(struct usb_configuration *c, | |||
| 1002 | video_unregister_device(&uvc->vdev); | 1026 | video_unregister_device(&uvc->vdev); |
| 1003 | v4l2_device_unregister(&uvc->v4l2_dev); | 1027 | v4l2_device_unregister(&uvc->v4l2_dev); |
| 1004 | 1028 | ||
| 1005 | - if (uvc->func_connected) { | 1029 | + scoped_guard(mutex, &uvc->lock) |
| 1030 | + connected = uvc->func_connected; | ||
| 1031 | + | ||
| 1032 | + if (connected) { | ||
| 1006 | /* | 1033 | /* |
| 1007 | * Wait for the release to occur to ensure there are no longer any | 1034 | * Wait for the release to occur to ensure there are no longer any |
| 1008 | * pending operations that may cause panics when resources are cleaned | 1035 | * pending operations that may cause panics when resources are cleaned |
| @@ -1014,6 +1041,10 @@ static void uvc_function_unbind(struct usb_configuration *c, | |||
| 1014 | uvcg_dbg(f, "done waiting for release with ret: %ld\n", wait_ret); | 1041 | uvcg_dbg(f, "done waiting for release with ret: %ld\n", wait_ret); |
| 1015 | } | 1042 | } |
| 1016 | 1043 | ||
| 1044 | + /* Wait for the video device to be released */ | ||
| 1045 | + wait_for_completion(&vdev_release_done); | ||
| 1046 | + uvc->vdev_release_done = NULL; | ||
| 1047 | + | ||
| 1017 | usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); | 1048 | usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); |
| 1018 | kfree(uvc->control_buf); | 1049 | kfree(uvc->control_buf); |
| 1019 | 1050 | ||
| @@ -1032,6 +1063,8 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi) | |||
| 1032 | return ERR_PTR(-ENOMEM); | 1063 | return ERR_PTR(-ENOMEM); |
| 1033 | 1064 | ||
| 1034 | mutex_init(&uvc->video.mutex); | 1065 | mutex_init(&uvc->video.mutex); |
| 1066 | + mutex_init(&uvc->lock); | ||
| 1067 | + uvc->func_unbound = true; | ||
| 1035 | uvc->state = UVC_STATE_DISCONNECTED; | 1068 | uvc->state = UVC_STATE_DISCONNECTED; |
| 1036 | init_waitqueue_head(&uvc->func_connected_queue); | 1069 | init_waitqueue_head(&uvc->func_connected_queue); |
| 1037 | opts = fi_to_f_uvc_opts(fi); | 1070 | opts = fi_to_f_uvc_opts(fi); |
| @@ -131,6 +131,9 @@ struct uvc_device { | |||
| 131 | enum uvc_state state; | 131 | enum uvc_state state; |
| 132 | struct usb_function func; | 132 | struct usb_function func; |
| 133 | struct uvc_video video; | 133 | struct uvc_video video; |
| 134 | + struct completion *vdev_release_done; | ||
| 135 | + struct mutex lock; /* protects func_unbound and func_connected */ | ||
| 136 | + bool func_unbound; | ||
| 134 | bool func_connected; | 137 | bool func_connected; |
| 135 | wait_queue_head_t func_connected_queue; | 138 | wait_queue_head_t func_connected_queue; |
| 136 | 139 | ||
| @@ -505,6 +505,8 @@ uvc_v4l2_subscribe_event(struct v4l2_fh *fh, | |||
| 505 | if (sub->type < UVC_EVENT_FIRST || sub->type > UVC_EVENT_LAST) | 505 | if (sub->type < UVC_EVENT_FIRST || sub->type > UVC_EVENT_LAST) |
| 506 | return -EINVAL; | 506 | return -EINVAL; |
| 507 | 507 | ||
| 508 | + guard(mutex)(&uvc->lock); | ||
| 509 | + | ||
| 508 | if (sub->type == UVC_EVENT_SETUP && uvc->func_connected) | 510 | if (sub->type == UVC_EVENT_SETUP && uvc->func_connected) |
| 509 | return -EBUSY; | 511 | return -EBUSY; |
| 510 | 512 | ||
| @@ -526,7 +528,8 @@ static void uvc_v4l2_disable(struct uvc_device *uvc) | |||
| 526 | uvc_function_disconnect(uvc); | 528 | uvc_function_disconnect(uvc); |
| 527 | uvcg_video_enable(&uvc->video, 0); | 529 | uvcg_video_enable(&uvc->video, 0); |
| 528 | uvcg_free_buffers(&uvc->video.queue); | 530 | uvcg_free_buffers(&uvc->video.queue); |
| 529 | - uvc->func_connected = false; | 531 | + scoped_guard(mutex, &uvc->lock) |
| 532 | + uvc->func_connected = false; | ||
| 530 | wake_up_interruptible(&uvc->func_connected_queue); | 533 | wake_up_interruptible(&uvc->func_connected_queue); |
| 531 | } | 534 | } |
| 532 | 535 | ||
| @@ -907,21 +907,6 @@ static int dummy_pullup(struct usb_gadget *_gadget, int value) | |||
| 907 | spin_lock_irqsave(&dum->lock, flags); | 907 | spin_lock_irqsave(&dum->lock, flags); |
| 908 | dum->pullup = (value != 0); | 908 | dum->pullup = (value != 0); |
| 909 | set_link_state(dum_hcd); | 909 | set_link_state(dum_hcd); |
| 910 | - if (value == 0) { | ||
| 911 | - /* | ||
| 912 | - * Emulate synchronize_irq(): wait for callbacks to finish. | ||
| 913 | - * This seems to be the best place to emulate the call to | ||
| 914 | - * synchronize_irq() that's in usb_gadget_remove_driver(). | ||
| 915 | - * Doing it in dummy_udc_stop() would be too late since it | ||
| 916 | - * is called after the unbind callback and unbind shouldn't | ||
| 917 | - * be invoked until all the other callbacks are finished. | ||
| 918 | - */ | ||
| 919 | - while (dum->callback_usage > 0) { | ||
| 920 | - spin_unlock_irqrestore(&dum->lock, flags); | ||
| 921 | - usleep_range(1000, 2000); | ||
| 922 | - spin_lock_irqsave(&dum->lock, flags); | ||
| 923 | - } | ||
| 924 | - } | ||
| 925 | spin_unlock_irqrestore(&dum->lock, flags); | 910 | spin_unlock_irqrestore(&dum->lock, flags); |
| 926 | 911 | ||
| 927 | usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd)); | 912 | usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd)); |
| @@ -944,6 +929,20 @@ static void dummy_udc_async_callbacks(struct usb_gadget *_gadget, bool enable) | |||
| 944 | 929 | ||
| 945 | spin_lock_irq(&dum->lock); | 930 | spin_lock_irq(&dum->lock); |
| 946 | dum->ints_enabled = enable; | 931 | dum->ints_enabled = enable; |
| 932 | + if (!enable) { | ||
| 933 | + /* | ||
| 934 | + * Emulate synchronize_irq(): wait for callbacks to finish. | ||
| 935 | + * This has to happen after emulated interrupts are disabled | ||
| 936 | + * (dum->ints_enabled is clear) and before the unbind callback, | ||
| 937 | + * just like the call to synchronize_irq() in | ||
| 938 | + * gadget/udc/core:gadget_unbind_driver(). | ||
| 939 | + */ | ||
| 940 | + while (dum->callback_usage > 0) { | ||
| 941 | + spin_unlock_irq(&dum->lock); | ||
| 942 | + usleep_range(1000, 2000); | ||
| 943 | + spin_lock_irq(&dum->lock); | ||
| 944 | + } | ||
| 945 | + } | ||
| 947 | spin_unlock_irq(&dum->lock); | 946 | spin_unlock_irq(&dum->lock); |
| 948 | } | 947 | } |
| 949 | 948 | ||
| @@ -3180,9 +3180,6 @@ static int mlx5_set_group_asid(struct vdpa_device *vdev, u32 group, | |||
| 3180 | { | 3180 | { |
| 3181 | struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); | 3181 | struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); |
| 3182 | 3182 | ||
| 3183 | - if (group >= MLX5_VDPA_NUMVQ_GROUPS) | ||
| 3184 | - return -EINVAL; | ||
| 3185 | - | ||
| 3186 | mvdev->group2asid[group] = asid; | 3183 | mvdev->group2asid[group] = asid; |
| 3187 | return 0; | 3184 | return 0; |
| 3188 | } | 3185 | } |
| @@ -584,12 +584,6 @@ static int vdpasim_set_group_asid(struct vdpa_device *vdpa, unsigned int group, | |||
| 584 | struct vhost_iotlb *iommu; | 584 | struct vhost_iotlb *iommu; |
| 585 | int i; | 585 | int i; |
| 586 | 586 | ||
| 587 | - if (group > vdpasim->dev_attr.ngroups) | ||
| 588 | - return -EINVAL; | ||
| 589 | - | ||
| 590 | - if (asid >= vdpasim->dev_attr.nas) | ||
| 591 | - return -EINVAL; | ||
| 592 | - | ||
| 593 | iommu = &vdpasim->iommu[asid]; | 587 | iommu = &vdpasim->iommu[asid]; |
| 594 | 588 | ||
| 595 | mutex_lock(&vdpasim->mutex); | 589 | mutex_lock(&vdpasim->mutex); |
| @@ -606,7 +606,7 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd, | |||
| 606 | case VHOST_VDPA_SET_GROUP_ASID: | 606 | case VHOST_VDPA_SET_GROUP_ASID: |
| 607 | if (copy_from_user(&s, argp, sizeof(s))) | 607 | if (copy_from_user(&s, argp, sizeof(s))) |
| 608 | return -EFAULT; | 608 | return -EFAULT; |
| 609 | - if (s.num >= vdpa->nas) | 609 | + if (idx >= vdpa->ngroups || s.num >= vdpa->nas) |
| 610 | return -EINVAL; | 610 | return -EINVAL; |
| 611 | if (!ops->set_group_asid) | 611 | if (!ops->set_group_asid) |
| 612 | return -EOPNOTSUPP; | 612 | return -EOPNOTSUPP; |
| @@ -145,6 +145,7 @@ static inline int ima_measure_critical_data(const char *event_label, | |||
| 145 | 145 | ||
| 146 | int __init ima_free_kexec_buffer(void); | 146 | int __init ima_free_kexec_buffer(void); |
| 147 | int __init ima_get_kexec_buffer(void **addr, size_t *size); | 147 | int __init ima_get_kexec_buffer(void **addr, size_t *size); |
| 148 | +int ima_validate_range(phys_addr_t phys, size_t size); | ||
| 148 | 149 | ||
| 149 | 150 | ||
| 150 | 151 | ||
| @@ -83,6 +83,11 @@ void nf_conntrack_lock(spinlock_t *lock); | |||
| 83 | 83 | ||
| 84 | extern spinlock_t nf_conntrack_expect_lock; | 84 | extern spinlock_t nf_conntrack_expect_lock; |
| 85 | 85 | ||
| 86 | +static inline void lockdep_nfct_expect_lock_held(void) | ||
| 87 | +{ | ||
| 88 | + lockdep_assert_held(&nf_conntrack_expect_lock); | ||
| 89 | +} | ||
| 90 | + | ||
| 86 | /* ctnetlink code shared by both ctnetlink and nf_conntrack_bpf */ | 91 | /* ctnetlink code shared by both ctnetlink and nf_conntrack_bpf */ |
| 87 | 92 | ||
| 88 | static inline void __nf_ct_set_timeout(struct nf_conn *ct, u64 timeout) | 93 | static inline void __nf_ct_set_timeout(struct nf_conn *ct, u64 timeout) |
| @@ -2434,6 +2434,7 @@ static void cgroup_migrate_add_task(struct task_struct *task, | |||
| 2434 | 2434 | ||
| 2435 | mgctx->tset.nr_tasks++; | 2435 | mgctx->tset.nr_tasks++; |
| 2436 | 2436 | ||
| 2437 | + css_set_skip_task_iters(cset, task); | ||
| 2437 | list_move_tail(&task->cg_list, &cset->mg_tasks); | 2438 | list_move_tail(&task->cg_list, &cset->mg_tasks); |
| 2438 | if (list_empty(&cset->mg_node)) | 2439 | if (list_empty(&cset->mg_node)) |
| 2439 | list_add_tail(&cset->mg_node, | 2440 | list_add_tail(&cset->mg_node, |
| @@ -1726,6 +1726,8 @@ static DEFINE_MUTEX(vmap_purge_lock); | |||
| 1726 | /* for per-CPU blocks */ | 1726 | /* for per-CPU blocks */ |
| 1727 | static void purge_fragmented_blocks_allcpus(void); | 1727 | static void purge_fragmented_blocks_allcpus(void); |
| 1728 | 1728 | ||
| 1729 | + | ||
| 1730 | + | ||
| 1729 | /* | 1731 | /* |
| 1730 | * Purges all lazily-freed vmap areas. | 1732 | * Purges all lazily-freed vmap areas. |
| 1731 | */ | 1733 | */ |
| @@ -1735,6 +1737,7 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) | |||
| 1735 | unsigned int num_purged_areas = 0; | 1737 | unsigned int num_purged_areas = 0; |
| 1736 | struct list_head local_purge_list; | 1738 | struct list_head local_purge_list; |
| 1737 | struct vmap_area *va, *n_va; | 1739 | struct vmap_area *va, *n_va; |
| 1740 | + unsigned int batch_count = 0; | ||
| 1738 | 1741 | ||
| 1739 | lockdep_assert_held(&vmap_purge_lock); | 1742 | lockdep_assert_held(&vmap_purge_lock); |
| 1740 | 1743 | ||
| @@ -1746,6 +1749,7 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) | |||
| 1746 | if (unlikely(list_empty(&local_purge_list))) | 1749 | if (unlikely(list_empty(&local_purge_list))) |
| 1747 | goto out; | 1750 | goto out; |
| 1748 | 1751 | ||
| 1752 | + | ||
| 1749 | start = min(start, | 1753 | start = min(start, |
| 1750 | list_first_entry(&local_purge_list, | 1754 | list_first_entry(&local_purge_list, |
| 1751 | struct vmap_area, list)->va_start); | 1755 | struct vmap_area, list)->va_start); |
| @@ -1781,8 +1785,11 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) | |||
| 1781 | atomic_long_sub(nr, &vmap_lazy_nr); | 1785 | atomic_long_sub(nr, &vmap_lazy_nr); |
| 1782 | num_purged_areas++; | 1786 | num_purged_areas++; |
| 1783 | 1787 | ||
| 1784 | - if (atomic_long_read(&vmap_lazy_nr) < resched_threshold) | 1788 | + if (need_resched() || (++batch_count >= KASAN_RELEASE_BATCH_SIZE) || |
| 1789 | + atomic_long_read(&vmap_lazy_nr) < resched_threshold) { | ||
| 1785 | cond_resched_lock(&free_vmap_area_lock); | 1790 | cond_resched_lock(&free_vmap_area_lock); |
| 1791 | + batch_count = 0; | ||
| 1792 | + } | ||
| 1786 | } | 1793 | } |
| 1787 | spin_unlock(&free_vmap_area_lock); | 1794 | spin_unlock(&free_vmap_area_lock); |
| 1788 | 1795 | ||
| @@ -4047,6 +4054,7 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, | |||
| 4047 | struct vmap_area **vas, *va; | 4054 | struct vmap_area **vas, *va; |
| 4048 | struct vm_struct **vms; | 4055 | struct vm_struct **vms; |
| 4049 | int area, area2, last_area, term_area; | 4056 | int area, area2, last_area, term_area; |
| 4057 | + unsigned int batch_count; | ||
| 4050 | unsigned long base, start, size, end, last_end, orig_start, orig_end; | 4058 | unsigned long base, start, size, end, last_end, orig_start, orig_end; |
| 4051 | bool purged = false; | 4059 | bool purged = false; |
| 4052 | 4060 | ||
| @@ -4254,6 +4262,7 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, | |||
| 4254 | return NULL; | 4262 | return NULL; |
| 4255 | 4263 | ||
| 4256 | err_free_shadow: | 4264 | err_free_shadow: |
| 4265 | + batch_count = 0; | ||
| 4257 | spin_lock(&free_vmap_area_lock); | 4266 | spin_lock(&free_vmap_area_lock); |
| 4258 | /* | 4267 | /* |
| 4259 | * We release all the vmalloc shadows, even the ones for regions that | 4268 | * We release all the vmalloc shadows, even the ones for regions that |
| @@ -4269,6 +4278,11 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, | |||
| 4269 | kasan_release_vmalloc(orig_start, orig_end, | 4278 | kasan_release_vmalloc(orig_start, orig_end, |
| 4270 | va->va_start, va->va_end); | 4279 | va->va_start, va->va_end); |
| 4271 | vas[area] = NULL; | 4280 | vas[area] = NULL; |
| 4281 | + | ||
| 4282 | + if (need_resched() || (++batch_count >= KASAN_RELEASE_BATCH_SIZE)) { | ||
| 4283 | + cond_resched_lock(&free_vmap_area_lock); | ||
| 4284 | + batch_count = 0; | ||
| 4285 | + } | ||
| 4272 | kfree(vms[area]); | 4286 | kfree(vms[area]); |
| 4273 | } | 4287 | } |
| 4274 | spin_unlock(&free_vmap_area_lock); | 4288 | spin_unlock(&free_vmap_area_lock); |
| @@ -37,9 +37,6 @@ static int set_secret(struct ceph_crypto_key *key, void *buf) | |||
| 37 | return -ENOTSUPP; | 37 | return -ENOTSUPP; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | - if (!key->len) | ||
| 41 | - return -EINVAL; | ||
| 42 | - | ||
| 43 | key->key = kmemdup(buf, key->len, GFP_NOIO); | 40 | key->key = kmemdup(buf, key->len, GFP_NOIO); |
| 44 | if (!key->key) { | 41 | if (!key->key) { |
| 45 | ret = -ENOMEM; | 42 | ret = -ENOMEM; |
| @@ -95,6 +92,11 @@ int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end) | |||
| 95 | ceph_decode_copy(p, &key->created, sizeof(key->created)); | 92 | ceph_decode_copy(p, &key->created, sizeof(key->created)); |
| 96 | key->len = ceph_decode_16(p); | 93 | key->len = ceph_decode_16(p); |
| 97 | ceph_decode_need(p, end, key->len, bad); | 94 | ceph_decode_need(p, end, key->len, bad); |
| 95 | + if (key->len > CEPH_MAX_KEY_LEN) { | ||
| 96 | + pr_err("secret too big %d\n", key->len); | ||
| 97 | + return -EINVAL; | ||
| 98 | + } | ||
| 99 | + | ||
| 98 | ret = set_secret(key, *p); | 100 | ret = set_secret(key, *p); |
| 99 | memzero_explicit(*p, key->len); | 101 | memzero_explicit(*p, key->len); |
| 100 | *p += key->len; | 102 | *p += key->len; |
| @@ -2393,7 +2393,7 @@ static int process_auth_reply_more(struct ceph_connection *con, | |||
| 2393 | */ | 2393 | */ |
| 2394 | static int process_auth_done(struct ceph_connection *con, void *p, void *end) | 2394 | static int process_auth_done(struct ceph_connection *con, void *p, void *end) |
| 2395 | { | 2395 | { |
| 2396 | - u8 session_key_buf[CEPH_KEY_LEN + 16]; | 2396 | + u8 session_key_buf[CEPH_MAX_KEY_LEN + 16]; |
| 2397 | u8 con_secret_buf[CEPH_MAX_CON_SECRET_LEN + 16]; | 2397 | u8 con_secret_buf[CEPH_MAX_CON_SECRET_LEN + 16]; |
| 2398 | u8 *session_key = PTR_ALIGN(&session_key_buf[0], 16); | 2398 | u8 *session_key = PTR_ALIGN(&session_key_buf[0], 16); |
| 2399 | u8 *con_secret = PTR_ALIGN(&con_secret_buf[0], 16); | 2399 | u8 *con_secret = PTR_ALIGN(&con_secret_buf[0], 16); |
| @@ -2869,12 +2869,15 @@ static int process_message_header(struct ceph_connection *con, | |||
| 2869 | void *p, void *end) | 2869 | void *p, void *end) |
| 2870 | { | 2870 | { |
| 2871 | struct ceph_frame_desc *desc = &con->v2.in_desc; | 2871 | struct ceph_frame_desc *desc = &con->v2.in_desc; |
| 2872 | - struct ceph_msg_header2 *hdr2 = p; | 2872 | + struct ceph_msg_header2 *hdr2; |
| 2873 | struct ceph_msg_header hdr; | 2873 | struct ceph_msg_header hdr; |
| 2874 | int skip; | 2874 | int skip; |
| 2875 | int ret; | 2875 | int ret; |
| 2876 | u64 seq; | 2876 | u64 seq; |
| 2877 | 2877 | ||
| 2878 | + ceph_decode_need(&p, end, sizeof(*hdr2), bad); | ||
| 2879 | + hdr2 = p; | ||
| 2880 | + | ||
| 2878 | /* verify seq# */ | 2881 | /* verify seq# */ |
| 2879 | seq = le64_to_cpu(hdr2->seq); | 2882 | seq = le64_to_cpu(hdr2->seq); |
| 2880 | if ((s64)seq - (s64)con->in_seq < 1) { | 2883 | if ((s64)seq - (s64)con->in_seq < 1) { |
| @@ -2905,6 +2908,10 @@ static int process_message_header(struct ceph_connection *con, | |||
| 2905 | WARN_ON(!con->in_msg); | 2908 | WARN_ON(!con->in_msg); |
| 2906 | WARN_ON(con->in_msg->con != con); | 2909 | WARN_ON(con->in_msg->con != con); |
| 2907 | return 1; | 2910 | return 1; |
| 2911 | + | ||
| 2912 | +bad: | ||
| 2913 | + pr_err("failed to decode message header\n"); | ||
| 2914 | + return -EINVAL; | ||
| 2908 | } | 2915 | } |
| 2909 | 2916 | ||
| 2910 | static int process_message(struct ceph_connection *con) | 2917 | static int process_message(struct ceph_connection *con) |
| @@ -3594,12 +3594,12 @@ static void addrconf_permanent_addr(struct net *net, struct net_device *dev) | |||
| 3594 | if ((ifp->flags & IFA_F_PERMANENT) && | 3594 | if ((ifp->flags & IFA_F_PERMANENT) && |
| 3595 | fixup_permanent_addr(net, idev, ifp) < 0) { | 3595 | fixup_permanent_addr(net, idev, ifp) < 0) { |
| 3596 | write_unlock_bh(&idev->lock); | 3596 | write_unlock_bh(&idev->lock); |
| 3597 | - in6_ifa_hold(ifp); | ||
| 3598 | - ipv6_del_addr(ifp); | ||
| 3599 | - write_lock_bh(&idev->lock); | ||
| 3600 | 3597 | ||
| 3601 | net_info_ratelimited("%s: Failed to add prefix route for address %pI6c; dropping\n", | 3598 | net_info_ratelimited("%s: Failed to add prefix route for address %pI6c; dropping\n", |
| 3602 | idev->dev->name, &ifp->addr); | 3599 | idev->dev->name, &ifp->addr); |
| 3600 | + in6_ifa_hold(ifp); | ||
| 3601 | + ipv6_del_addr(ifp); | ||
| 3602 | + write_lock_bh(&idev->lock); | ||
| 3603 | } | 3603 | } |
| 3604 | } | 3604 | } |
| 3605 | 3605 | ||
| @@ -57,6 +57,7 @@ static int xfrm6_get_saddr(xfrm_address_t *saddr, | |||
| 57 | struct dst_entry *dst; | 57 | struct dst_entry *dst; |
| 58 | struct net_device *dev; | 58 | struct net_device *dev; |
| 59 | struct inet6_dev *idev; | 59 | struct inet6_dev *idev; |
| 60 | + int err; | ||
| 60 | 61 | ||
| 61 | dst = xfrm6_dst_lookup(params); | 62 | dst = xfrm6_dst_lookup(params); |
| 62 | if (IS_ERR(dst)) | 63 | if (IS_ERR(dst)) |
| @@ -68,9 +69,11 @@ static int xfrm6_get_saddr(xfrm_address_t *saddr, | |||
| 68 | return -EHOSTUNREACH; | 69 | return -EHOSTUNREACH; |
| 69 | } | 70 | } |
| 70 | dev = idev->dev; | 71 | dev = idev->dev; |
| 71 | - ipv6_dev_get_saddr(dev_net(dev), dev, ¶ms->daddr->in6, 0, | 72 | + err = ipv6_dev_get_saddr(dev_net(dev), dev, ¶ms->daddr->in6, 0, |
| 72 | - &saddr->in6); | 73 | + &saddr->in6); |
| 73 | dst_release(dst); | 74 | dst_release(dst); |
| 75 | + if (err) | ||
| 76 | + return -EHOSTUNREACH; | ||
| 74 | return 0; | 77 | return 0; |
| 75 | } | 78 | } |
| 76 | 79 | ||
| @@ -757,6 +757,22 @@ static unsigned int pfkey_sockaddr_fill(const xfrm_address_t *xaddr, __be16 port | |||
| 757 | return 0; | 757 | return 0; |
| 758 | } | 758 | } |
| 759 | 759 | ||
| 760 | +static unsigned int pfkey_sockaddr_fill_zero_tail(const xfrm_address_t *xaddr, | ||
| 761 | + __be16 port, | ||
| 762 | + struct sockaddr *sa, | ||
| 763 | + unsigned short family) | ||
| 764 | +{ | ||
| 765 | + unsigned int prefixlen; | ||
| 766 | + int sockaddr_len = pfkey_sockaddr_len(family); | ||
| 767 | + int sockaddr_size = pfkey_sockaddr_size(family); | ||
| 768 | + | ||
| 769 | + prefixlen = pfkey_sockaddr_fill(xaddr, port, sa, family); | ||
| 770 | + if (sockaddr_size > sockaddr_len) | ||
| 771 | + memset((u8 *)sa + sockaddr_len, 0, sockaddr_size - sockaddr_len); | ||
| 772 | + | ||
| 773 | + return prefixlen; | ||
| 774 | +} | ||
| 775 | + | ||
| 760 | static struct sk_buff *__pfkey_xfrm_state2msg(const struct xfrm_state *x, | 776 | static struct sk_buff *__pfkey_xfrm_state2msg(const struct xfrm_state *x, |
| 761 | int add_keys, int hsc) | 777 | int add_keys, int hsc) |
| 762 | { | 778 | { |
| @@ -3205,9 +3221,9 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
| 3205 | addr->sadb_address_proto = 0; | 3221 | addr->sadb_address_proto = 0; |
| 3206 | addr->sadb_address_reserved = 0; | 3222 | addr->sadb_address_reserved = 0; |
| 3207 | addr->sadb_address_prefixlen = | 3223 | addr->sadb_address_prefixlen = |
| 3208 | - pfkey_sockaddr_fill(&x->props.saddr, 0, | 3224 | + pfkey_sockaddr_fill_zero_tail(&x->props.saddr, 0, |
| 3209 | - (struct sockaddr *) (addr + 1), | 3225 | + (struct sockaddr *)(addr + 1), |
| 3210 | - x->props.family); | 3226 | + x->props.family); |
| 3211 | if (!addr->sadb_address_prefixlen) | 3227 | if (!addr->sadb_address_prefixlen) |
| 3212 | BUG(); | 3228 | BUG(); |
| 3213 | 3229 | ||
| @@ -3220,9 +3236,9 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
| 3220 | addr->sadb_address_proto = 0; | 3236 | addr->sadb_address_proto = 0; |
| 3221 | addr->sadb_address_reserved = 0; | 3237 | addr->sadb_address_reserved = 0; |
| 3222 | addr->sadb_address_prefixlen = | 3238 | addr->sadb_address_prefixlen = |
| 3223 | - pfkey_sockaddr_fill(&x->id.daddr, 0, | 3239 | + pfkey_sockaddr_fill_zero_tail(&x->id.daddr, 0, |
| 3224 | - (struct sockaddr *) (addr + 1), | 3240 | + (struct sockaddr *)(addr + 1), |
| 3225 | - x->props.family); | 3241 | + x->props.family); |
| 3226 | if (!addr->sadb_address_prefixlen) | 3242 | if (!addr->sadb_address_prefixlen) |
| 3227 | BUG(); | 3243 | BUG(); |
| 3228 | 3244 | ||
| @@ -3420,9 +3436,9 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, | |||
| 3420 | addr->sadb_address_proto = 0; | 3436 | addr->sadb_address_proto = 0; |
| 3421 | addr->sadb_address_reserved = 0; | 3437 | addr->sadb_address_reserved = 0; |
| 3422 | addr->sadb_address_prefixlen = | 3438 | addr->sadb_address_prefixlen = |
| 3423 | - pfkey_sockaddr_fill(&x->props.saddr, 0, | 3439 | + pfkey_sockaddr_fill_zero_tail(&x->props.saddr, 0, |
| 3424 | - (struct sockaddr *) (addr + 1), | 3440 | + (struct sockaddr *)(addr + 1), |
| 3425 | - x->props.family); | 3441 | + x->props.family); |
| 3426 | if (!addr->sadb_address_prefixlen) | 3442 | if (!addr->sadb_address_prefixlen) |
| 3427 | BUG(); | 3443 | BUG(); |
| 3428 | 3444 | ||
| @@ -3442,9 +3458,9 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, | |||
| 3442 | addr->sadb_address_proto = 0; | 3458 | addr->sadb_address_proto = 0; |
| 3443 | addr->sadb_address_reserved = 0; | 3459 | addr->sadb_address_reserved = 0; |
| 3444 | addr->sadb_address_prefixlen = | 3460 | addr->sadb_address_prefixlen = |
| 3445 | - pfkey_sockaddr_fill(ipaddr, 0, | 3461 | + pfkey_sockaddr_fill_zero_tail(ipaddr, 0, |
| 3446 | - (struct sockaddr *) (addr + 1), | 3462 | + (struct sockaddr *)(addr + 1), |
| 3447 | - x->props.family); | 3463 | + x->props.family); |
| 3448 | if (!addr->sadb_address_prefixlen) | 3464 | if (!addr->sadb_address_prefixlen) |
| 3449 | BUG(); | 3465 | BUG(); |
| 3450 | 3466 | ||
| @@ -3473,15 +3489,15 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type, | |||
| 3473 | switch (type) { | 3489 | switch (type) { |
| 3474 | case SADB_EXT_ADDRESS_SRC: | 3490 | case SADB_EXT_ADDRESS_SRC: |
| 3475 | addr->sadb_address_prefixlen = sel->prefixlen_s; | 3491 | addr->sadb_address_prefixlen = sel->prefixlen_s; |
| 3476 | - pfkey_sockaddr_fill(&sel->saddr, 0, | 3492 | + pfkey_sockaddr_fill_zero_tail(&sel->saddr, 0, |
| 3477 | - (struct sockaddr *)(addr + 1), | 3493 | + (struct sockaddr *)(addr + 1), |
| 3478 | - sel->family); | 3494 | + sel->family); |
| 3479 | break; | 3495 | break; |
| 3480 | case SADB_EXT_ADDRESS_DST: | 3496 | case SADB_EXT_ADDRESS_DST: |
| 3481 | addr->sadb_address_prefixlen = sel->prefixlen_d; | 3497 | addr->sadb_address_prefixlen = sel->prefixlen_d; |
| 3482 | - pfkey_sockaddr_fill(&sel->daddr, 0, | 3498 | + pfkey_sockaddr_fill_zero_tail(&sel->daddr, 0, |
| 3483 | - (struct sockaddr *)(addr + 1), | 3499 | + (struct sockaddr *)(addr + 1), |
| 3484 | - sel->family); | 3500 | + sel->family); |
| 3485 | break; | 3501 | break; |
| 3486 | default: | 3502 | default: |
| 3487 | return -EINVAL; | 3503 | return -EINVAL; |
| @@ -1086,6 +1086,11 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns | |||
| 1086 | uh->source = inet->inet_sport; | 1086 | uh->source = inet->inet_sport; |
| 1087 | uh->dest = inet->inet_dport; | 1087 | uh->dest = inet->inet_dport; |
| 1088 | udp_len = uhlen + session->hdr_len + data_len; | 1088 | udp_len = uhlen + session->hdr_len + data_len; |
| 1089 | + if (udp_len > U16_MAX) { | ||
| 1090 | + kfree_skb(skb); | ||
| 1091 | + ret = NET_XMIT_DROP; | ||
| 1092 | + goto out_unlock; | ||
| 1093 | + } | ||
| 1089 | uh->len = htons(udp_len); | 1094 | uh->len = htons(udp_len); |
| 1090 | 1095 | ||
| 1091 | /* Calculate UDP checksum if configured to do so */ | 1096 | /* Calculate UDP checksum if configured to do so */ |
| @@ -1452,7 +1452,6 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, | |||
| 1452 | ret = ip_vs_bind_scheduler(svc, sched); | 1452 | ret = ip_vs_bind_scheduler(svc, sched); |
| 1453 | if (ret) | 1453 | if (ret) |
| 1454 | goto out_err; | 1454 | goto out_err; |
| 1455 | - sched = NULL; | ||
| 1456 | } | 1455 | } |
| 1457 | 1456 | ||
| 1458 | ret = ip_vs_start_estimator(ipvs, &svc->stats); | 1457 | ret = ip_vs_start_estimator(ipvs, &svc->stats); |
| @@ -237,6 +237,8 @@ void nf_ct_expect_event_report(enum ip_conntrack_expect_events event, | |||
| 237 | struct nf_ct_event_notifier *notify; | 237 | struct nf_ct_event_notifier *notify; |
| 238 | struct nf_conntrack_ecache *e; | 238 | struct nf_conntrack_ecache *e; |
| 239 | 239 | ||
| 240 | + lockdep_nfct_expect_lock_held(); | ||
| 241 | + | ||
| 240 | rcu_read_lock(); | 242 | rcu_read_lock(); |
| 241 | notify = rcu_dereference(net->ct.nf_conntrack_event_cb); | 243 | notify = rcu_dereference(net->ct.nf_conntrack_event_cb); |
| 242 | if (!notify) | 244 | if (!notify) |
| @@ -51,6 +51,7 @@ void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp, | |||
| 51 | struct net *net = nf_ct_exp_net(exp); | 51 | struct net *net = nf_ct_exp_net(exp); |
| 52 | struct nf_conntrack_net *cnet; | 52 | struct nf_conntrack_net *cnet; |
| 53 | 53 | ||
| 54 | + lockdep_nfct_expect_lock_held(); | ||
| 54 | WARN_ON(!master_help); | 55 | WARN_ON(!master_help); |
| 55 | WARN_ON(timer_pending(&exp->timeout)); | 56 | WARN_ON(timer_pending(&exp->timeout)); |
| 56 | 57 | ||
| @@ -118,6 +119,8 @@ nf_ct_exp_equal(const struct nf_conntrack_tuple *tuple, | |||
| 118 | 119 | ||
| 119 | bool nf_ct_remove_expect(struct nf_conntrack_expect *exp) | 120 | bool nf_ct_remove_expect(struct nf_conntrack_expect *exp) |
| 120 | { | 121 | { |
| 122 | + lockdep_nfct_expect_lock_held(); | ||
| 123 | + | ||
| 121 | if (del_timer(&exp->timeout)) { | 124 | if (del_timer(&exp->timeout)) { |
| 122 | nf_ct_unlink_expect(exp); | 125 | nf_ct_unlink_expect(exp); |
| 123 | nf_ct_expect_put(exp); | 126 | nf_ct_expect_put(exp); |
| @@ -177,6 +180,8 @@ nf_ct_find_expectation(struct net *net, | |||
| 177 | struct nf_conntrack_expect *i, *exp = NULL; | 180 | struct nf_conntrack_expect *i, *exp = NULL; |
| 178 | unsigned int h; | 181 | unsigned int h; |
| 179 | 182 | ||
| 183 | + lockdep_nfct_expect_lock_held(); | ||
| 184 | + | ||
| 180 | if (!cnet->expect_count) | 185 | if (!cnet->expect_count) |
| 181 | return NULL; | 186 | return NULL; |
| 182 | 187 | ||
| @@ -442,6 +447,8 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect, | |||
| 442 | unsigned int h; | 447 | unsigned int h; |
| 443 | int ret = 0; | 448 | int ret = 0; |
| 444 | 449 | ||
| 450 | + lockdep_nfct_expect_lock_held(); | ||
| 451 | + | ||
| 445 | if (!master_help) { | 452 | if (!master_help) { |
| 446 | ret = -ESHUTDOWN; | 453 | ret = -ESHUTDOWN; |
| 447 | goto out; | 454 | goto out; |
| @@ -498,8 +505,9 @@ int nf_ct_expect_related_report(struct nf_conntrack_expect *expect, | |||
| 498 | 505 | ||
| 499 | nf_ct_expect_insert(expect); | 506 | nf_ct_expect_insert(expect); |
| 500 | 507 | ||
| 501 | - spin_unlock_bh(&nf_conntrack_expect_lock); | ||
| 502 | nf_ct_expect_event_report(IPEXP_NEW, expect, portid, report); | 508 | nf_ct_expect_event_report(IPEXP_NEW, expect, portid, report); |
| 509 | + spin_unlock_bh(&nf_conntrack_expect_lock); | ||
| 510 | + | ||
| 503 | return 0; | 511 | return 0; |
| 504 | out: | 512 | out: |
| 505 | spin_unlock_bh(&nf_conntrack_expect_lock); | 513 | spin_unlock_bh(&nf_conntrack_expect_lock); |
| @@ -424,7 +424,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) | |||
| 424 | */ | 424 | */ |
| 425 | synchronize_rcu(); | 425 | synchronize_rcu(); |
| 426 | 426 | ||
| 427 | - nf_ct_expect_iterate_destroy(expect_iter_me, NULL); | 427 | + nf_ct_expect_iterate_destroy(expect_iter_me, me); |
| 428 | nf_ct_iterate_destroy(unhelp, me); | 428 | nf_ct_iterate_destroy(unhelp, me); |
| 429 | } | 429 | } |
| 430 | EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); | 430 | EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); |
| @@ -3327,31 +3327,37 @@ static int ctnetlink_get_expect(struct sk_buff *skb, | |||
| 3327 | if (err < 0) | 3327 | if (err < 0) |
| 3328 | return err; | 3328 | return err; |
| 3329 | 3329 | ||
| 3330 | + skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
| 3331 | + if (!skb2) | ||
| 3332 | + return -ENOMEM; | ||
| 3333 | + | ||
| 3334 | + spin_lock_bh(&nf_conntrack_expect_lock); | ||
| 3330 | exp = nf_ct_expect_find_get(info->net, &zone, &tuple); | 3335 | exp = nf_ct_expect_find_get(info->net, &zone, &tuple); |
| 3331 | - if (!exp) | 3336 | + if (!exp) { |
| 3337 | + spin_unlock_bh(&nf_conntrack_expect_lock); | ||
| 3338 | + kfree_skb(skb2); | ||
| 3332 | return -ENOENT; | 3339 | return -ENOENT; |
| 3340 | + } | ||
| 3333 | 3341 | ||
| 3334 | if (cda[CTA_EXPECT_ID]) { | 3342 | if (cda[CTA_EXPECT_ID]) { |
| 3335 | __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]); | 3343 | __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]); |
| 3336 | 3344 | ||
| 3337 | if (id != nf_expect_get_id(exp)) { | 3345 | if (id != nf_expect_get_id(exp)) { |
| 3338 | nf_ct_expect_put(exp); | 3346 | nf_ct_expect_put(exp); |
| 3347 | + spin_unlock_bh(&nf_conntrack_expect_lock); | ||
| 3348 | + kfree_skb(skb2); | ||
| 3339 | return -ENOENT; | 3349 | return -ENOENT; |
| 3340 | } | 3350 | } |
| 3341 | } | 3351 | } |
| 3342 | 3352 | ||
| 3343 | - skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
| 3344 | - if (!skb2) { | ||
| 3345 | - nf_ct_expect_put(exp); | ||
| 3346 | - return -ENOMEM; | ||
| 3347 | - } | ||
| 3348 | - | ||
| 3349 | rcu_read_lock(); | 3353 | rcu_read_lock(); |
| 3350 | err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).portid, | 3354 | err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).portid, |
| 3351 | info->nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, | 3355 | info->nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, |
| 3352 | exp); | 3356 | exp); |
| 3353 | rcu_read_unlock(); | 3357 | rcu_read_unlock(); |
| 3354 | nf_ct_expect_put(exp); | 3358 | nf_ct_expect_put(exp); |
| 3359 | + spin_unlock_bh(&nf_conntrack_expect_lock); | ||
| 3360 | + | ||
| 3355 | if (err <= 0) { | 3361 | if (err <= 0) { |
| 3356 | kfree_skb(skb2); | 3362 | kfree_skb(skb2); |
| 3357 | return -ENOMEM; | 3363 | return -ENOMEM; |
| @@ -3401,22 +3407,26 @@ static int ctnetlink_del_expect(struct sk_buff *skb, | |||
| 3401 | if (err < 0) | 3407 | if (err < 0) |
| 3402 | return err; | 3408 | return err; |
| 3403 | 3409 | ||
| 3410 | + spin_lock_bh(&nf_conntrack_expect_lock); | ||
| 3411 | + | ||
| 3404 | /* bump usage count to 2 */ | 3412 | /* bump usage count to 2 */ |
| 3405 | exp = nf_ct_expect_find_get(info->net, &zone, &tuple); | 3413 | exp = nf_ct_expect_find_get(info->net, &zone, &tuple); |
| 3406 | - if (!exp) | 3414 | + if (!exp) { |
| 3415 | + spin_unlock_bh(&nf_conntrack_expect_lock); | ||
| 3407 | return -ENOENT; | 3416 | return -ENOENT; |
| 3417 | + } | ||
| 3408 | 3418 | ||
| 3409 | if (cda[CTA_EXPECT_ID]) { | 3419 | if (cda[CTA_EXPECT_ID]) { |
| 3410 | __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]); | 3420 | __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]); |
| 3411 | 3421 | ||
| 3412 | if (id != nf_expect_get_id(exp)) { | 3422 | if (id != nf_expect_get_id(exp)) { |
| 3413 | nf_ct_expect_put(exp); | 3423 | nf_ct_expect_put(exp); |
| 3424 | + spin_unlock_bh(&nf_conntrack_expect_lock); | ||
| 3414 | return -ENOENT; | 3425 | return -ENOENT; |
| 3415 | } | 3426 | } |
| 3416 | } | 3427 | } |
| 3417 | 3428 | ||
| 3418 | /* after list removal, usage count == 1 */ | 3429 | /* after list removal, usage count == 1 */ |
| 3419 | - spin_lock_bh(&nf_conntrack_expect_lock); | ||
| 3420 | if (del_timer(&exp->timeout)) { | 3430 | if (del_timer(&exp->timeout)) { |
| 3421 | nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).portid, | 3431 | nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).portid, |
| 3422 | nlmsg_report(info->nlh)); | 3432 | nlmsg_report(info->nlh)); |
| @@ -3552,6 +3562,12 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, | |||
| 3552 | exp, nf_ct_l3num(ct)); | 3562 | exp, nf_ct_l3num(ct)); |
| 3553 | if (err < 0) | 3563 | if (err < 0) |
| 3554 | goto err_out; | 3564 | goto err_out; |
| 3565 | + | ||
| 3566 | + } else { | ||
| 3567 | + memset(&exp->saved_addr, 0, sizeof(exp->saved_addr)); | ||
| 3568 | + memset(&exp->saved_proto, 0, sizeof(exp->saved_proto)); | ||
| 3569 | + exp->dir = 0; | ||
| 3570 | + | ||
| 3555 | } | 3571 | } |
| 3556 | return exp; | 3572 | return exp; |
| 3557 | err_out: | 3573 | err_out: |
| @@ -10449,7 +10449,6 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, | |||
| 10449 | switch (data->verdict.code & NF_VERDICT_MASK) { | 10449 | switch (data->verdict.code & NF_VERDICT_MASK) { |
| 10450 | case NF_ACCEPT: | 10450 | case NF_ACCEPT: |
| 10451 | case NF_DROP: | 10451 | case NF_DROP: |
| 10452 | - case NF_QUEUE: | ||
| 10453 | break; | 10452 | break; |
| 10454 | default: | 10453 | default: |
| 10455 | return -EINVAL; | 10454 | return -EINVAL; |
| @@ -603,10 +603,10 @@ nfnl_cthelper_dump_table(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 603 | goto out; | 603 | goto out; |
| 604 | } | 604 | } |
| 605 | } | 605 | } |
| 606 | - } | 606 | + if (cb->args[1]) { |
| 607 | - if (cb->args[1]) { | 607 | + cb->args[1] = 0; |
| 608 | - cb->args[1] = 0; | 608 | + goto restart; |
| 609 | - goto restart; | 609 | + } |
| 610 | } | 610 | } |
| 611 | out: | 611 | out: |
| 612 | rcu_read_unlock(); | 612 | rcu_read_unlock(); |
| @@ -361,10 +361,10 @@ static void | |||
| 361 | __nfulnl_send(struct nfulnl_instance *inst) | 361 | __nfulnl_send(struct nfulnl_instance *inst) |
| 362 | { | 362 | { |
| 363 | if (inst->qlen > 1) { | 363 | if (inst->qlen > 1) { |
| 364 | - struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0, | 364 | + struct nlmsghdr *nlh = nfnl_msg_put(inst->skb, 0, 0, |
| 365 | - NLMSG_DONE, | 365 | + NLMSG_DONE, 0, |
| 366 | - sizeof(struct nfgenmsg), | 366 | + AF_UNSPEC, NFNETLINK_V0, |
| 367 | - 0); | 367 | + htons(inst->group_num)); |
| 368 | if (WARN_ONCE(!nlh, "bad nlskb size: %u, tailroom %d\n", | 368 | if (WARN_ONCE(!nlh, "bad nlskb size: %u, tailroom %d\n", |
| 369 | inst->skb->len, skb_tailroom(inst->skb))) { | 369 | inst->skb->len, skb_tailroom(inst->skb))) { |
| 370 | kfree_skb(inst->skb); | 370 | kfree_skb(inst->skb); |
| @@ -1283,8 +1283,10 @@ static int nfqnl_recv_verdict(struct sk_buff *skb, const struct nfnl_info *info, | |||
| 1283 | 1283 | ||
| 1284 | if (entry->state.pf == PF_BRIDGE) { | 1284 | if (entry->state.pf == PF_BRIDGE) { |
| 1285 | err = nfqa_parse_bridge(entry, nfqa); | 1285 | err = nfqa_parse_bridge(entry, nfqa); |
| 1286 | - if (err < 0) | 1286 | + if (err < 0) { |
| 1287 | + nfqnl_reinject(entry, NF_DROP); | ||
| 1287 | return err; | 1288 | return err; |
| 1289 | + } | ||
| 1288 | } | 1290 | } |
| 1289 | 1291 | ||
| 1290 | if (nfqa[NFQA_PAYLOAD]) { | 1292 | if (nfqa[NFQA_PAYLOAD]) { |
| @@ -23,6 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | + | ||
| 26 | 27 | ||
| 27 | struct nft_ct_helper_obj { | 28 | struct nft_ct_helper_obj { |
| 28 | struct nf_conntrack_helper *helper4; | 29 | struct nf_conntrack_helper *helper4; |
| @@ -527,6 +528,7 @@ static void __nft_ct_set_destroy(const struct nft_ctx *ctx, struct nft_ct *priv) | |||
| 527 | 528 | ||
| 528 | 529 | ||
| 529 | case NFT_CT_ZONE: | 530 | case NFT_CT_ZONE: |
| 531 | + nf_queue_nf_hook_drop(ctx->net); | ||
| 530 | mutex_lock(&nft_ct_pcpu_mutex); | 532 | mutex_lock(&nft_ct_pcpu_mutex); |
| 531 | if (--nft_ct_pcpu_template_refcnt == 0) | 533 | if (--nft_ct_pcpu_template_refcnt == 0) |
| 532 | nft_ct_tmpl_put_pcpu(); | 534 | nft_ct_tmpl_put_pcpu(); |
| @@ -997,6 +999,7 @@ static void nft_ct_timeout_obj_destroy(const struct nft_ctx *ctx, | |||
| 997 | struct nft_ct_timeout_obj *priv = nft_obj_data(obj); | 999 | struct nft_ct_timeout_obj *priv = nft_obj_data(obj); |
| 998 | struct nf_ct_timeout *timeout = priv->timeout; | 1000 | struct nf_ct_timeout *timeout = priv->timeout; |
| 999 | 1001 | ||
| 1002 | + nf_queue_nf_hook_drop(ctx->net); | ||
| 1000 | nf_ct_untimeout(ctx->net, timeout); | 1003 | nf_ct_untimeout(ctx->net, timeout); |
| 1001 | nf_ct_netns_put(ctx->net, ctx->family); | 1004 | nf_ct_netns_put(ctx->net, ctx->family); |
| 1002 | kfree(priv->timeout); | 1005 | kfree(priv->timeout); |
| @@ -1129,6 +1132,7 @@ static void nft_ct_helper_obj_destroy(const struct nft_ctx *ctx, | |||
| 1129 | { | 1132 | { |
| 1130 | struct nft_ct_helper_obj *priv = nft_obj_data(obj); | 1133 | struct nft_ct_helper_obj *priv = nft_obj_data(obj); |
| 1131 | 1134 | ||
| 1135 | + nf_queue_nf_hook_drop(ctx->net); | ||
| 1132 | if (priv->helper4) | 1136 | if (priv->helper4) |
| 1133 | nf_conntrack_helper_put(priv->helper4); | 1137 | nf_conntrack_helper_put(priv->helper4); |
| 1134 | if (priv->helper6) | 1138 | if (priv->helper6) |
| @@ -1532,6 +1532,7 @@ static void pipapo_drop(struct nft_pipapo_match *m, | |||
| 1532 | int i; | 1532 | int i; |
| 1533 | 1533 | ||
| 1534 | nft_pipapo_for_each_field(f, i, m) { | 1534 | nft_pipapo_for_each_field(f, i, m) { |
| 1535 | + bool last = i == m->field_count - 1; | ||
| 1535 | int g; | 1536 | int g; |
| 1536 | 1537 | ||
| 1537 | for (g = 0; g < f->groups; g++) { | 1538 | for (g = 0; g < f->groups; g++) { |
| @@ -1551,7 +1552,7 @@ static void pipapo_drop(struct nft_pipapo_match *m, | |||
| 1551 | } | 1552 | } |
| 1552 | 1553 | ||
| 1553 | pipapo_unmap(f->mt, f->rules, rulemap[i].to, rulemap[i].n, | 1554 | pipapo_unmap(f->mt, f->rules, rulemap[i].to, rulemap[i].n, |
| 1554 | - rulemap[i + 1].n, i == m->field_count - 1); | 1555 | + last ? 0 : rulemap[i + 1].n, last); |
| 1555 | if (pipapo_resize(f, f->rules, f->rules - rulemap[i].n)) { | 1556 | if (pipapo_resize(f, f->rules, f->rules - rulemap[i].n)) { |
| 1556 | /* We can ignore this, a failure to shrink tables down | 1557 | /* We can ignore this, a failure to shrink tables down |
| 1557 | * doesn't make tables invalid. | 1558 | * doesn't make tables invalid. |
| @@ -242,7 +242,7 @@ static int nft_pipapo_avx2_lookup_4b_2(unsigned long *map, unsigned long *fill, | |||
| 242 | 242 | ||
| 243 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); | 243 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); |
| 244 | if (last) | 244 | if (last) |
| 245 | - return b; | 245 | + ret = b; |
| 246 | 246 | ||
| 247 | if (unlikely(ret == -1)) | 247 | if (unlikely(ret == -1)) |
| 248 | ret = b / XSAVE_YMM_SIZE; | 248 | ret = b / XSAVE_YMM_SIZE; |
| @@ -319,7 +319,7 @@ static int nft_pipapo_avx2_lookup_4b_4(unsigned long *map, unsigned long *fill, | |||
| 319 | 319 | ||
| 320 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); | 320 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); |
| 321 | if (last) | 321 | if (last) |
| 322 | - return b; | 322 | + ret = b; |
| 323 | 323 | ||
| 324 | if (unlikely(ret == -1)) | 324 | if (unlikely(ret == -1)) |
| 325 | ret = b / XSAVE_YMM_SIZE; | 325 | ret = b / XSAVE_YMM_SIZE; |
| @@ -414,7 +414,7 @@ static int nft_pipapo_avx2_lookup_4b_8(unsigned long *map, unsigned long *fill, | |||
| 414 | 414 | ||
| 415 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); | 415 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); |
| 416 | if (last) | 416 | if (last) |
| 417 | - return b; | 417 | + ret = b; |
| 418 | 418 | ||
| 419 | if (unlikely(ret == -1)) | 419 | if (unlikely(ret == -1)) |
| 420 | ret = b / XSAVE_YMM_SIZE; | 420 | ret = b / XSAVE_YMM_SIZE; |
| @@ -505,7 +505,7 @@ static int nft_pipapo_avx2_lookup_4b_12(unsigned long *map, unsigned long *fill, | |||
| 505 | 505 | ||
| 506 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); | 506 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); |
| 507 | if (last) | 507 | if (last) |
| 508 | - return b; | 508 | + ret = b; |
| 509 | 509 | ||
| 510 | if (unlikely(ret == -1)) | 510 | if (unlikely(ret == -1)) |
| 511 | ret = b / XSAVE_YMM_SIZE; | 511 | ret = b / XSAVE_YMM_SIZE; |
| @@ -641,7 +641,7 @@ static int nft_pipapo_avx2_lookup_4b_32(unsigned long *map, unsigned long *fill, | |||
| 641 | 641 | ||
| 642 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); | 642 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); |
| 643 | if (last) | 643 | if (last) |
| 644 | - return b; | 644 | + ret = b; |
| 645 | 645 | ||
| 646 | if (unlikely(ret == -1)) | 646 | if (unlikely(ret == -1)) |
| 647 | ret = b / XSAVE_YMM_SIZE; | 647 | ret = b / XSAVE_YMM_SIZE; |
| @@ -699,7 +699,7 @@ static int nft_pipapo_avx2_lookup_8b_1(unsigned long *map, unsigned long *fill, | |||
| 699 | 699 | ||
| 700 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); | 700 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); |
| 701 | if (last) | 701 | if (last) |
| 702 | - return b; | 702 | + ret = b; |
| 703 | 703 | ||
| 704 | if (unlikely(ret == -1)) | 704 | if (unlikely(ret == -1)) |
| 705 | ret = b / XSAVE_YMM_SIZE; | 705 | ret = b / XSAVE_YMM_SIZE; |
| @@ -764,7 +764,7 @@ static int nft_pipapo_avx2_lookup_8b_2(unsigned long *map, unsigned long *fill, | |||
| 764 | 764 | ||
| 765 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); | 765 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); |
| 766 | if (last) | 766 | if (last) |
| 767 | - return b; | 767 | + ret = b; |
| 768 | 768 | ||
| 769 | if (unlikely(ret == -1)) | 769 | if (unlikely(ret == -1)) |
| 770 | ret = b / XSAVE_YMM_SIZE; | 770 | ret = b / XSAVE_YMM_SIZE; |
| @@ -839,7 +839,7 @@ static int nft_pipapo_avx2_lookup_8b_4(unsigned long *map, unsigned long *fill, | |||
| 839 | 839 | ||
| 840 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); | 840 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); |
| 841 | if (last) | 841 | if (last) |
| 842 | - return b; | 842 | + ret = b; |
| 843 | 843 | ||
| 844 | if (unlikely(ret == -1)) | 844 | if (unlikely(ret == -1)) |
| 845 | ret = b / XSAVE_YMM_SIZE; | 845 | ret = b / XSAVE_YMM_SIZE; |
| @@ -925,7 +925,7 @@ static int nft_pipapo_avx2_lookup_8b_6(unsigned long *map, unsigned long *fill, | |||
| 925 | 925 | ||
| 926 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); | 926 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); |
| 927 | if (last) | 927 | if (last) |
| 928 | - return b; | 928 | + ret = b; |
| 929 | 929 | ||
| 930 | if (unlikely(ret == -1)) | 930 | if (unlikely(ret == -1)) |
| 931 | ret = b / XSAVE_YMM_SIZE; | 931 | ret = b / XSAVE_YMM_SIZE; |
| @@ -1019,7 +1019,7 @@ static int nft_pipapo_avx2_lookup_8b_16(unsigned long *map, unsigned long *fill, | |||
| 1019 | 1019 | ||
| 1020 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); | 1020 | b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); |
| 1021 | if (last) | 1021 | if (last) |
| 1022 | - return b; | 1022 | + ret = b; |
| 1023 | 1023 | ||
| 1024 | if (unlikely(ret == -1)) | 1024 | if (unlikely(ret == -1)) |
| 1025 | ret = b / XSAVE_YMM_SIZE; | 1025 | ret = b / XSAVE_YMM_SIZE; |
| @@ -53,6 +53,9 @@ static int cgroup_mt_check_v1(const struct xt_mtchk_param *par) | |||
| 53 | 53 | ||
| 54 | info->priv = NULL; | 54 | info->priv = NULL; |
| 55 | if (info->has_path) { | 55 | if (info->has_path) { |
| 56 | + if (strnlen(info->path, sizeof(info->path)) >= sizeof(info->path)) | ||
| 57 | + return -ENAMETOOLONG; | ||
| 58 | + | ||
| 56 | cgrp = cgroup_get_from_path(info->path); | 59 | cgrp = cgroup_get_from_path(info->path); |
| 57 | if (IS_ERR(cgrp)) { | 60 | if (IS_ERR(cgrp)) { |
| 58 | pr_info_ratelimited("invalid path, errno=%ld\n", | 61 | pr_info_ratelimited("invalid path, errno=%ld\n", |
| @@ -85,6 +88,9 @@ static int cgroup_mt_check_v2(const struct xt_mtchk_param *par) | |||
| 85 | 88 | ||
| 86 | info->priv = NULL; | 89 | info->priv = NULL; |
| 87 | if (info->has_path) { | 90 | if (info->has_path) { |
| 91 | + if (strnlen(info->path, sizeof(info->path)) >= sizeof(info->path)) | ||
| 92 | + return -ENAMETOOLONG; | ||
| 93 | + | ||
| 88 | cgrp = cgroup_get_from_path(info->path); | 94 | cgrp = cgroup_get_from_path(info->path); |
| 89 | if (IS_ERR(cgrp)) { | 95 | if (IS_ERR(cgrp)) { |
| 90 | pr_info_ratelimited("invalid path, errno=%ld\n", | 96 | pr_info_ratelimited("invalid path, errno=%ld\n", |
| @@ -62,10 +62,10 @@ dccp_find_option(u_int8_t option, | |||
| 62 | return true; | 62 | return true; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | - if (op[i] < 2) | 65 | + if (op[i] < 2 || i == optlen - 1) |
| 66 | i++; | 66 | i++; |
| 67 | else | 67 | else |
| 68 | - i += op[i+1]?:1; | 68 | + i += op[i + 1] ? : 1; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | spin_unlock_bh(&dccp_buflock); | 71 | spin_unlock_bh(&dccp_buflock); |
| @@ -91,6 +91,11 @@ static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par) | |||
| 91 | goto err1; | 91 | goto err1; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | + if (strnlen(info->name1, sizeof(info->name1)) >= sizeof(info->name1)) | ||
| 95 | + return -ENAMETOOLONG; | ||
| 96 | + if (strnlen(info->name2, sizeof(info->name2)) >= sizeof(info->name2)) | ||
| 97 | + return -ENAMETOOLONG; | ||
| 98 | + | ||
| 94 | ret = -ENOENT; | 99 | ret = -ENOENT; |
| 95 | est1 = xt_rateest_lookup(par->net, info->name1); | 100 | est1 = xt_rateest_lookup(par->net, info->name1); |
| 96 | if (!est1) | 101 | if (!est1) |
| @@ -61,7 +61,7 @@ tcpmss_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 61 | return (mssval >= info->mss_min && | 61 | return (mssval >= info->mss_min && |
| 62 | mssval <= info->mss_max) ^ info->invert; | 62 | mssval <= info->mss_max) ^ info->invert; |
| 63 | } | 63 | } |
| 64 | - if (op[i] < 2) | 64 | + if (op[i] < 2 || i == optlen - 1) |
| 65 | i++; | 65 | i++; |
| 66 | else | 66 | else |
| 67 | i += op[i+1] ? : 1; | 67 | i += op[i+1] ? : 1; |
| @@ -59,8 +59,10 @@ tcp_find_option(u_int8_t option, | |||
| 59 | 59 | ||
| 60 | for (i = 0; i < optlen; ) { | 60 | for (i = 0; i < optlen; ) { |
| 61 | if (op[i] == option) return !invert; | 61 | if (op[i] == option) return !invert; |
| 62 | - if (op[i] < 2) i++; | 62 | + if (op[i] < 2 || i == optlen - 1) |
| 63 | - else i += op[i+1]?:1; | 63 | + i++; |
| 64 | + else | ||
| 65 | + i += op[i + 1] ? : 1; | ||
| 64 | } | 66 | } |
| 65 | 67 | ||
| 66 | return invert; | 68 | return invert; |
| @@ -128,7 +128,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, | |||
| 128 | struct tcf_skbedit *d; | 128 | struct tcf_skbedit *d; |
| 129 | u32 flags = 0, *priority = NULL, *mark = NULL, *mask = NULL; | 129 | u32 flags = 0, *priority = NULL, *mark = NULL, *mask = NULL; |
| 130 | u16 *queue_mapping = NULL, *ptype = NULL; | 130 | u16 *queue_mapping = NULL, *ptype = NULL; |
| 131 | - u16 mapping_mod = 1; | 131 | + u32 mapping_mod = 1; |
| 132 | bool exists = false; | 132 | bool exists = false; |
| 133 | int ret = 0, err; | 133 | int ret = 0, err; |
| 134 | u32 index; | 134 | u32 index; |
| @@ -196,6 +196,10 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, | |||
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | mapping_mod = *queue_mapping_max - *queue_mapping + 1; | 198 | mapping_mod = *queue_mapping_max - *queue_mapping + 1; |
| 199 | + if (mapping_mod > U16_MAX) { | ||
| 200 | + NL_SET_ERR_MSG_MOD(extack, "The range of queue_mapping is invalid."); | ||
| 201 | + return -EINVAL; | ||
| 202 | + } | ||
| 199 | flags |= SKBEDIT_F_TXQ_SKBHASH; | 203 | flags |= SKBEDIT_F_TXQ_SKBHASH; |
| 200 | } | 204 | } |
| 201 | if (*pure_flags & SKBEDIT_F_INHERITDSFIELD) | 205 | if (*pure_flags & SKBEDIT_F_INHERITDSFIELD) |
| @@ -2879,6 +2879,7 @@ static int tc_chain_fill_node(const struct tcf_proto_ops *tmplt_ops, | |||
| 2879 | tcm->tcm__pad1 = 0; | 2879 | tcm->tcm__pad1 = 0; |
| 2880 | tcm->tcm__pad2 = 0; | 2880 | tcm->tcm__pad2 = 0; |
| 2881 | tcm->tcm_handle = 0; | 2881 | tcm->tcm_handle = 0; |
| 2882 | + tcm->tcm_info = 0; | ||
| 2882 | if (block->q) { | 2883 | if (block->q) { |
| 2883 | tcm->tcm_ifindex = qdisc_dev(block->q)->ifindex; | 2884 | tcm->tcm_ifindex = qdisc_dev(block->q)->ifindex; |
| 2884 | tcm->tcm_parent = block->q->handle; | 2885 | tcm->tcm_parent = block->q->handle; |
| @@ -515,6 +515,14 @@ static int xfrm_dev_down(struct net_device *dev) | |||
| 515 | return NOTIFY_DONE; | 515 | return NOTIFY_DONE; |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | +static int xfrm_dev_unregister(struct net_device *dev) | ||
| 519 | +{ | ||
| 520 | + xfrm_dev_state_flush(dev_net(dev), dev, true); | ||
| 521 | + xfrm_dev_policy_flush(dev_net(dev), dev, true); | ||
| 522 | + | ||
| 523 | + return NOTIFY_DONE; | ||
| 524 | +} | ||
| 525 | + | ||
| 518 | static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr) | 526 | static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr) |
| 519 | { | 527 | { |
| 520 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | 528 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); |
| @@ -527,8 +535,10 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void | |||
| 527 | return xfrm_api_check(dev); | 535 | return xfrm_api_check(dev); |
| 528 | 536 | ||
| 529 | case NETDEV_DOWN: | 537 | case NETDEV_DOWN: |
| 530 | - case NETDEV_UNREGISTER: | ||
| 531 | return xfrm_dev_down(dev); | 538 | return xfrm_dev_down(dev); |
| 539 | + | ||
| 540 | + case NETDEV_UNREGISTER: | ||
| 541 | + return xfrm_dev_unregister(dev); | ||
| 532 | } | 542 | } |
| 533 | return NOTIFY_DONE; | 543 | return NOTIFY_DONE; |
| 534 | } | 544 | } |
| @@ -4208,6 +4208,8 @@ static void xfrm_policy_fini(struct net *net) | |||
| 4208 | 4208 | ||
| 4209 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, false); | 4209 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, false); |
| 4210 | 4210 | ||
| 4211 | + synchronize_rcu(); | ||
| 4212 | + | ||
| 4211 | WARN_ON(!list_empty(&net->xfrm.policy_all)); | 4213 | WARN_ON(!list_empty(&net->xfrm.policy_all)); |
| 4212 | 4214 | ||
| 4213 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | 4215 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { |
| @@ -2407,7 +2407,7 @@ static inline unsigned int xfrm_aevent_msgsize(struct xfrm_state *x) | |||
| 2407 | + nla_total_size_64bit(sizeof(struct xfrm_lifetime_cur)) | 2407 | + nla_total_size_64bit(sizeof(struct xfrm_lifetime_cur)) |
| 2408 | + nla_total_size(sizeof(struct xfrm_mark)) | 2408 | + nla_total_size(sizeof(struct xfrm_mark)) |
| 2409 | + nla_total_size(4) /* XFRM_AE_RTHR */ | 2409 | + nla_total_size(4) /* XFRM_AE_RTHR */ |
| 2410 | - + nla_total_size(4); /* XFRM_AE_ETHR */ | 2410 | + + nla_total_size(sizeof(x->if_id)); /* XFRMA_IF_ID */ |
| 2411 | } | 2411 | } |
| 2412 | 2412 | ||
| 2413 | static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct km_event *c) | 2413 | static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct km_event *c) |
| @@ -2508,7 +2508,12 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 2508 | c.portid = nlh->nlmsg_pid; | 2508 | c.portid = nlh->nlmsg_pid; |
| 2509 | 2509 | ||
| 2510 | err = build_aevent(r_skb, x, &c); | 2510 | err = build_aevent(r_skb, x, &c); |
| 2511 | - BUG_ON(err < 0); | 2511 | + if (err < 0) { |
| 2512 | + spin_unlock_bh(&x->lock); | ||
| 2513 | + xfrm_state_put(x); | ||
| 2514 | + kfree_skb(r_skb); | ||
| 2515 | + return err; | ||
| 2516 | + } | ||
| 2512 | 2517 | ||
| 2513 | err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).portid); | 2518 | err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).portid); |
| 2514 | spin_unlock_bh(&x->lock); | 2519 | spin_unlock_bh(&x->lock); |
| @@ -3787,6 +3792,7 @@ static int build_mapping(struct sk_buff *skb, struct xfrm_state *x, | |||
| 3787 | 3792 | ||
| 3788 | um = nlmsg_data(nlh); | 3793 | um = nlmsg_data(nlh); |
| 3789 | 3794 | ||
| 3795 | + memset(&um->id, 0, sizeof(um->id)); | ||
| 3790 | memcpy(&um->id.daddr, &x->id.daddr, sizeof(um->id.daddr)); | 3796 | memcpy(&um->id.daddr, &x->id.daddr, sizeof(um->id.daddr)); |
| 3791 | um->id.spi = x->id.spi; | 3797 | um->id.spi = x->id.spi; |
| 3792 | um->id.family = x->props.family; | 3798 | um->id.family = x->props.family; |
| @@ -12,6 +12,8 @@ | |||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | + | ||
| 16 | + | ||
| 15 | 17 | ||
| 16 | 18 | ||
| 17 | 19 | ||
| @@ -164,3 +166,36 @@ void __init ima_load_kexec_buffer(void) | |||
| 164 | pr_debug("Error restoring the measurement list: %d\n", rc); | 166 | pr_debug("Error restoring the measurement list: %d\n", rc); |
| 165 | } | 167 | } |
| 166 | } | 168 | } |
| 169 | + | ||
| 170 | +/* | ||
| 171 | + * ima_validate_range - verify a physical buffer lies in addressable RAM | ||
| 172 | + * @phys: physical start address of the buffer from previous kernel | ||
| 173 | + * @size: size of the buffer | ||
| 174 | + * | ||
| 175 | + * On success return 0. On failure returns -EINVAL so callers can skip | ||
| 176 | + * restoring. | ||
| 177 | + */ | ||
| 178 | +int ima_validate_range(phys_addr_t phys, size_t size) | ||
| 179 | +{ | ||
| 180 | + unsigned long start_pfn, end_pfn; | ||
| 181 | + phys_addr_t end_phys; | ||
| 182 | + | ||
| 183 | + if (check_add_overflow(phys, (phys_addr_t)size - 1, &end_phys)) | ||
| 184 | + return -EINVAL; | ||
| 185 | + | ||
| 186 | + start_pfn = PHYS_PFN(phys); | ||
| 187 | + end_pfn = PHYS_PFN(end_phys); | ||
| 188 | + | ||
| 189 | + | ||
| 190 | + if (!pfn_range_is_mapped(start_pfn, end_pfn)) | ||
| 191 | + | ||
| 192 | + if (!page_is_ram(start_pfn) || !page_is_ram(end_pfn)) | ||
| 193 | + | ||
| 194 | + { | ||
| 195 | + pr_warn("IMA: previous kernel measurement buffer %pa (size 0x%zx) lies outside available memory\n", | ||
| 196 | + &phys, size); | ||
| 197 | + return -EINVAL; | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + return 0; | ||
| 201 | +} | ||
| @@ -1236,7 +1236,7 @@ static const char *uaccess_safe_builtin[] = { | |||
| 1236 | "copy_mc_enhanced_fast_string", | 1236 | "copy_mc_enhanced_fast_string", |
| 1237 | "rep_stos_alternative", | 1237 | "rep_stos_alternative", |
| 1238 | "rep_movs_alternative", | 1238 | "rep_movs_alternative", |
| 1239 | - "__copy_user_nocache", | 1239 | + "copy_to_nontemporal", |
| 1240 | NULL | 1240 | NULL |
| 1241 | }; | 1241 | }; |
| 1242 | 1242 | ||