diff --git a/SOURCES/CVE-2022-4744.patch b/SOURCES/CVE-2022-4744.patch new file mode 100644 index 0000000..13bee3a --- /dev/null +++ b/SOURCES/CVE-2022-4744.patch @@ -0,0 +1,349 @@ +From 951ae7dd395dd1407cfc6d7f2f59163850ec0362 Mon Sep 17 00:00:00 2001 +From: Yannick Cote +Date: Tue, 14 Mar 2023 21:40:48 -0400 +Subject: [KPATCH CVE-2022-4744] kpatch fixes for CVE-2022-4744 + +Kernels: +5.14.0-162.6.1.el9_1 +5.14.0-162.12.1.el9_1 +5.14.0-162.18.1.el9_1 + + +Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-9/-/merge_requests/28 +Approved-by: Joe Lawrence (@joe.lawrence) +Changes since last build: +[x86_64]: +control.o: changed function: snd_ctl_elem_read +control.o: changed function: snd_ctl_ioctl +dev.o: changed function: register_netdevice +tun.o: changed function: tun_free_netdev +tun.o: changed function: tun_set_iff.constprop.0 +tun.o: new function: kpp_cve_2022_4744_tun_net_init + +[ppc64le]: +dev.o: changed function: register_netdevice +tun.o: changed function: tun_free_netdev +tun.o: changed function: tun_set_iff.constprop.0 +tun.o: new function: kpp_cve_2022_4744_tun_net_init + +--------------------------- + +Modifications: +- add shadow variables for tun->ifr, tun->file, ndo_init +- call init from register_netdevice() when shadow variables are detected +- renamed new tun_net_init() -> kpp_cve_2022_4744_tun_net_init() +- code to allocate, maintain and remove shadow variables + +commit 8ab79b18abf2f3a2cf33903794ff0de7cec105fc +Author: Jon Maloy +Date: Wed Mar 8 11:35:45 2023 -0500 + + tun: avoid double free in tun_free_netdev + + Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2156372 + Upstream: Merged + CVE: CVE-2022-4744 + + commit 158b515f703e75e7d68289bf4d98c664e1d632df + Author: George Kennedy + Date: Thu Dec 16 13:25:32 2021 -0500 + + tun: avoid double free in tun_free_netdev + + 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: Jon Maloy + +Signed-off-by: Yannick Cote +--- + drivers/net/tun.c | 135 ++++++++++++++++++++++++++++------------------ + net/core/dev.c | 31 ++++++++++- + 2 files changed, 112 insertions(+), 54 deletions(-) + +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index a3aec566fb4b..2a2fee5e3c10 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -216,6 +216,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 +956,67 @@ static int check_filter(struct tap_filter *filter, const struct sk_buff *skb) + + static const struct ethtool_ops tun_ethtool_ops; + ++/* CVE-2022-4744 - kpatch gathered definitions */ ++#ifndef __GENKSYMS__ ++/* Note: avoid symvers churn for tun_get_tx_ring and tun_get_socket */ ++# include ++# define KLP_CVE_2022_4744 0x2022474400000001 ++struct klp_cve_2022_4774_t { ++ struct ifreq tun_ifr; ++ struct file tun_file; ++ int (*ndo_init)(struct net_device *netdev); ++}; ++#endif ++int kpp_cve_2022_4744_tun_net_init(struct net_device *dev) ++{ ++ struct tun_struct *tun = netdev_priv(dev); ++ int err; ++ struct klp_cve_2022_4774_t *klp_sv; ++ ++ klp_sv = klp_shadow_get(tun, KLP_CVE_2022_4744); ++ if (!klp_sv) ++ return -EINVAL; ++ ++ 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); ++ klp_sv = klp_shadow_get(tun, KLP_CVE_2022_4744); ++ if (klp_sv) { ++ tun->flags = (tun->flags & ~TUN_FEATURES) | ++ (klp_sv->tun_ifr.ifr_flags & TUN_FEATURES); ++ ++ INIT_LIST_HEAD(&tun->disabled); ++ err = tun_attach(tun, &klp_sv->tun_file, false, ++ klp_sv->tun_ifr.ifr_flags & IFF_NAPI, ++ klp_sv->tun_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) + { +@@ -2206,15 +2270,11 @@ static void tun_free_netdev(struct net_device *dev) + 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); + __tun_set_ebpf(tun, &tun->filter_prog, NULL); ++ klp_shadow_free(tun, KLP_CVE_2022_4744, NULL); + } + + static void tun_setup(struct net_device *dev) +@@ -2716,41 +2776,30 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) + 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; +- } ++/* kpatch */ ++{ ++ struct klp_cve_2022_4774_t *klp_sv; + +- spin_lock_init(&tun->lock); ++ klp_sv = klp_shadow_alloc(tun, KLP_CVE_2022_4744, ++ sizeof(*klp_sv), GFP_KERNEL, NULL, NULL); ++ if (!klp_sv) { ++ free_netdev(dev); ++ return -ENOMEM; ++ } + +- err = security_tun_dev_alloc_security(&tun->security); +- if (err < 0) +- goto err_free_stat; ++ memcpy(&klp_sv->tun_ifr, ifr, sizeof(*ifr)); ++ memcpy(&klp_sv->tun_file, file, sizeof(*file)); ++ klp_sv->ndo_init = kpp_cve_2022_4744_tun_net_init; ++} + + 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); +- +- 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; + + err = register_netdevice(tun->dev); +- if (err < 0) +- goto err_detach; ++ if (err < 0) { ++ klp_shadow_free(tun, KLP_CVE_2022_4744, NULL); ++ 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 +2816,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) + + 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) +diff --git a/net/core/dev.c b/net/core/dev.c +index 89ff6b1e7735..d5f07da178dc 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -9544,6 +9544,15 @@ EXPORT_SYMBOL(netif_tx_stop_all_queues); + * will not get the same name. + */ + ++/* CVE-2022-4744 - kpatch gathered definitions */ ++#include ++#define KLP_CVE_2022_4744 0x2022474400000001 ++struct klp_cve_2022_4774_t { ++ struct ifreq tun_ifr; ++ struct file tun_file; ++ int (*ndo_init)(struct net_device *netdev); ++}; ++ + int register_netdevice(struct net_device *dev) + { + int ret; +@@ -9576,15 +9585,33 @@ int register_netdevice(struct net_device *dev) + if (!dev->name_node) + goto out; + ++/* kpatch */ ++{ + /* Init, if this function is available */ +- if (dev->netdev_ops->ndo_init) { +- ret = dev->netdev_ops->ndo_init(dev); ++ struct klp_cve_2022_4774_t *klp_sv; ++ int (*ndo_init)(struct net_device *netdev) = NULL; ++ ++ /* Does device has shadow variable ndo_init? */ ++ if (netdev_priv(dev)) { ++ klp_sv = klp_shadow_get(netdev_priv(dev), KLP_CVE_2022_4744); ++ if (klp_sv && klp_sv->ndo_init) ++ ndo_init = klp_sv->ndo_init; ++ } ++ ++ /* How about typical netdev_ops->ndo_init */ ++ if (!ndo_init && dev->netdev_ops->ndo_init) ++ ndo_init = dev->netdev_ops->ndo_init; ++ ++ /* Run ndo_init callback if found */ ++ if (ndo_init) { ++ ret = ndo_init(dev); + if (ret) { + if (ret > 0) + ret = -EIO; + goto err_free_name; + } + } ++} + + if (((dev->hw_features | dev->features) & + NETIF_F_HW_VLAN_CTAG_FILTER) && +-- +2.39.2 + + diff --git a/SOURCES/CVE-2023-0266.patch b/SOURCES/CVE-2023-0266.patch new file mode 100644 index 0000000..3d6a0de --- /dev/null +++ b/SOURCES/CVE-2023-0266.patch @@ -0,0 +1,152 @@ +From 120548cde1d7642ff79d71827993e32babfb4e2f Mon Sep 17 00:00:00 2001 +From: Ryan Sullivan +Date: Fri, 17 Feb 2023 12:26:57 -0500 +Subject: [KPATCH CVE-2023-0266] kpatch fixes for CVE-2023-0266 + +Kernels: +5.14.0-162.6.1.el9_1 +5.14.0-162.12.1.el9_1 + + +Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-9/-/merge_requests/24 +Approved-by: Yannick Cote (@ycote1) +Approved-by: Joe Lawrence (@joe.lawrence) +Changes since last build: +[x86_64]: +control.o: changed function: snd_ctl_elem_read +control.o: changed function: snd_ctl_ioctl +dev.o: changed function: register_netdevice +tun.o: changed function: tun_free_netdev +tun.o: changed function: tun_set_iff.constprop.0 +tun.o: new function: kpp_cve_2022_4744_tun_net_init + +[ppc64le]: +dev.o: changed function: register_netdevice +tun.o: changed function: tun_free_netdev +tun.o: changed function: tun_set_iff.constprop.0 +tun.o: new function: kpp_cve_2022_4744_tun_net_init + +--------------------------- + +Modifications: none + +commit c0295d3bd6b49f47e30822a9de9c042020092424 +Author: Jaroslav Kysela +Date: Tue Jan 31 17:13:11 2023 +0100 + + ALSA: pcm: Move rwsem lock inside snd_ctl_elem_read to prevent UAF + + Takes rwsem lock inside snd_ctl_elem_read instead of snd_ctl_elem_read_user + like it was done for write in commit 1fa4445f9adf1 ("ALSA: control - introduce + snd_ctl_notify_one() helper"). Doing this way we are also fixing the following + locking issue happening in the compat path which can be easily triggered and + turned into an use-after-free. + + 64-bits: + snd_ctl_ioctl + snd_ctl_elem_read_user + [takes controls_rwsem] + snd_ctl_elem_read [lock properly held, all good] + [drops controls_rwsem] + + 32-bits: + snd_ctl_ioctl_compat + snd_ctl_elem_write_read_compat + ctl_elem_write_read + snd_ctl_elem_read [missing lock, not good] + + CVE-2023-0266 was assigned for this issue. + + Cc: stable@kernel.org # 5.13+ + Signed-off-by: Clement Lecigne + Reviewed-by: Jaroslav Kysela + Link: https://lore.kernel.org/r/20230113120745.25464-1-tiwai@suse.de + Signed-off-by: Takashi Iwai + + Author: Clement Lecigne + Date: Fri Jan 13 13:07:45 2023 +0100 + + CVE: CVE-2023-0266 + + Signed-off-by: Jaroslav Kysela + (cherry picked from commit 56b88b50565cd8b946a2d00b0c83927b7ebb055e) + Bugzilla: https://bugzilla.redhat.com/2163390 + +Signed-off-by: Ryan Sullivan +--- + sound/core/control.c | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +diff --git a/sound/core/control.c b/sound/core/control.c +index a25c0d64d104..6e2a1e424627 100644 +--- a/sound/core/control.c ++++ b/sound/core/control.c +@@ -1066,14 +1066,19 @@ static int snd_ctl_elem_read(struct snd_card *card, + const u32 pattern = 0xdeadbeef; + int ret; + ++ down_read(&card->controls_rwsem); + kctl = snd_ctl_find_id(card, &control->id); +- if (kctl == NULL) +- return -ENOENT; ++ if (kctl == NULL) { ++ ret = -ENOENT; ++ goto unlock; ++ } + + index_offset = snd_ctl_get_ioff(kctl, &control->id); + vd = &kctl->vd[index_offset]; +- if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) || kctl->get == NULL) +- return -EPERM; ++ if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) || kctl->get == NULL) { ++ ret = -EPERM; ++ goto unlock; ++ } + + snd_ctl_build_ioff(&control->id, kctl, index_offset); + +@@ -1083,7 +1088,7 @@ static int snd_ctl_elem_read(struct snd_card *card, + info.id = control->id; + ret = __snd_ctl_elem_info(card, kctl, &info, NULL); + if (ret < 0) +- return ret; ++ goto unlock; + #endif + + if (!snd_ctl_skip_validation(&info)) +@@ -1093,7 +1098,7 @@ static int snd_ctl_elem_read(struct snd_card *card, + ret = kctl->get(kctl, control); + snd_power_unref(card); + if (ret < 0) +- return ret; ++ goto unlock; + if (!snd_ctl_skip_validation(&info) && + sanity_check_elem_value(card, control, &info, pattern) < 0) { + dev_err(card->dev, +@@ -1101,8 +1106,11 @@ static int snd_ctl_elem_read(struct snd_card *card, + control->id.iface, control->id.device, + control->id.subdevice, control->id.name, + control->id.index); +- return -EINVAL; ++ ret = -EINVAL; ++ goto unlock; + } ++unlock: ++ up_read(&card->controls_rwsem); + return ret; + } + +@@ -1116,9 +1124,7 @@ static int snd_ctl_elem_read_user(struct snd_card *card, + if (IS_ERR(control)) + return PTR_ERR(control); + +- down_read(&card->controls_rwsem); + result = snd_ctl_elem_read(card, control); +- up_read(&card->controls_rwsem); + if (result < 0) + goto error; + +-- +2.39.2 + + diff --git a/SPECS/kpatch-patch.spec b/SPECS/kpatch-patch.spec index f30787d..ff47a14 100644 --- a/SPECS/kpatch-patch.spec +++ b/SPECS/kpatch-patch.spec @@ -6,7 +6,7 @@ %define kernel_ver 5.14.0-162.6.1.el9_1 %define kpatch_ver 0.9.7 %define rpm_ver 1 -%define rpm_rel 2 +%define rpm_rel 3 %if !%{empty_package} # Patch sources below. DO NOT REMOVE THIS LINE. @@ -34,6 +34,12 @@ Source106: CVE-2022-4379.patch # # https://bugzilla.redhat.com/2161747 Source107: CVE-2023-0179.patch +# +# https://bugzilla.redhat.com/2156383 +Source108: CVE-2022-4744.patch +# +# https://bugzilla.redhat.com/2163415 +Source109: CVE-2023-0266.patch # End of patch sources. DO NOT REMOVE THIS LINE. %endif @@ -211,6 +217,10 @@ It is only a method to subscribe to the kpatch stream for kernel-%{kernel_ver}. %endif %changelog +* Sat Mar 18 2023 Yannick Cote [1-3.el9_1] +- ALSA: pcm: Move rwsem lock inside snd_ctl_elem_read to prevent UAF [2163415] {CVE-2023-0266} +- EMBARGOED CVE-2022-4744 kernel: tun: avoid double free in tun_free_netdev [2156383] {CVE-2022-4744} + * Tue Feb 14 2023 Yannick Cote [1-2.el9_1] - kernel: Netfilter integer overflow vulnerability in nft_payload_copy_vlan [2161747] {CVE-2023-0179} - kernel: use-after-free in __nfs42_ssc_open() in fs/nfs/nfs4file.c leading to remote Denial of Service attack [2153157] {CVE-2022-4379}