/* * NFC Digital Protocol stack * Copyright (c) 2013, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * */ #ifndef __DIGITAL_H #define __DIGITAL_H #include #include #include #include #define PROTOCOL_ERR(req) pr_err("%d: NFC Digital Protocol error: %s\n", \ __LINE__, req) #define DIGITAL_CMD_IN_SEND 0 #define DIGITAL_CMD_TG_SEND 1 #define DIGITAL_CMD_TG_LISTEN 2 #define DIGITAL_CMD_TG_LISTEN_MDAA 3 #define DIGITAL_CMD_TG_LISTEN_MD 4 #define DIGITAL_MAX_HEADER_LEN 7 #define DIGITAL_CRC_LEN 2 #define DIGITAL_SENSF_NFCID2_NFC_DEP_B1 0x01 #define DIGITAL_SENSF_NFCID2_NFC_DEP_B2 0xFE #define DIGITAL_SENS_RES_NFC_DEP 0x0100 #define DIGITAL_SEL_RES_NFC_DEP 0x40 #define DIGITAL_SENSF_FELICA_SC 0xFFFF #define DIGITAL_DRV_CAPS_IN_CRC(ddev) \ ((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_IN_CRC) #define DIGITAL_DRV_CAPS_TG_CRC(ddev) \ ((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_TG_CRC) struct digital_data_exch { data_exchange_cb_t cb; void *cb_context; }; struct sk_buff *digital_skb_alloc(struct nfc_digital_dev *ddev, unsigned int len); int digital_send_cmd(struct nfc_digital_dev *ddev, u8 cmd_type, struct sk_buff *skb, struct digital_tg_mdaa_params *params, u16 timeout, nfc_digital_cmd_complete_t cmd_cb, void *cb_context); int digital_in_configure_hw(struct nfc_digital_dev *ddev, int type, int param); static inline int digital_in_send_cmd(struct nfc_digital_dev *ddev, struct sk_buff *skb, u16 timeout, nfc_digital_cmd_complete_t cmd_cb, void *cb_context) { return digital_send_cmd(ddev, DIGITAL_CMD_IN_SEND, skb, NULL, timeout, cmd_cb, cb_context); } void digital_poll_next_tech(struct nfc_digital_dev *ddev); int digital_in_send_sens_req(struct nfc_digital_dev *ddev, u8 rf_tech); int digital_in_send_sensb_req(struct nfc_digital_dev *ddev, u8 rf_tech); int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech); int digital_in_send_iso15693_inv_req(struct nfc_digital_dev *ddev, u8 rf_tech); int digital_in_iso_dep_pull_sod(struct nfc_digital_dev *ddev, struct sk_buff *skb); int digital_in_iso_dep_push_sod(struct nfc_digital_dev *ddev, struct sk_buff *skb); int digital_target_found(struct nfc_digital_dev *ddev, struct nfc_target *target, u8 protocol); int digital_in_recv_mifare_res(struct sk_buff *resp); int digital_in_send_atr_req(struct nfc_digital_dev *ddev, struct nfc_target *target, __u8 comm_mode, __u8 *gb, size_t gb_len); int digital_in_send_dep_req(struct nfc_digital_dev *ddev, struct nfc_target *target, struct sk_buff *skb, struct digital_data_exch *data_exch); int digital_tg_configure_hw(struct nfc_digital_dev *ddev, int type, int param); static inline int digital_tg_send_cmd(struct nfc_digital_dev *ddev, struct sk_buff *skb, u16 timeout, nfc_digital_cmd_complete_t cmd_cb, void *cb_context) { return digital_send_cmd(ddev, DIGITAL_CMD_TG_SEND, skb, NULL, timeout, cmd_cb, cb_context); } void digital_tg_recv_sens_req(struct nfc_digital_dev *ddev, void *arg, struct sk_buff *resp); void digital_tg_recv_sensf_req(struct nfc_digital_dev *ddev, void *arg, struct sk_buff *resp); static inline int digital_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, nfc_digital_cmd_complete_t cb, void *arg) { return digital_send_cmd(ddev, DIGITAL_CMD_TG_LISTEN, NULL, NULL, timeout, cb, arg); } void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg, struct sk_buff *resp); int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb); int digital_tg_listen_nfca(struct nfc_digital_dev *ddev, u8 rf_tech); int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech); void digital_tg_recv_md_req(struct nfc_digital_dev *ddev, void *arg, struct sk_buff *resp); typedef u16 (*crc_func_t)(u16, const u8 *, size_t); #define CRC_A_INIT 0x6363 #define CRC_B_INIT 0xFFFF #define CRC_F_INIT 0x0000 void digital_skb_add_crc(struct sk_buff *skb, crc_func_t crc_func, u16 init, u8 bitwise_inv, u8 msb_first); static inline void digital_skb_add_crc_a(struct sk_buff *skb) { digital_skb_add_crc(skb, crc_ccitt, CRC_A_INIT, 0, 0); } static inline void digital_skb_add_crc_b(struct sk_buff *skb) { digital_skb_add_crc(skb, crc_ccitt, CRC_B_INIT, 1, 0); } static inline void digital_skb_add_crc_f(struct sk_buff *skb) { digital_skb_add_crc(skb, crc_itu_t, CRC_F_INIT, 0, 1); } static inline void digital_skb_add_crc_none(struct sk_buff *skb) { return; } int digital_skb_check_crc(struct sk_buff *skb, crc_func_t crc_func, u16 crc_init, u8 bitwise_inv, u8 msb_first); static inline int digital_skb_check_crc_a(struct sk_buff *skb) { return digital_skb_check_crc(skb, crc_ccitt, CRC_A_INIT, 0, 0); } static inline int digital_skb_check_crc_b(struct sk_buff *skb) { return digital_skb_check_crc(skb, crc_ccitt, CRC_B_INIT, 1, 0); } static inline int digital_skb_check_crc_f(struct sk_buff *skb) { return digital_skb_check_crc(skb, crc_itu_t, CRC_F_INIT, 0, 1); } static inline int digital_skb_check_crc_none(struct sk_buff *skb) { return 0; } #endif /* __DIGITAL_H */ 55350abb95d4f1c0dc860a /net/lapb/lapb_in.c parente6e7b48b295afa5a5ab440de0a94d9ad8b3ce2d0 (diff)
drm/atomic: Fix double free in drm_atomic_state_default_clear
drm_atomic_helper_page_flip and drm_atomic_ioctl set their own events in crtc_state->event. But when it's set the event is freed in 2 places. Solve this by only freeing the event in the atomic ioctl when it allocated its own event. This has been broken twice. The first time when the code was introduced, but only in the corner case when an event is allocated, but more crtc's were included by atomic check and then failing. This can mostly happen when you do an atomic modeset in i915 and the display clock is changed, which forces all crtc's to be included to the state. This has been broken worse by adding in-fences support, which caused the double free to be done unconditionally. [IGT] kms_rotation_crc: starting subtest primary-rotation-180 ============================================================================= BUG kmalloc-128 (Tainted: G U ): Object already free ----------------------------------------------------------------------------- Disabling lock debugging due to kernel taint INFO: Allocated in drm_atomic_helper_setup_commit+0x285/0x2f0 [drm_kms_helper] age=0 cpu=3 pid=1529 ___slab_alloc+0x308/0x3b0 __slab_alloc+0xd/0x20 kmem_cache_alloc_trace+0x92/0x1c0 drm_atomic_helper_setup_commit+0x285/0x2f0 [drm_kms_helper] intel_atomic_commit+0x35/0x4f0 [i915] drm_atomic_commit+0x46/0x50 [drm] drm_mode_atomic_ioctl+0x7d4/0xab0 [drm] drm_ioctl+0x2b3/0x490 [drm] do_vfs_ioctl+0x69c/0x700 SyS_ioctl+0x4e/0x80 entry_SYSCALL_64_fastpath+0x13/0x94 INFO: Freed in drm_event_cancel_free+0xa3/0xb0 [drm] age=0 cpu=3 pid=1529 __slab_free+0x48/0x2e0 kfree+0x159/0x1a0 drm_event_cancel_free+0xa3/0xb0 [drm] drm_mode_atomic_ioctl+0x86d/0xab0 [drm] drm_ioctl+0x2b3/0x490 [drm] do_vfs_ioctl+0x69c/0x700 SyS_ioctl+0x4e/0x80 entry_SYSCALL_64_fastpath+0x13/0x94 INFO: Slab 0xffffde1f0997b080 objects=17 used=2 fp=0xffff92fb65ec2578 flags=0x200000000008101 INFO: Object 0xffff92fb65ec2578 @offset=1400 fp=0xffff92fb65ec2ae8 Redzone ffff92fb65ec2570: bb bb bb bb bb bb bb bb ........ Object ffff92fb65ec2578: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object ffff92fb65ec2588: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object ffff92fb65ec2598: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object ffff92fb65ec25a8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object ffff92fb65ec25b8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object ffff92fb65ec25c8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object ffff92fb65ec25d8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object ffff92fb65ec25e8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5 kkkkkkkkkkkkkkk. Redzone ffff92fb65ec25f8: bb bb bb bb bb bb bb bb ........ Padding ffff92fb65ec2738: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ CPU: 3 PID: 180 Comm: kworker/3:2 Tainted: G BU 4.10.0-rc6-patser+ #5039 Hardware name: /NUC5PPYB, BIOS PYBSWCEL.86A.0031.2015.0601.1712 06/01/2015 Workqueue: events intel_atomic_helper_free_state [i915] Call Trace: dump_stack+0x4d/0x6d print_trailer+0x20c/0x220 free_debug_processing+0x1c6/0x330 ? drm_atomic_state_default_clear+0xf7/0x1c0 [drm] __slab_free+0x48/0x2e0 ? drm_atomic_state_default_clear+0xf7/0x1c0 [drm] kfree+0x159/0x1a0 drm_atomic_state_default_clear+0xf7/0x1c0 [drm] ? drm_atomic_state_clear+0x30/0x30 [drm] intel_atomic_state_clear+0xd/0x20 [i915] drm_atomic_state_clear+0x1a/0x30 [drm] __drm_atomic_state_free+0x13/0x60 [drm] intel_atomic_helper_free_state+0x5d/0x70 [i915] process_one_work+0x260/0x4a0 worker_thread+0x2d1/0x4f0 kthread+0x127/0x130 ? process_one_work+0x4a0/0x4a0 ? kthread_stop+0x120/0x120 ret_from_fork+0x29/0x40 FIX kmalloc-128: Object at 0xffff92fb65ec2578 not freed Fixes: 3b24f7d67581 ("drm/atomic: Add struct drm_crtc_commit to track async updates") Fixes: 9626014258a5 ("drm/fence: add in-fences support") Cc: <stable@vger.kernel.org> # v4.8+ Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1485854725-27640-1-git-send-email-maarten.lankhorst@linux.intel.com
Diffstat (limited to 'net/lapb/lapb_in.c')