From: Greg Kroah-Hartman Date: Mon, 27 Dec 2021 14:58:11 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v4.4.297~2 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=4ea3edcdc994dda903c2ce5201678bacfc7777b2;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: ax25-npd-bug-when-detaching-ax25-device.patch hamradio-defer-ax25-kfree-after-unregister_netdev.patch hamradio-improve-the-incomplete-fix-to-avoid-npd.patch hwmom-lm90-fix-citical-alarm-status-for-max6680-max6681.patch hwmon-lm90-do-not-report-busy-status-bit-as-alarm.patch phonet-pep-refuse-to-enable-an-unbound-pipe.patch pinctrl-mediatek-fix-global-out-of-bounds-issue.patch r8152-sync-ocp-base.patch tun-avoid-double-free-in-tun_free_netdev.patch --- diff --git a/queue-5.15/ax25-npd-bug-when-detaching-ax25-device.patch b/queue-5.15/ax25-npd-bug-when-detaching-ax25-device.patch new file mode 100644 index 00000000000..94c2c41a253 --- /dev/null +++ b/queue-5.15/ax25-npd-bug-when-detaching-ax25-device.patch @@ -0,0 +1,58 @@ +From 1ade48d0c27d5da1ccf4b583d8c5fc8b534a3ac8 Mon Sep 17 00:00:00 2001 +From: Lin Ma +Date: Fri, 17 Dec 2021 10:29:41 +0800 +Subject: ax25: NPD bug when detaching AX25 device + +From: Lin Ma + +commit 1ade48d0c27d5da1ccf4b583d8c5fc8b534a3ac8 upstream. + +The existing cleanup routine implementation is not well synchronized +with the syscall routine. When a device is detaching, below race could +occur. + +static int ax25_sendmsg(...) { + ... + lock_sock() + ax25 = sk_to_ax25(sk); + if (ax25->ax25_dev == NULL) // CHECK + ... + ax25_queue_xmit(skb, ax25->ax25_dev->dev); // USE + ... +} + +static void ax25_kill_by_device(...) { + ... + if (s->ax25_dev == ax25_dev) { + s->ax25_dev = NULL; + ... +} + +Other syscall functions like ax25_getsockopt, ax25_getname, +ax25_info_show also suffer from similar races. To fix them, this patch +introduce lock_sock() into ax25_kill_by_device in order to guarantee +that the nullify action in cleanup routine cannot proceed when another +socket request is pending. + +Signed-off-by: Hanjie Wu +Signed-off-by: Lin Ma +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ax25/af_ax25.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -85,8 +85,10 @@ static void ax25_kill_by_device(struct n + again: + ax25_for_each(s, &ax25_list) { + if (s->ax25_dev == ax25_dev) { +- s->ax25_dev = NULL; + spin_unlock_bh(&ax25_list_lock); ++ lock_sock(s->sk); ++ s->ax25_dev = NULL; ++ release_sock(s->sk); + ax25_disconnect(s, ENETUNREACH); + spin_lock_bh(&ax25_list_lock); + diff --git a/queue-5.15/hamradio-defer-ax25-kfree-after-unregister_netdev.patch b/queue-5.15/hamradio-defer-ax25-kfree-after-unregister_netdev.patch new file mode 100644 index 00000000000..cc81ac91023 --- /dev/null +++ b/queue-5.15/hamradio-defer-ax25-kfree-after-unregister_netdev.patch @@ -0,0 +1,66 @@ +From 3e0588c291d6ce225f2b891753ca41d45ba42469 Mon Sep 17 00:00:00 2001 +From: Lin Ma +Date: Mon, 8 Nov 2021 18:37:21 +0800 +Subject: hamradio: defer ax25 kfree after unregister_netdev + +From: Lin Ma + +commit 3e0588c291d6ce225f2b891753ca41d45ba42469 upstream. + +There is a possible race condition (use-after-free) like below + + (USE) | (FREE) +ax25_sendmsg | + ax25_queue_xmit | + dev_queue_xmit | + __dev_queue_xmit | + __dev_xmit_skb | + sch_direct_xmit | ... + xmit_one | + netdev_start_xmit | tty_ldisc_kill + __netdev_start_xmit | mkiss_close + ax_xmit | kfree + ax_encaps | + | + +Even though there are two synchronization primitives before the kfree: +1. wait_for_completion(&ax->dead). This can prevent the race with +routines from mkiss_ioctl. However, it cannot stop the routine coming +from upper layer, i.e., the ax25_sendmsg. + +2. netif_stop_queue(ax->dev). It seems that this line of code aims to +halt the transmit queue but it fails to stop the routine that already +being xmit. + +This patch reorder the kfree after the unregister_netdev to avoid the +possible UAF as the unregister_netdev() is well synchronized and won't +return if there is a running routine. + +Signed-off-by: Lin Ma +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/hamradio/mkiss.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/net/hamradio/mkiss.c ++++ b/drivers/net/hamradio/mkiss.c +@@ -792,13 +792,14 @@ static void mkiss_close(struct tty_struc + */ + netif_stop_queue(ax->dev); + +- /* Free all AX25 frame buffers. */ +- kfree(ax->rbuff); +- kfree(ax->xbuff); +- + ax->tty = NULL; + + unregister_netdev(ax->dev); ++ ++ /* Free all AX25 frame buffers after unreg. */ ++ kfree(ax->rbuff); ++ kfree(ax->xbuff); ++ + free_netdev(ax->dev); + } + diff --git a/queue-5.15/hamradio-improve-the-incomplete-fix-to-avoid-npd.patch b/queue-5.15/hamradio-improve-the-incomplete-fix-to-avoid-npd.patch new file mode 100644 index 00000000000..17bb08a60ab --- /dev/null +++ b/queue-5.15/hamradio-improve-the-incomplete-fix-to-avoid-npd.patch @@ -0,0 +1,74 @@ +From b2f37aead1b82a770c48b5d583f35ec22aabb61e Mon Sep 17 00:00:00 2001 +From: Lin Ma +Date: Fri, 17 Dec 2021 10:13:56 +0800 +Subject: hamradio: improve the incomplete fix to avoid NPD + +From: Lin Ma + +commit b2f37aead1b82a770c48b5d583f35ec22aabb61e upstream. + +The previous commit 3e0588c291d6 ("hamradio: defer ax25 kfree after +unregister_netdev") reorder the kfree operations and unregister_netdev +operation to prevent UAF. + +This commit improves the previous one by also deferring the nullify of +the ax->tty pointer. Otherwise, a NULL pointer dereference bug occurs. +Partial of the stack trace is shown below. + +BUG: kernel NULL pointer dereference, address: 0000000000000538 +RIP: 0010:ax_xmit+0x1f9/0x400 +... +Call Trace: + dev_hard_start_xmit+0xec/0x320 + sch_direct_xmit+0xea/0x240 + __qdisc_run+0x166/0x5c0 + __dev_queue_xmit+0x2c7/0xaf0 + ax25_std_establish_data_link+0x59/0x60 + ax25_connect+0x3a0/0x500 + ? security_socket_connect+0x2b/0x40 + __sys_connect+0x96/0xc0 + ? __hrtimer_init+0xc0/0xc0 + ? common_nsleep+0x2e/0x50 + ? switch_fpu_return+0x139/0x1a0 + __x64_sys_connect+0x11/0x20 + do_syscall_64+0x33/0x40 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +The crash point is shown as below + +static void ax_encaps(...) { + ... + set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); // ax->tty = NULL! + ... +} + +By placing the nullify action after the unregister_netdev, the ax->tty +pointer won't be assigned as NULL net_device framework layer is well +synchronized. + +Signed-off-by: Lin Ma +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/hamradio/mkiss.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/hamradio/mkiss.c ++++ b/drivers/net/hamradio/mkiss.c +@@ -792,14 +792,14 @@ static void mkiss_close(struct tty_struc + */ + netif_stop_queue(ax->dev); + +- ax->tty = NULL; +- + unregister_netdev(ax->dev); + + /* Free all AX25 frame buffers after unreg. */ + kfree(ax->rbuff); + kfree(ax->xbuff); + ++ ax->tty = NULL; ++ + free_netdev(ax->dev); + } + diff --git a/queue-5.15/hwmom-lm90-fix-citical-alarm-status-for-max6680-max6681.patch b/queue-5.15/hwmom-lm90-fix-citical-alarm-status-for-max6680-max6681.patch new file mode 100644 index 00000000000..a678e61bd8e --- /dev/null +++ b/queue-5.15/hwmom-lm90-fix-citical-alarm-status-for-max6680-max6681.patch @@ -0,0 +1,59 @@ +From da7dc0568491104c7acb632e9d41ddce9aaabbb1 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Fri, 26 Nov 2021 22:43:39 -0800 +Subject: hwmom: (lm90) Fix citical alarm status for MAX6680/MAX6681 + +From: Guenter Roeck + +commit da7dc0568491104c7acb632e9d41ddce9aaabbb1 upstream. + +Tests with a real chip and a closer look into the datasheet reveals +that the local and remote critical alarm status bits are swapped for +MAX6680/MAX6681. + +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/lm90.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/hwmon/lm90.c ++++ b/drivers/hwmon/lm90.c +@@ -190,6 +190,7 @@ enum chips { lm90, adm1032, lm99, lm86, + #define LM90_HAVE_EXTENDED_TEMP (1 << 8) /* extended temperature support*/ + #define LM90_PAUSE_FOR_CONFIG (1 << 9) /* Pause conversion for config */ + #define LM90_HAVE_CRIT (1 << 10)/* Chip supports CRIT/OVERT register */ ++#define LM90_HAVE_CRIT_ALRM_SWP (1 << 11)/* critical alarm bits swapped */ + + /* LM90 status */ + #define LM90_STATUS_LTHRM (1 << 0) /* local THERM limit tripped */ +@@ -415,7 +416,8 @@ static const struct lm90_params lm90_par + .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, + }, + [max6680] = { +- .flags = LM90_HAVE_OFFSET | LM90_HAVE_CRIT, ++ .flags = LM90_HAVE_OFFSET | LM90_HAVE_CRIT ++ | LM90_HAVE_CRIT_ALRM_SWP, + .alert_alarms = 0x7c, + .max_convrate = 7, + }, +@@ -1201,6 +1203,7 @@ static const u8 lm90_temp_emerg_index[3] + static const u8 lm90_min_alarm_bits[3] = { 5, 3, 11 }; + static const u8 lm90_max_alarm_bits[3] = { 6, 4, 12 }; + static const u8 lm90_crit_alarm_bits[3] = { 0, 1, 9 }; ++static const u8 lm90_crit_alarm_bits_swapped[3] = { 1, 0, 9 }; + static const u8 lm90_emergency_alarm_bits[3] = { 15, 13, 14 }; + static const u8 lm90_fault_bits[3] = { 0, 2, 10 }; + +@@ -1226,7 +1229,10 @@ static int lm90_temp_read(struct device + *val = (data->alarms >> lm90_max_alarm_bits[channel]) & 1; + break; + case hwmon_temp_crit_alarm: +- *val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1; ++ if (data->flags & LM90_HAVE_CRIT_ALRM_SWP) ++ *val = (data->alarms >> lm90_crit_alarm_bits_swapped[channel]) & 1; ++ else ++ *val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1; + break; + case hwmon_temp_emergency_alarm: + *val = (data->alarms >> lm90_emergency_alarm_bits[channel]) & 1; diff --git a/queue-5.15/hwmon-lm90-do-not-report-busy-status-bit-as-alarm.patch b/queue-5.15/hwmon-lm90-do-not-report-busy-status-bit-as-alarm.patch new file mode 100644 index 00000000000..6bdbb19a1c1 --- /dev/null +++ b/queue-5.15/hwmon-lm90-do-not-report-busy-status-bit-as-alarm.patch @@ -0,0 +1,38 @@ +From cdc5287acad9ede121924a9c9313544b80d15842 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Fri, 3 Dec 2021 13:42:22 -0800 +Subject: hwmon: (lm90) Do not report 'busy' status bit as alarm + +From: Guenter Roeck + +commit cdc5287acad9ede121924a9c9313544b80d15842 upstream. + +Bit 7 of the status register indicates that the chip is busy +doing a conversion. It does not indicate an alarm status. +Stop reporting it as alarm status bit. + +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/lm90.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/hwmon/lm90.c ++++ b/drivers/hwmon/lm90.c +@@ -200,6 +200,7 @@ enum chips { lm90, adm1032, lm99, lm86, + #define LM90_STATUS_RHIGH (1 << 4) /* remote high temp limit tripped */ + #define LM90_STATUS_LLOW (1 << 5) /* local low temp limit tripped */ + #define LM90_STATUS_LHIGH (1 << 6) /* local high temp limit tripped */ ++#define LM90_STATUS_BUSY (1 << 7) /* conversion is ongoing */ + + #define MAX6696_STATUS2_R2THRM (1 << 1) /* remote2 THERM limit tripped */ + #define MAX6696_STATUS2_R2OPEN (1 << 2) /* remote2 is an open circuit */ +@@ -820,7 +821,7 @@ static int lm90_update_device(struct dev + val = lm90_read_reg(client, LM90_REG_R_STATUS); + if (val < 0) + return val; +- data->alarms = val; /* lower 8 bit of alarms */ ++ data->alarms = val & ~LM90_STATUS_BUSY; + + if (data->kind == max6696) { + val = lm90_select_remote_channel(data, 1); diff --git a/queue-5.15/phonet-pep-refuse-to-enable-an-unbound-pipe.patch b/queue-5.15/phonet-pep-refuse-to-enable-an-unbound-pipe.patch new file mode 100644 index 00000000000..794b3e5c5f1 --- /dev/null +++ b/queue-5.15/phonet-pep-refuse-to-enable-an-unbound-pipe.patch @@ -0,0 +1,39 @@ +From 75a2f31520095600f650597c0ac41f48b5ba0068 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= +Date: Sun, 19 Dec 2021 19:03:39 +0200 +Subject: phonet/pep: refuse to enable an unbound pipe +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rémi Denis-Courmont + +commit 75a2f31520095600f650597c0ac41f48b5ba0068 upstream. + +This ioctl() implicitly assumed that the socket was already bound to +a valid local socket name, i.e. Phonet object. If the socket was not +bound, two separate problems would occur: + +1) We'd send an pipe enablement request with an invalid source object. +2) Later socket calls could BUG on the socket unexpectedly being + connected yet not bound to a valid object. + +Reported-by: syzbot+2dc91e7fc3dea88b1e8a@syzkaller.appspotmail.com +Signed-off-by: Rémi Denis-Courmont +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/phonet/pep.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/phonet/pep.c ++++ b/net/phonet/pep.c +@@ -946,6 +946,8 @@ static int pep_ioctl(struct sock *sk, in + ret = -EBUSY; + else if (sk->sk_state == TCP_ESTABLISHED) + ret = -EISCONN; ++ else if (!pn->pn_sk.sobject) ++ ret = -EADDRNOTAVAIL; + else + ret = pep_sock_enable(sk, NULL, 0); + release_sock(sk); diff --git a/queue-5.15/pinctrl-mediatek-fix-global-out-of-bounds-issue.patch b/queue-5.15/pinctrl-mediatek-fix-global-out-of-bounds-issue.patch new file mode 100644 index 00000000000..6c302803e78 --- /dev/null +++ b/queue-5.15/pinctrl-mediatek-fix-global-out-of-bounds-issue.patch @@ -0,0 +1,39 @@ +From 2d5446da5acecf9c67db1c9d55ae2c3e5de01f8d Mon Sep 17 00:00:00 2001 +From: Guodong Liu +Date: Wed, 10 Nov 2021 15:19:00 +0800 +Subject: pinctrl: mediatek: fix global-out-of-bounds issue + +From: Guodong Liu + +commit 2d5446da5acecf9c67db1c9d55ae2c3e5de01f8d upstream. + +When eint virtual eint number is greater than gpio number, +it maybe produce 'desc[eint_n]' size globle-out-of-bounds issue. + +Signed-off-by: Guodong Liu +Signed-off-by: Zhiyong Tao +Reviewed-by: Chen-Yu Tsai +Link: https://lore.kernel.org/r/20211110071900.4490-2-zhiyong.tao@mediatek.com +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c ++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +@@ -285,8 +285,12 @@ static int mtk_xt_get_gpio_n(void *data, + desc = (const struct mtk_pin_desc *)hw->soc->pins; + *gpio_chip = &hw->chip; + +- /* Be greedy to guess first gpio_n is equal to eint_n */ +- if (desc[eint_n].eint.eint_n == eint_n) ++ /* ++ * Be greedy to guess first gpio_n is equal to eint_n. ++ * Only eint virtual eint number is greater than gpio number. ++ */ ++ if (hw->soc->npins > eint_n && ++ desc[eint_n].eint.eint_n == eint_n) + *gpio_n = eint_n; + else + *gpio_n = mtk_xt_find_eint_num(hw, eint_n); diff --git a/queue-5.15/r8152-sync-ocp-base.patch b/queue-5.15/r8152-sync-ocp-base.patch new file mode 100644 index 00000000000..bbed7c0e1b5 --- /dev/null +++ b/queue-5.15/r8152-sync-ocp-base.patch @@ -0,0 +1,135 @@ +From b24edca309535c2d9af86aab95d64065f6ef1d26 Mon Sep 17 00:00:00 2001 +From: Hayes Wang +Date: Thu, 23 Dec 2021 17:27:02 +0800 +Subject: r8152: sync ocp base + +From: Hayes Wang + +commit b24edca309535c2d9af86aab95d64065f6ef1d26 upstream. + +There are some chances that the actual base of hardware is different +from the value recorded by driver, so we have to reset the variable +of ocp_base to sync it. + +Set ocp_base to -1. Then, it would be updated and the new base would be +set to the hardware next time. + +Signed-off-by: Hayes Wang +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/r8152.c | 26 ++++++++++++++++++++++---- + 1 file changed, 22 insertions(+), 4 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -32,7 +32,7 @@ + #define NETNEXT_VERSION "12" + + /* Information for net */ +-#define NET_VERSION "11" ++#define NET_VERSION "12" + + #define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION + #define DRIVER_AUTHOR "Realtek linux nic maintainers " +@@ -4016,6 +4016,11 @@ static void rtl_clear_bp(struct r8152 *t + ocp_write_word(tp, type, PLA_BP_BA, 0); + } + ++static inline void rtl_reset_ocp_base(struct r8152 *tp) ++{ ++ tp->ocp_base = -1; ++} ++ + static int rtl_phy_patch_request(struct r8152 *tp, bool request, bool wait) + { + u16 data, check; +@@ -4087,8 +4092,6 @@ static int rtl_post_ram_code(struct r815 + + rtl_phy_patch_request(tp, false, wait); + +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base); +- + return 0; + } + +@@ -4800,6 +4803,8 @@ static void rtl_ram_code_speed_up(struct + u32 len; + u8 *data; + ++ rtl_reset_ocp_base(tp); ++ + if (sram_read(tp, SRAM_GPHY_FW_VER) >= __le16_to_cpu(phy->version)) { + dev_dbg(&tp->intf->dev, "PHY firmware has been the newest\n"); + return; +@@ -4845,7 +4850,8 @@ static void rtl_ram_code_speed_up(struct + } + } + +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base); ++ rtl_reset_ocp_base(tp); ++ + rtl_phy_patch_request(tp, false, wait); + + if (sram_read(tp, SRAM_GPHY_FW_VER) == __le16_to_cpu(phy->version)) +@@ -4861,6 +4867,8 @@ static int rtl8152_fw_phy_ver(struct r81 + ver_addr = __le16_to_cpu(phy_ver->ver.addr); + ver = __le16_to_cpu(phy_ver->ver.data); + ++ rtl_reset_ocp_base(tp); ++ + if (sram_read(tp, ver_addr) >= ver) { + dev_dbg(&tp->intf->dev, "PHY firmware has been the newest\n"); + return 0; +@@ -4877,6 +4885,8 @@ static void rtl8152_fw_phy_fixup(struct + { + u16 addr, data; + ++ rtl_reset_ocp_base(tp); ++ + addr = __le16_to_cpu(fix->setting.addr); + data = ocp_reg_read(tp, addr); + +@@ -4908,6 +4918,8 @@ static void rtl8152_fw_phy_union_apply(s + u32 length; + int i, num; + ++ rtl_reset_ocp_base(tp); ++ + num = phy->pre_num; + for (i = 0; i < num; i++) + sram_write(tp, __le16_to_cpu(phy->pre_set[i].addr), +@@ -4938,6 +4950,8 @@ static void rtl8152_fw_phy_nc_apply(stru + u32 length, i, num; + __le16 *data; + ++ rtl_reset_ocp_base(tp); ++ + mode_reg = __le16_to_cpu(phy->mode_reg); + sram_write(tp, mode_reg, __le16_to_cpu(phy->mode_pre)); + sram_write(tp, __le16_to_cpu(phy->ba_reg), +@@ -5107,6 +5121,7 @@ post_fw: + if (rtl_fw->post_fw) + rtl_fw->post_fw(tp); + ++ rtl_reset_ocp_base(tp); + strscpy(rtl_fw->version, fw_hdr->version, RTL_VER_SIZE); + dev_info(&tp->intf->dev, "load %s successfully\n", rtl_fw->version); + } +@@ -8484,6 +8499,8 @@ static int rtl8152_resume(struct usb_int + + mutex_lock(&tp->control); + ++ rtl_reset_ocp_base(tp); ++ + if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) + ret = rtl8152_runtime_resume(tp); + else +@@ -8499,6 +8516,7 @@ static int rtl8152_reset_resume(struct u + struct r8152 *tp = usb_get_intfdata(intf); + + clear_bit(SELECTIVE_SUSPEND, &tp->flags); ++ rtl_reset_ocp_base(tp); + tp->rtl_ops.init(tp); + queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); + set_ethernet_addr(tp, true); diff --git a/queue-5.15/series b/queue-5.15/series index 43f4a0884bc..8042d304472 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -117,3 +117,12 @@ asoc-tas2770-fix-setting-of-high-sample-rates.patch asoc-sof-intel-pci-tgl-add-new-adl-p-variant.patch asoc-sof-intel-pci-tgl-add-adl-n-support.patch asoc-rt5682-fix-the-wrong-jack-type-detected.patch +pinctrl-mediatek-fix-global-out-of-bounds-issue.patch +hwmom-lm90-fix-citical-alarm-status-for-max6680-max6681.patch +hwmon-lm90-do-not-report-busy-status-bit-as-alarm.patch +r8152-sync-ocp-base.patch +ax25-npd-bug-when-detaching-ax25-device.patch +hamradio-defer-ax25-kfree-after-unregister_netdev.patch +hamradio-improve-the-incomplete-fix-to-avoid-npd.patch +tun-avoid-double-free-in-tun_free_netdev.patch +phonet-pep-refuse-to-enable-an-unbound-pipe.patch diff --git a/queue-5.15/tun-avoid-double-free-in-tun_free_netdev.patch b/queue-5.15/tun-avoid-double-free-in-tun_free_netdev.patch new file mode 100644 index 00000000000..7305aca8d2c --- /dev/null +++ b/queue-5.15/tun-avoid-double-free-in-tun_free_netdev.patch @@ -0,0 +1,241 @@ +From 158b515f703e75e7d68289bf4d98c664e1d632df Mon Sep 17 00:00:00 2001 +From: George Kennedy +Date: Thu, 16 Dec 2021 13:25:32 -0500 +Subject: tun: avoid double free in tun_free_netdev + +From: George Kennedy + +commit 158b515f703e75e7d68289bf4d98c664e1d632df upstream. + +Avoid double free in tun_free_netdev() by moving the +dev->tstats and tun->security allocs to a new ndo_init routine +(tun_net_init()) that will be called by register_netdevice(). +ndo_init is paired with the desctructor (tun_free_netdev()), +so if there's an error in register_netdevice() the destructor +will handle the frees. + +BUG: KASAN: double-free or invalid-free in selinux_tun_dev_free_security+0x1a/0x20 security/selinux/hooks.c:5605 + +CPU: 0 PID: 25750 Comm: syz-executor416 Not tainted 5.16.0-rc2-syzk #1 +Hardware name: Red Hat KVM, BIOS +Call Trace: + +__dump_stack lib/dump_stack.c:88 [inline] +dump_stack_lvl+0x89/0xb5 lib/dump_stack.c:106 +print_address_description.constprop.9+0x28/0x160 mm/kasan/report.c:247 +kasan_report_invalid_free+0x55/0x80 mm/kasan/report.c:372 +____kasan_slab_free mm/kasan/common.c:346 [inline] +__kasan_slab_free+0x107/0x120 mm/kasan/common.c:374 +kasan_slab_free include/linux/kasan.h:235 [inline] +slab_free_hook mm/slub.c:1723 [inline] +slab_free_freelist_hook mm/slub.c:1749 [inline] +slab_free mm/slub.c:3513 [inline] +kfree+0xac/0x2d0 mm/slub.c:4561 +selinux_tun_dev_free_security+0x1a/0x20 security/selinux/hooks.c:5605 +security_tun_dev_free_security+0x4f/0x90 security/security.c:2342 +tun_free_netdev+0xe6/0x150 drivers/net/tun.c:2215 +netdev_run_todo+0x4df/0x840 net/core/dev.c:10627 +rtnl_unlock+0x13/0x20 net/core/rtnetlink.c:112 +__tun_chr_ioctl+0x80c/0x2870 drivers/net/tun.c:3302 +tun_chr_ioctl+0x2f/0x40 drivers/net/tun.c:3311 +vfs_ioctl fs/ioctl.c:51 [inline] +__do_sys_ioctl fs/ioctl.c:874 [inline] +__se_sys_ioctl fs/ioctl.c:860 [inline] +__x64_sys_ioctl+0x19d/0x220 fs/ioctl.c:860 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x3a/0x80 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x44/0xae + +Reported-by: syzkaller +Signed-off-by: George Kennedy +Suggested-by: Jakub Kicinski +Link: https://lore.kernel.org/r/1639679132-19884-1-git-send-email-george.kennedy@oracle.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tun.c | 115 +++++++++++++++++++++++++++--------------------------- + 1 file changed, 59 insertions(+), 56 deletions(-) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -209,6 +209,9 @@ struct tun_struct { + struct tun_prog __rcu *steering_prog; + struct tun_prog __rcu *filter_prog; + struct ethtool_link_ksettings link_ksettings; ++ /* init args */ ++ struct file *file; ++ struct ifreq *ifr; + }; + + struct veth { +@@ -216,6 +219,9 @@ struct veth { + __be16 h_vlan_TCI; + }; + ++static void tun_flow_init(struct tun_struct *tun); ++static void tun_flow_uninit(struct tun_struct *tun); ++ + static int tun_napi_receive(struct napi_struct *napi, int budget) + { + struct tun_file *tfile = container_of(napi, struct tun_file, napi); +@@ -953,6 +959,49 @@ static int check_filter(struct tap_filte + + static const struct ethtool_ops tun_ethtool_ops; + ++static int tun_net_init(struct net_device *dev) ++{ ++ struct tun_struct *tun = netdev_priv(dev); ++ struct ifreq *ifr = tun->ifr; ++ int err; ++ ++ dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); ++ if (!dev->tstats) ++ return -ENOMEM; ++ ++ spin_lock_init(&tun->lock); ++ ++ err = security_tun_dev_alloc_security(&tun->security); ++ if (err < 0) { ++ free_percpu(dev->tstats); ++ return err; ++ } ++ ++ tun_flow_init(tun); ++ ++ dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | ++ TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | ++ NETIF_F_HW_VLAN_STAG_TX; ++ dev->features = dev->hw_features | NETIF_F_LLTX; ++ dev->vlan_features = dev->features & ++ ~(NETIF_F_HW_VLAN_CTAG_TX | ++ NETIF_F_HW_VLAN_STAG_TX); ++ ++ tun->flags = (tun->flags & ~TUN_FEATURES) | ++ (ifr->ifr_flags & TUN_FEATURES); ++ ++ INIT_LIST_HEAD(&tun->disabled); ++ err = tun_attach(tun, tun->file, false, ifr->ifr_flags & IFF_NAPI, ++ ifr->ifr_flags & IFF_NAPI_FRAGS, false); ++ if (err < 0) { ++ tun_flow_uninit(tun); ++ security_tun_dev_free_security(tun->security); ++ free_percpu(dev->tstats); ++ return err; ++ } ++ return 0; ++} ++ + /* Net device detach from fd. */ + static void tun_net_uninit(struct net_device *dev) + { +@@ -1169,6 +1218,7 @@ static int tun_net_change_carrier(struct + } + + static const struct net_device_ops tun_netdev_ops = { ++ .ndo_init = tun_net_init, + .ndo_uninit = tun_net_uninit, + .ndo_open = tun_net_open, + .ndo_stop = tun_net_close, +@@ -1252,6 +1302,7 @@ static int tun_xdp_tx(struct net_device + } + + static const struct net_device_ops tap_netdev_ops = { ++ .ndo_init = tun_net_init, + .ndo_uninit = tun_net_uninit, + .ndo_open = tun_net_open, + .ndo_stop = tun_net_close, +@@ -1292,7 +1343,7 @@ static void tun_flow_uninit(struct tun_s + #define MAX_MTU 65535 + + /* Initialize net device. */ +-static void tun_net_init(struct net_device *dev) ++static void tun_net_initialize(struct net_device *dev) + { + struct tun_struct *tun = netdev_priv(dev); + +@@ -2206,11 +2257,6 @@ static void tun_free_netdev(struct net_d + BUG_ON(!(list_empty(&tun->disabled))); + + free_percpu(dev->tstats); +- /* We clear tstats so that tun_set_iff() can tell if +- * tun_free_netdev() has been called from register_netdevice(). +- */ +- dev->tstats = NULL; +- + tun_flow_uninit(tun); + security_tun_dev_free_security(tun->security); + __tun_set_ebpf(tun, &tun->steering_prog, NULL); +@@ -2716,41 +2762,16 @@ static int tun_set_iff(struct net *net, + tun->rx_batched = 0; + RCU_INIT_POINTER(tun->steering_prog, NULL); + +- dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); +- if (!dev->tstats) { +- err = -ENOMEM; +- goto err_free_dev; +- } +- +- spin_lock_init(&tun->lock); +- +- err = security_tun_dev_alloc_security(&tun->security); +- if (err < 0) +- goto err_free_stat; +- +- tun_net_init(dev); +- tun_flow_init(tun); +- +- dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | +- TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | +- NETIF_F_HW_VLAN_STAG_TX; +- dev->features = dev->hw_features | NETIF_F_LLTX; +- dev->vlan_features = dev->features & +- ~(NETIF_F_HW_VLAN_CTAG_TX | +- NETIF_F_HW_VLAN_STAG_TX); +- +- tun->flags = (tun->flags & ~TUN_FEATURES) | +- (ifr->ifr_flags & TUN_FEATURES); ++ tun->ifr = ifr; ++ tun->file = file; + +- INIT_LIST_HEAD(&tun->disabled); +- err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI, +- ifr->ifr_flags & IFF_NAPI_FRAGS, false); +- if (err < 0) +- goto err_free_flow; ++ tun_net_initialize(dev); + + err = register_netdevice(tun->dev); +- if (err < 0) +- goto err_detach; ++ if (err < 0) { ++ free_netdev(dev); ++ return err; ++ } + /* free_netdev() won't check refcnt, to avoid race + * with dev_put() we need publish tun after registration. + */ +@@ -2767,24 +2788,6 @@ static int tun_set_iff(struct net *net, + + strcpy(ifr->ifr_name, tun->dev->name); + return 0; +- +-err_detach: +- tun_detach_all(dev); +- /* We are here because register_netdevice() has failed. +- * If register_netdevice() already called tun_free_netdev() +- * while dealing with the error, dev->stats has been cleared. +- */ +- if (!dev->tstats) +- goto err_free_dev; +- +-err_free_flow: +- tun_flow_uninit(tun); +- security_tun_dev_free_security(tun->security); +-err_free_stat: +- free_percpu(dev->tstats); +-err_free_dev: +- free_netdev(dev); +- return err; + } + + static void tun_get_iff(struct tun_struct *tun, struct ifreq *ifr)