diff options
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed')
20 files changed, 2014 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39685-1.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39685-1.patch new file mode 100644 index 000000000..5e963a989 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39685-1.patch @@ -0,0 +1,45 @@ +From 6eea4ace62fa6414432692ee44f0c0a3d541d97a Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Date: Thu, 9 Dec 2021 19:02:15 +0100 +Subject: [PATCH] USB: gadget: zero allocate endpoint 0 buffers + +commit 86ebbc11bb3f60908a51f3e41a17e3f477c2eaa3 upstream. + +Under some conditions, USB gadget devices can show allocated buffer +contents to a host. Fix this up by zero-allocating them so that any +extra data will all just be zeros. + +Reported-by: Szymon Heidrich <szymon.heidrich@gmail.com> +Tested-by: Szymon Heidrich <szymon.heidrich@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/usb/gadget/composite.c | 2 +- + drivers/usb/gadget/legacy/dbgp.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c +index 1ef7922b57b62e..284eea9f6e4d8d 100644 +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -2221,7 +2221,7 @@ int composite_dev_prepare(struct usb_composite_driver *composite, + if (!cdev->req) + return -ENOMEM; + +- cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL); ++ cdev->req->buf = kzalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL); + if (!cdev->req->buf) + goto fail; + +diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c +index e567afcb2794c0..355bc7dab9d5f6 100644 +--- a/drivers/usb/gadget/legacy/dbgp.c ++++ b/drivers/usb/gadget/legacy/dbgp.c +@@ -137,7 +137,7 @@ static int dbgp_enable_ep_req(struct usb_ep *ep) + goto fail_1; + } + +- req->buf = kmalloc(DBGP_REQ_LEN, GFP_KERNEL); ++ req->buf = kzalloc(DBGP_REQ_LEN, GFP_KERNEL); + if (!req->buf) { + err = -ENOMEM; + stp = 2; diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39685-2.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39685-2.patch new file mode 100644 index 000000000..44337588a --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39685-2.patch @@ -0,0 +1,93 @@ +From abd3a33b3f2bff26fa531da668b041bef980f238 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Date: Tue, 14 Dec 2021 19:46:21 +0100 +Subject: [PATCH] USB: gadget: bRequestType is a bitfield, not a enum + +[ Upstream commit f08adf5add9a071160c68bb2a61d697f39ab0758 ] + +Szymon rightly pointed out that the previous check for the endpoint +direction in bRequestType was not looking at only the bit involved, but +rather the whole value. Normally this is ok, but for some request +types, bits other than bit 8 could be set and the check for the endpoint +length could not stall correctly. + +Fix that up by only checking the single bit. + +Fixes: 153a2d7e3350 ("USB: gadget: detect too-big endpoint 0 requests") +Cc: Felipe Balbi <balbi@kernel.org> +Reported-by: Szymon Heidrich <szymon.heidrich@gmail.com> +Link: https://lore.kernel.org/r/20211214184621.385828-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/gadget/composite.c | 6 +++--- + drivers/usb/gadget/legacy/dbgp.c | 6 +++--- + drivers/usb/gadget/legacy/inode.c | 6 +++--- + 3 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c +index 284eea9f6e4d8d..3789c329183ca6 100644 +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -1680,14 +1680,14 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) + u8 endp; + + if (w_length > USB_COMP_EP0_BUFSIZ) { +- if (ctrl->bRequestType == USB_DIR_OUT) { +- goto done; +- } else { ++ if (ctrl->bRequestType & USB_DIR_IN) { + /* Cast away the const, we are going to overwrite on purpose. */ + __le16 *temp = (__le16 *)&ctrl->wLength; + + *temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ); + w_length = USB_COMP_EP0_BUFSIZ; ++ } else { ++ goto done; + } + } + +diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c +index 355bc7dab9d5f6..6bcbad38258020 100644 +--- a/drivers/usb/gadget/legacy/dbgp.c ++++ b/drivers/usb/gadget/legacy/dbgp.c +@@ -346,14 +346,14 @@ static int dbgp_setup(struct usb_gadget *gadget, + u16 len = 0; + + if (length > DBGP_REQ_LEN) { +- if (ctrl->bRequestType == USB_DIR_OUT) { +- return err; +- } else { ++ if (ctrl->bRequestType & USB_DIR_IN) { + /* Cast away the const, we are going to overwrite on purpose. */ + __le16 *temp = (__le16 *)&ctrl->wLength; + + *temp = cpu_to_le16(DBGP_REQ_LEN); + length = DBGP_REQ_LEN; ++ } else { ++ return err; + } + } + +diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c +index 0a4041552ed193..1b223cba4c2c92 100644 +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -1337,14 +1337,14 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) + u16 w_length = le16_to_cpu(ctrl->wLength); + + if (w_length > RBUF_SIZE) { +- if (ctrl->bRequestType == USB_DIR_OUT) { +- return value; +- } else { ++ if (ctrl->bRequestType & USB_DIR_IN) { + /* Cast away the const, we are going to overwrite on purpose. */ + __le16 *temp = (__le16 *)&ctrl->wLength; + + *temp = cpu_to_le16(RBUF_SIZE); + w_length = RBUF_SIZE; ++ } else { ++ return value; + } + } + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39685.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39685.patch new file mode 100644 index 000000000..f94ac946b --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39685.patch @@ -0,0 +1,108 @@ +From 36dfdf11af49d3c009c711fb16f5c6e7a274505d Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Date: Thu, 9 Dec 2021 18:59:27 +0100 +Subject: [PATCH] USB: gadget: detect too-big endpoint 0 requests + +commit 153a2d7e3350cc89d406ba2d35be8793a64c2038 upstream. + +Sometimes USB hosts can ask for buffers that are too large from endpoint +0, which should not be allowed. If this happens for OUT requests, stall +the endpoint, but for IN requests, trim the request size to the endpoint +buffer size. + +Co-developed-by: Szymon Heidrich <szymon.heidrich@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/usb/gadget/composite.c | 12 ++++++++++++ + drivers/usb/gadget/legacy/dbgp.c | 13 +++++++++++++ + drivers/usb/gadget/legacy/inode.c | 16 +++++++++++++++- + 3 files changed, 40 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c +index 504c1cbc255d14..1ef7922b57b62e 100644 +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -1679,6 +1679,18 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) + struct usb_function *f = NULL; + u8 endp; + ++ if (w_length > USB_COMP_EP0_BUFSIZ) { ++ if (ctrl->bRequestType == USB_DIR_OUT) { ++ goto done; ++ } else { ++ /* Cast away the const, we are going to overwrite on purpose. */ ++ __le16 *temp = (__le16 *)&ctrl->wLength; ++ ++ *temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ); ++ w_length = USB_COMP_EP0_BUFSIZ; ++ } ++ } ++ + /* partial re-init of the response message; the function or the + * gadget might need to intercept e.g. a control-OUT completion + * when we delegate to it. +diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c +index e1d566c9918ae5..e567afcb2794c0 100644 +--- a/drivers/usb/gadget/legacy/dbgp.c ++++ b/drivers/usb/gadget/legacy/dbgp.c +@@ -345,6 +345,19 @@ static int dbgp_setup(struct usb_gadget *gadget, + void *data = NULL; + u16 len = 0; + ++ if (length > DBGP_REQ_LEN) { ++ if (ctrl->bRequestType == USB_DIR_OUT) { ++ return err; ++ } else { ++ /* Cast away the const, we are going to overwrite on purpose. */ ++ __le16 *temp = (__le16 *)&ctrl->wLength; ++ ++ *temp = cpu_to_le16(DBGP_REQ_LEN); ++ length = DBGP_REQ_LEN; ++ } ++ } ++ ++ + if (request == USB_REQ_GET_DESCRIPTOR) { + switch (value>>8) { + case USB_DT_DEVICE: +diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c +index 539220d7f5b620..0a4041552ed193 100644 +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -110,6 +110,8 @@ enum ep0_state { + /* enough for the whole queue: most events invalidate others */ + #define N_EVENT 5 + ++#define RBUF_SIZE 256 ++ + struct dev_data { + spinlock_t lock; + refcount_t count; +@@ -144,7 +146,7 @@ struct dev_data { + struct dentry *dentry; + + /* except this scratch i/o buffer for ep0 */ +- u8 rbuf [256]; ++ u8 rbuf[RBUF_SIZE]; + }; + + static inline void get_dev (struct dev_data *data) +@@ -1334,6 +1336,18 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) + u16 w_value = le16_to_cpu(ctrl->wValue); + u16 w_length = le16_to_cpu(ctrl->wLength); + ++ if (w_length > RBUF_SIZE) { ++ if (ctrl->bRequestType == USB_DIR_OUT) { ++ return value; ++ } else { ++ /* Cast away the const, we are going to overwrite on purpose. */ ++ __le16 *temp = (__le16 *)&ctrl->wLength; ++ ++ *temp = cpu_to_le16(RBUF_SIZE); ++ w_length = RBUF_SIZE; ++ } ++ } ++ + spin_lock (&dev->lock); + dev->setup_abort = 0; + if (dev->state == STATE_DEV_UNCONNECTED) { diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39698-1.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39698-1.patch new file mode 100644 index 000000000..444fb1035 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39698-1.patch @@ -0,0 +1,47 @@ +From 8d6760fd5d1604df29dd7651033167ef99a7698d Mon Sep 17 00:00:00 2001 +From: Eric Biggers <ebiggers@google.com> +Date: Wed, 8 Dec 2021 17:04:53 -0800 +Subject: [PATCH] signalfd: use wake_up_pollfree() + +commit 9537bae0da1f8d1e2361ab6d0479e8af7824e160 upstream. + +wake_up_poll() uses nr_exclusive=1, so it's not guaranteed to wake up +all exclusive waiters. Yet, POLLFREE *must* wake up all waiters. epoll +and aio poll are fortunately not affected by this, but it's very +fragile. Thus, the new function wake_up_pollfree() has been introduced. + +Convert signalfd to use wake_up_pollfree(). + +Reported-by: Linus Torvalds <torvalds@linux-foundation.org> +Fixes: d80e731ecab4 ("epoll: introduce POLLFREE to flush ->signalfd_wqh before kfree()") +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20211209010455.42744-4-ebiggers@kernel.org +Signed-off-by: Eric Biggers <ebiggers@google.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + fs/signalfd.c | 12 +----------- + 1 file changed, 1 insertion(+), 11 deletions(-) + +diff --git a/fs/signalfd.c b/fs/signalfd.c +index 040e1cf9052826..65ce0e72e7b958 100644 +--- a/fs/signalfd.c ++++ b/fs/signalfd.c +@@ -35,17 +35,7 @@ + + void signalfd_cleanup(struct sighand_struct *sighand) + { +- wait_queue_head_t *wqh = &sighand->signalfd_wqh; +- /* +- * The lockless check can race with remove_wait_queue() in progress, +- * but in this case its caller should run under rcu_read_lock() and +- * sighand_cachep is SLAB_TYPESAFE_BY_RCU, we can safely return. +- */ +- if (likely(!waitqueue_active(wqh))) +- return; +- +- /* wait_queue_entry_t->func(POLLFREE) should do remove_wait_queue() */ +- wake_up_poll(wqh, EPOLLHUP | POLLFREE); ++ wake_up_pollfree(&sighand->signalfd_wqh); + } + + struct signalfd_ctx { diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39698.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39698.patch new file mode 100644 index 000000000..9a7250566 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-39698.patch @@ -0,0 +1,107 @@ +From 1ebb6cd8c754bfe1a5f9539027980756bce7cb08 Mon Sep 17 00:00:00 2001 +From: Eric Biggers <ebiggers@google.com> +Date: Wed, 8 Dec 2021 17:04:51 -0800 +Subject: [PATCH] wait: add wake_up_pollfree() + +commit 42288cb44c4b5fff7653bc392b583a2b8bd6a8c0 upstream. + +Several ->poll() implementations are special in that they use a +waitqueue whose lifetime is the current task, rather than the struct +file as is normally the case. This is okay for blocking polls, since a +blocking poll occurs within one task; however, non-blocking polls +require another solution. This solution is for the queue to be cleared +before it is freed, using 'wake_up_poll(wq, EPOLLHUP | POLLFREE);'. + +However, that has a bug: wake_up_poll() calls __wake_up() with +nr_exclusive=1. Therefore, if there are multiple "exclusive" waiters, +and the wakeup function for the first one returns a positive value, only +that one will be called. That's *not* what's needed for POLLFREE; +POLLFREE is special in that it really needs to wake up everyone. + +Considering the three non-blocking poll systems: + +- io_uring poll doesn't handle POLLFREE at all, so it is broken anyway. + +- aio poll is unaffected, since it doesn't support exclusive waits. + However, that's fragile, as someone could add this feature later. + +- epoll doesn't appear to be broken by this, since its wakeup function + returns 0 when it sees POLLFREE. But this is fragile. + +Although there is a workaround (see epoll), it's better to define a +function which always sends POLLFREE to all waiters. Add such a +function. Also make it verify that the queue really becomes empty after +all waiters have been woken up. + +Reported-by: Linus Torvalds <torvalds@linux-foundation.org> +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20211209010455.42744-2-ebiggers@kernel.org +Signed-off-by: Eric Biggers <ebiggers@google.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + include/linux/wait.h | 26 ++++++++++++++++++++++++++ + kernel/sched/wait.c | 7 +++++++ + 2 files changed, 33 insertions(+) + +diff --git a/include/linux/wait.h b/include/linux/wait.h +index 93dab0e9580f8d..d22cf2985b8fd6 100644 +--- a/include/linux/wait.h ++++ b/include/linux/wait.h +@@ -217,6 +217,7 @@ void __wake_up_sync_key(struct wait_queue_head *wq_head, unsigned int mode, void + void __wake_up_locked_sync_key(struct wait_queue_head *wq_head, unsigned int mode, void *key); + void __wake_up_locked(struct wait_queue_head *wq_head, unsigned int mode, int nr); + void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode); ++void __wake_up_pollfree(struct wait_queue_head *wq_head); + + #define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL) + #define wake_up_nr(x, nr) __wake_up(x, TASK_NORMAL, nr, NULL) +@@ -245,6 +246,31 @@ void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode); + #define wake_up_interruptible_sync_poll_locked(x, m) \ + __wake_up_locked_sync_key((x), TASK_INTERRUPTIBLE, poll_to_key(m)) + ++/** ++ * wake_up_pollfree - signal that a polled waitqueue is going away ++ * @wq_head: the wait queue head ++ * ++ * In the very rare cases where a ->poll() implementation uses a waitqueue whose ++ * lifetime is tied to a task rather than to the 'struct file' being polled, ++ * this function must be called before the waitqueue is freed so that ++ * non-blocking polls (e.g. epoll) are notified that the queue is going away. ++ * ++ * The caller must also RCU-delay the freeing of the wait_queue_head, e.g. via ++ * an explicit synchronize_rcu() or call_rcu(), or via SLAB_TYPESAFE_BY_RCU. ++ */ ++static inline void wake_up_pollfree(struct wait_queue_head *wq_head) ++{ ++ /* ++ * For performance reasons, we don't always take the queue lock here. ++ * Therefore, we might race with someone removing the last entry from ++ * the queue, and proceed while they still hold the queue lock. ++ * However, rcu_read_lock() is required to be held in such cases, so we ++ * can safely proceed with an RCU-delayed free. ++ */ ++ if (waitqueue_active(wq_head)) ++ __wake_up_pollfree(wq_head); ++} ++ + #define ___wait_cond_timeout(condition) \ + ({ \ + bool __cond = (condition); \ +diff --git a/kernel/sched/wait.c b/kernel/sched/wait.c +index 76577d1642a5dc..eca38107b32f16 100644 +--- a/kernel/sched/wait.c ++++ b/kernel/sched/wait.c +@@ -238,6 +238,13 @@ void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode) + } + EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */ + ++void __wake_up_pollfree(struct wait_queue_head *wq_head) ++{ ++ __wake_up(wq_head, TASK_NORMAL, 0, poll_to_key(EPOLLHUP | POLLFREE)); ++ /* POLLFREE must have cleared the queue. */ ++ WARN_ON_ONCE(waitqueue_active(wq_head)); ++} ++ + /* + * Note: we use "set_current_state()" _after_ the wait-queue add, + * because we need a memory barrier there on SMP, so that any diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-4083.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-4083.patch new file mode 100644 index 000000000..233085359 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-4083.patch @@ -0,0 +1,64 @@ +From 6fe4eadd54da3040cf6f6579ae157ae1395dc0f8 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds <torvalds@linux-foundation.org> +Date: Wed, 1 Dec 2021 10:06:14 -0800 +Subject: [PATCH] fget: check that the fd still exists after getting a ref to + it + +commit 054aa8d439b9185d4f5eb9a90282d1ce74772969 upstream. + +Jann Horn points out that there is another possible race wrt Unix domain +socket garbage collection, somewhat reminiscent of the one fixed in +commit cbcf01128d0a ("af_unix: fix garbage collect vs MSG_PEEK"). + +See the extended comment about the garbage collection requirements added +to unix_peek_fds() by that commit for details. + +The race comes from how we can locklessly look up a file descriptor just +as it is in the process of being closed, and with the right artificial +timing (Jann added a few strategic 'mdelay(500)' calls to do that), the +Unix domain socket garbage collector could see the reference count +decrement of the close() happen before fget() took its reference to the +file and the file was attached onto a new file descriptor. + +This is all (intentionally) correct on the 'struct file *' side, with +RCU lookups and lockless reference counting very much part of the +design. Getting that reference count out of order isn't a problem per +se. + +But the garbage collector can get confused by seeing this situation of +having seen a file not having any remaining external references and then +seeing it being attached to an fd. + +In commit cbcf01128d0a ("af_unix: fix garbage collect vs MSG_PEEK") the +fix was to serialize the file descriptor install with the garbage +collector by taking and releasing the unix_gc_lock. + +That's not really an option here, but since this all happens when we are +in the process of looking up a file descriptor, we can instead simply +just re-check that the file hasn't been closed in the meantime, and just +re-do the lookup if we raced with a concurrent close() of the same file +descriptor. + +Reported-and-tested-by: Jann Horn <jannh@google.com> +Acked-by: Miklos Szeredi <mszeredi@redhat.com> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + fs/file.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/file.c b/fs/file.c +index 8627dacfc4246f..ad4a8bf3cf109f 100644 +--- a/fs/file.c ++++ b/fs/file.c +@@ -858,6 +858,10 @@ static struct file *__fget_files(struct files_struct *files, unsigned int fd, + file = NULL; + else if (!get_file_rcu_many(file, refs)) + goto loop; ++ else if (files_lookup_fd_raw(files, fd) != file) { ++ fput_many(file, refs); ++ goto loop; ++ } + } + rcu_read_unlock(); + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-0168.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-0168.patch new file mode 100644 index 000000000..68e56b224 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-0168.patch @@ -0,0 +1,335 @@ +From eee9254fe110ed2cb4593abb6eceb3a72cb92fe9 Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara <pc@cjr.nz> +Date: Tue, 29 Mar 2022 16:20:06 -0300 +Subject: [PATCH] cifs: fix NULL ptr dereference in smb2_ioctl_query_info() + +commit d6f5e358452479fa8a773b5c6ccc9e4ec5a20880 upstream. + +When calling smb2_ioctl_query_info() with invalid +smb_query_info::flags, a NULL ptr dereference is triggered when trying +to kfree() uninitialised rqst[n].rq_iov array. + +This also fixes leaked paths that are created in SMB2_open_init() +which required SMB2_open_free() to properly free them. + +Here is a small C reproducer that triggers it + + #include <stdio.h> + #include <stdlib.h> + #include <stdint.h> + #include <unistd.h> + #include <fcntl.h> + #include <sys/ioctl.h> + + #define die(s) perror(s), exit(1) + #define QUERY_INFO 0xc018cf07 + + int main(int argc, char *argv[]) + { + int fd; + + if (argc < 2) + exit(1); + fd = open(argv[1], O_RDONLY); + if (fd == -1) + die("open"); + if (ioctl(fd, QUERY_INFO, (uint32_t[]) { 0, 0, 0, 4, 0, 0}) == -1) + die("ioctl"); + close(fd); + return 0; + } + + mount.cifs //srv/share /mnt -o ... + gcc repro.c && ./a.out /mnt/f0 + + [ 1832.124468] CIFS: VFS: \\w22-dc.zelda.test\test Invalid passthru query flags: 0x4 + [ 1832.125043] general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN NOPTI + [ 1832.125764] KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] + [ 1832.126241] CPU: 3 PID: 1133 Comm: a.out Not tainted 5.17.0-rc8 #2 + [ 1832.126630] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.15.0-0-g2dd4b9b-rebuilt.opensuse.org 04/01/2014 + [ 1832.127322] RIP: 0010:smb2_ioctl_query_info+0x7a3/0xe30 [cifs] + [ 1832.127749] Code: 00 00 00 fc ff df 48 c1 ea 03 80 3c 02 00 0f 85 6c 05 00 00 48 b8 00 00 00 00 00 fc ff df 4d 8b 74 24 28 4c 89 f2 48 c1 ea 03 <80> 3c 02 00 0f 85 cb 04 00 00 49 8b 3e e8 bb fc fa ff 48 89 da 48 + [ 1832.128911] RSP: 0018:ffffc90000957b08 EFLAGS: 00010256 + [ 1832.129243] RAX: dffffc0000000000 RBX: ffff888117e9b850 RCX: ffffffffa020580d + [ 1832.129691] RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffffffffa043a2c0 + [ 1832.130137] RBP: ffff888117e9b878 R08: 0000000000000001 R09: 0000000000000003 + [ 1832.130585] R10: fffffbfff4087458 R11: 0000000000000001 R12: ffff888117e9b800 + [ 1832.131037] R13: 00000000ffffffea R14: 0000000000000000 R15: ffff888117e9b8a8 + [ 1832.131485] FS: 00007fcee9900740(0000) GS:ffff888151a00000(0000) knlGS:0000000000000000 + [ 1832.131993] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + [ 1832.132354] CR2: 00007fcee9a1ef5e CR3: 0000000114cd2000 CR4: 0000000000350ee0 + [ 1832.132801] Call Trace: + [ 1832.132962] <TASK> + [ 1832.133104] ? smb2_query_reparse_tag+0x890/0x890 [cifs] + [ 1832.133489] ? cifs_mapchar+0x460/0x460 [cifs] + [ 1832.133822] ? rcu_read_lock_sched_held+0x3f/0x70 + [ 1832.134125] ? cifs_strndup_to_utf16+0x15b/0x250 [cifs] + [ 1832.134502] ? lock_downgrade+0x6f0/0x6f0 + [ 1832.134760] ? cifs_convert_path_to_utf16+0x198/0x220 [cifs] + [ 1832.135170] ? smb2_check_message+0x1080/0x1080 [cifs] + [ 1832.135545] cifs_ioctl+0x1577/0x3320 [cifs] + [ 1832.135864] ? lock_downgrade+0x6f0/0x6f0 + [ 1832.136125] ? cifs_readdir+0x2e60/0x2e60 [cifs] + [ 1832.136468] ? rcu_read_lock_sched_held+0x3f/0x70 + [ 1832.136769] ? __rseq_handle_notify_resume+0x80b/0xbe0 + [ 1832.137096] ? __up_read+0x192/0x710 + [ 1832.137327] ? __ia32_sys_rseq+0xf0/0xf0 + [ 1832.137578] ? __x64_sys_openat+0x11f/0x1d0 + [ 1832.137850] __x64_sys_ioctl+0x127/0x190 + [ 1832.138103] do_syscall_64+0x3b/0x90 + [ 1832.138378] entry_SYSCALL_64_after_hwframe+0x44/0xae + [ 1832.138702] RIP: 0033:0x7fcee9a253df + [ 1832.138937] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <41> 89 c0 3d 00 f0 ff ff 77 1f 48 8b 44 24 18 64 48 2b 04 25 28 00 + [ 1832.140107] RSP: 002b:00007ffeba94a8a0 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 + [ 1832.140606] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fcee9a253df + [ 1832.141058] RDX: 00007ffeba94a910 RSI: 00000000c018cf07 RDI: 0000000000000003 + [ 1832.141503] RBP: 00007ffeba94a930 R08: 00007fcee9b24db0 R09: 00007fcee9b45c4e + [ 1832.141948] R10: 00007fcee9918d40 R11: 0000000000000246 R12: 00007ffeba94aa48 + [ 1832.142396] R13: 0000000000401176 R14: 0000000000403df8 R15: 00007fcee9b78000 + [ 1832.142851] </TASK> + [ 1832.142994] Modules linked in: cifs cifs_arc4 cifs_md4 bpf_preload [last unloaded: cifs] + +Cc: stable@vger.kernel.org +Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + fs/cifs/smb2ops.c | 130 +++++++++++++++++++++++++--------------------- + 1 file changed, 70 insertions(+), 60 deletions(-) + +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index bda606dc72b1..db3ead52ec7c 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -1631,6 +1631,7 @@ smb2_ioctl_query_info(const unsigned int xid, + unsigned int size[2]; + void *data[2]; + int create_options = is_dir ? CREATE_NOT_FILE : CREATE_NOT_DIR; ++ void (*free_req1_func)(struct smb_rqst *r); + + vars = kzalloc(sizeof(*vars), GFP_ATOMIC); + if (vars == NULL) +@@ -1640,27 +1641,29 @@ smb2_ioctl_query_info(const unsigned int xid, + + resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; + +- if (copy_from_user(&qi, arg, sizeof(struct smb_query_info))) +- goto e_fault; +- ++ if (copy_from_user(&qi, arg, sizeof(struct smb_query_info))) { ++ rc = -EFAULT; ++ goto free_vars; ++ } + if (qi.output_buffer_length > 1024) { +- kfree(vars); +- return -EINVAL; ++ rc = -EINVAL; ++ goto free_vars; + } + + if (!ses || !server) { +- kfree(vars); +- return -EIO; ++ rc = -EIO; ++ goto free_vars; + } + + if (smb3_encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + +- buffer = memdup_user(arg + sizeof(struct smb_query_info), +- qi.output_buffer_length); +- if (IS_ERR(buffer)) { +- kfree(vars); +- return PTR_ERR(buffer); ++ if (qi.output_buffer_length) { ++ buffer = memdup_user(arg + sizeof(struct smb_query_info), qi.output_buffer_length); ++ if (IS_ERR(buffer)) { ++ rc = PTR_ERR(buffer); ++ goto free_vars; ++ } + } + + /* Open */ +@@ -1698,45 +1701,45 @@ smb2_ioctl_query_info(const unsigned int xid, + rc = SMB2_open_init(tcon, server, + &rqst[0], &oplock, &oparms, path); + if (rc) +- goto iqinf_exit; ++ goto free_output_buffer; + smb2_set_next_command(tcon, &rqst[0]); + + /* Query */ + if (qi.flags & PASSTHRU_FSCTL) { + /* Can eventually relax perm check since server enforces too */ +- if (!capable(CAP_SYS_ADMIN)) ++ if (!capable(CAP_SYS_ADMIN)) { + rc = -EPERM; +- else { +- rqst[1].rq_iov = &vars->io_iov[0]; +- rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE; +- +- rc = SMB2_ioctl_init(tcon, server, +- &rqst[1], +- COMPOUND_FID, COMPOUND_FID, +- qi.info_type, true, buffer, +- qi.output_buffer_length, +- CIFSMaxBufSize - +- MAX_SMB2_CREATE_RESPONSE_SIZE - +- MAX_SMB2_CLOSE_RESPONSE_SIZE); ++ goto free_open_req; + } ++ rqst[1].rq_iov = &vars->io_iov[0]; ++ rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE; ++ ++ rc = SMB2_ioctl_init(tcon, server, &rqst[1], COMPOUND_FID, COMPOUND_FID, ++ qi.info_type, true, buffer, qi.output_buffer_length, ++ CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE - ++ MAX_SMB2_CLOSE_RESPONSE_SIZE); ++ free_req1_func = SMB2_ioctl_free; + } else if (qi.flags == PASSTHRU_SET_INFO) { + /* Can eventually relax perm check since server enforces too */ +- if (!capable(CAP_SYS_ADMIN)) ++ if (!capable(CAP_SYS_ADMIN)) { + rc = -EPERM; +- else { +- rqst[1].rq_iov = &vars->si_iov[0]; +- rqst[1].rq_nvec = 1; +- +- size[0] = 8; +- data[0] = buffer; +- +- rc = SMB2_set_info_init(tcon, server, +- &rqst[1], +- COMPOUND_FID, COMPOUND_FID, +- current->tgid, +- FILE_END_OF_FILE_INFORMATION, +- SMB2_O_INFO_FILE, 0, data, size); ++ goto free_open_req; + } ++ if (qi.output_buffer_length < 8) { ++ rc = -EINVAL; ++ goto free_open_req; ++ } ++ rqst[1].rq_iov = &vars->si_iov[0]; ++ rqst[1].rq_nvec = 1; ++ ++ /* MS-FSCC 2.4.13 FileEndOfFileInformation */ ++ size[0] = 8; ++ data[0] = buffer; ++ ++ rc = SMB2_set_info_init(tcon, server, &rqst[1], COMPOUND_FID, COMPOUND_FID, ++ current->tgid, FILE_END_OF_FILE_INFORMATION, ++ SMB2_O_INFO_FILE, 0, data, size); ++ free_req1_func = SMB2_set_info_free; + } else if (qi.flags == PASSTHRU_QUERY_INFO) { + rqst[1].rq_iov = &vars->qi_iov[0]; + rqst[1].rq_nvec = 1; +@@ -1747,6 +1750,7 @@ smb2_ioctl_query_info(const unsigned int xid, + qi.info_type, qi.additional_information, + qi.input_buffer_length, + qi.output_buffer_length, buffer); ++ free_req1_func = SMB2_query_info_free; + } else { /* unknown flags */ + cifs_tcon_dbg(VFS, "Invalid passthru query flags: 0x%x\n", + qi.flags); +@@ -1754,7 +1758,7 @@ smb2_ioctl_query_info(const unsigned int xid, + } + + if (rc) +- goto iqinf_exit; ++ goto free_open_req; + smb2_set_next_command(tcon, &rqst[1]); + smb2_set_related(&rqst[1]); + +@@ -1765,14 +1769,14 @@ smb2_ioctl_query_info(const unsigned int xid, + rc = SMB2_close_init(tcon, server, + &rqst[2], COMPOUND_FID, COMPOUND_FID, false); + if (rc) +- goto iqinf_exit; ++ goto free_req_1; + smb2_set_related(&rqst[2]); + + rc = compound_send_recv(xid, ses, server, + flags, 3, rqst, + resp_buftype, rsp_iov); + if (rc) +- goto iqinf_exit; ++ goto out; + + /* No need to bump num_remote_opens since handle immediately closed */ + if (qi.flags & PASSTHRU_FSCTL) { +@@ -1782,18 +1786,22 @@ smb2_ioctl_query_info(const unsigned int xid, + qi.input_buffer_length = le32_to_cpu(io_rsp->OutputCount); + if (qi.input_buffer_length > 0 && + le32_to_cpu(io_rsp->OutputOffset) + qi.input_buffer_length +- > rsp_iov[1].iov_len) +- goto e_fault; ++ > rsp_iov[1].iov_len) { ++ rc = -EFAULT; ++ goto out; ++ } + + if (copy_to_user(&pqi->input_buffer_length, + &qi.input_buffer_length, +- sizeof(qi.input_buffer_length))) +- goto e_fault; ++ sizeof(qi.input_buffer_length))) { ++ rc = -EFAULT; ++ goto out; ++ } + + if (copy_to_user((void __user *)pqi + sizeof(struct smb_query_info), + (const void *)io_rsp + le32_to_cpu(io_rsp->OutputOffset), + qi.input_buffer_length)) +- goto e_fault; ++ rc = -EFAULT; + } else { + pqi = (struct smb_query_info __user *)arg; + qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base; +@@ -1801,28 +1809,30 @@ smb2_ioctl_query_info(const unsigned int xid, + qi.input_buffer_length = le32_to_cpu(qi_rsp->OutputBufferLength); + if (copy_to_user(&pqi->input_buffer_length, + &qi.input_buffer_length, +- sizeof(qi.input_buffer_length))) +- goto e_fault; ++ sizeof(qi.input_buffer_length))) { ++ rc = -EFAULT; ++ goto out; ++ } + + if (copy_to_user(pqi + 1, qi_rsp->Buffer, + qi.input_buffer_length)) +- goto e_fault; ++ rc = -EFAULT; + } + +- iqinf_exit: +- cifs_small_buf_release(rqst[0].rq_iov[0].iov_base); +- cifs_small_buf_release(rqst[1].rq_iov[0].iov_base); +- cifs_small_buf_release(rqst[2].rq_iov[0].iov_base); ++out: + free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); + free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); + free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); +- kfree(vars); ++ SMB2_close_free(&rqst[2]); ++free_req_1: ++ free_req1_func(&rqst[1]); ++free_open_req: ++ SMB2_open_free(&rqst[0]); ++free_output_buffer: + kfree(buffer); ++free_vars: ++ kfree(vars); + return rc; +- +-e_fault: +- rc = -EFAULT; +- goto iqinf_exit; + } + + static ssize_t +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1012.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1012.patch new file mode 100644 index 000000000..3a8831e60 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1012.patch @@ -0,0 +1,146 @@ +From 1a8ee547da2b64d6a2aedbd38a691578eff14718 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau <w@1wt.eu> +Date: Mon, 2 May 2022 10:46:08 +0200 +Subject: [PATCH] secure_seq: use the 64 bits of the siphash for port offset + calculation + +[ Upstream commit b2d057560b8107c633b39aabe517ff9d93f285e3 ] + +SipHash replaced MD5 in secure_ipv{4,6}_port_ephemeral() via commit +7cd23e5300c1 ("secure_seq: use SipHash in place of MD5"), but the output +remained truncated to 32-bit only. In order to exploit more bits from the +hash, let's make the functions return the full 64-bit of siphash_3u32(). +We also make sure the port offset calculation in __inet_hash_connect() +remains done on 32-bit to avoid the need for div_u64_rem() and an extra +cost on 32-bit systems. + +Cc: Jason A. Donenfeld <Jason@zx2c4.com> +Cc: Moshe Kol <moshe.kol@mail.huji.ac.il> +Cc: Yossi Gilad <yossi.gilad@mail.huji.ac.il> +Cc: Amit Klein <aksecurity@gmail.com> +Reviewed-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: Willy Tarreau <w@1wt.eu> +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + include/net/inet_hashtables.h | 2 +- + include/net/secure_seq.h | 4 ++-- + net/core/secure_seq.c | 4 ++-- + net/ipv4/inet_hashtables.c | 10 ++++++---- + net/ipv6/inet6_hashtables.c | 4 ++-- + 5 files changed, 13 insertions(+), 11 deletions(-) + +diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h +index f72ec113ae568a..98e1ec1a14f038 100644 +--- a/include/net/inet_hashtables.h ++++ b/include/net/inet_hashtables.h +@@ -425,7 +425,7 @@ static inline void sk_rcv_saddr_set(struct sock *sk, __be32 addr) + } + + int __inet_hash_connect(struct inet_timewait_death_row *death_row, +- struct sock *sk, u32 port_offset, ++ struct sock *sk, u64 port_offset, + int (*check_established)(struct inet_timewait_death_row *, + struct sock *, __u16, + struct inet_timewait_sock **)); +diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h +index d7d2495f83c27c..dac91aa38c5af3 100644 +--- a/include/net/secure_seq.h ++++ b/include/net/secure_seq.h +@@ -4,8 +4,8 @@ + + #include <linux/types.h> + +-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); +-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, ++u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); ++u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, + __be16 dport); + u32 secure_tcp_seq(__be32 saddr, __be32 daddr, + __be16 sport, __be16 dport); +diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c +index b5bc680d475536..444cce0184c372 100644 +--- a/net/core/secure_seq.c ++++ b/net/core/secure_seq.c +@@ -94,7 +94,7 @@ u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr, + } + EXPORT_SYMBOL(secure_tcpv6_seq); + +-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, ++u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, + __be16 dport) + { + const struct { +@@ -142,7 +142,7 @@ u32 secure_tcp_seq(__be32 saddr, __be32 daddr, + } + EXPORT_SYMBOL_GPL(secure_tcp_seq); + +-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) ++u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) + { + net_secret_init(); + return siphash_3u32((__force u32)saddr, (__force u32)daddr, +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 7bd1e10086f0a4..606a4220ebb9d4 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -504,7 +504,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, + return -EADDRNOTAVAIL; + } + +-static u32 inet_sk_port_offset(const struct sock *sk) ++static u64 inet_sk_port_offset(const struct sock *sk) + { + const struct inet_sock *inet = inet_sk(sk); + +@@ -734,7 +734,7 @@ EXPORT_SYMBOL_GPL(inet_unhash); + static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT]; + + int __inet_hash_connect(struct inet_timewait_death_row *death_row, +- struct sock *sk, u32 port_offset, ++ struct sock *sk, u64 port_offset, + int (*check_established)(struct inet_timewait_death_row *, + struct sock *, __u16, struct inet_timewait_sock **)) + { +@@ -777,7 +777,9 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, + net_get_random_once(table_perturb, sizeof(table_perturb)); + index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT); + +- offset = (READ_ONCE(table_perturb[index]) + port_offset) % remaining; ++ offset = READ_ONCE(table_perturb[index]) + port_offset; ++ offset %= remaining; ++ + /* In first pass we try ports of @low parity. + * inet_csk_get_port() does the opposite choice. + */ +@@ -859,7 +861,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, + int inet_hash_connect(struct inet_timewait_death_row *death_row, + struct sock *sk) + { +- u32 port_offset = 0; ++ u64 port_offset = 0; + + if (!inet_sk(sk)->inet_num) + port_offset = inet_sk_port_offset(sk); +diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c +index 0a2e7f22839110..40203255ed88b9 100644 +--- a/net/ipv6/inet6_hashtables.c ++++ b/net/ipv6/inet6_hashtables.c +@@ -308,7 +308,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, + return -EADDRNOTAVAIL; + } + +-static u32 inet6_sk_port_offset(const struct sock *sk) ++static u64 inet6_sk_port_offset(const struct sock *sk) + { + const struct inet_sock *inet = inet_sk(sk); + +@@ -320,7 +320,7 @@ static u32 inet6_sk_port_offset(const struct sock *sk) + int inet6_hash_connect(struct inet_timewait_death_row *death_row, + struct sock *sk) + { +- u32 port_offset = 0; ++ u64 port_offset = 0; + + if (!inet_sk(sk)->inet_num) + port_offset = inet6_sk_port_offset(sk); diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1184_1.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1184_1.patch new file mode 100644 index 000000000..b08f7e043 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1184_1.patch @@ -0,0 +1,81 @@ +From 3a3ce941645407cd0b0b7f01ad9e2ea3770f46cc Mon Sep 17 00:00:00 2001 +From: Jan Kara <jack@suse.cz> +Date: Wed, 18 May 2022 11:33:29 +0200 +Subject: [PATCH] ext4: avoid cycles in directory h-tree + +commit 3ba733f879c2a88910744647e41edeefbc0d92b2 upstream. + +A maliciously corrupted filesystem can contain cycles in the h-tree +stored inside a directory. That can easily lead to the kernel corrupting +tree nodes that were already verified under its hands while doing a node +split and consequently accessing unallocated memory. Fix the problem by +verifying traversed block numbers are unique. + +Cc: stable@vger.kernel.org +Signed-off-by: Jan Kara <jack@suse.cz> +Link: https://lore.kernel.org/r/20220518093332.13986-2-jack@suse.cz +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + fs/ext4/namei.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 1deeaf56645130..7c286cd9fe0304 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -777,12 +777,14 @@ static struct dx_frame * + dx_probe(struct ext4_filename *fname, struct inode *dir, + struct dx_hash_info *hinfo, struct dx_frame *frame_in) + { +- unsigned count, indirect; ++ unsigned count, indirect, level, i; + struct dx_entry *at, *entries, *p, *q, *m; + struct dx_root *root; + struct dx_frame *frame = frame_in; + struct dx_frame *ret_err = ERR_PTR(ERR_BAD_DX_DIR); + u32 hash; ++ ext4_lblk_t block; ++ ext4_lblk_t blocks[EXT4_HTREE_LEVEL]; + + memset(frame_in, 0, EXT4_HTREE_LEVEL * sizeof(frame_in[0])); + frame->bh = ext4_read_dirblock(dir, 0, INDEX); +@@ -854,6 +856,8 @@ dx_probe(struct ext4_filename *fname, struct inode *dir, + } + + dxtrace(printk("Look up %x", hash)); ++ level = 0; ++ blocks[0] = 0; + while (1) { + count = dx_get_count(entries); + if (!count || count > dx_get_limit(entries)) { +@@ -882,15 +886,27 @@ dx_probe(struct ext4_filename *fname, struct inode *dir, + dx_get_block(at))); + frame->entries = entries; + frame->at = at; +- if (!indirect--) ++ ++ block = dx_get_block(at); ++ for (i = 0; i <= level; i++) { ++ if (blocks[i] == block) { ++ ext4_warning_inode(dir, ++ "dx entry: tree cycle block %u points back to block %u", ++ blocks[level], block); ++ goto fail; ++ } ++ } ++ if (++level > indirect) + return frame; ++ blocks[level] = block; + frame++; +- frame->bh = ext4_read_dirblock(dir, dx_get_block(at), INDEX); ++ frame->bh = ext4_read_dirblock(dir, block, INDEX); + if (IS_ERR(frame->bh)) { + ret_err = (struct dx_frame *) frame->bh; + frame->bh = NULL; + goto fail; + } ++ + entries = ((struct dx_node *) frame->bh->b_data)->entries; + + if (dx_get_limit(entries) != dx_node_limit(dir)) { diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1184_2.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1184_2.patch new file mode 100644 index 000000000..753272b2a --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1184_2.patch @@ -0,0 +1,88 @@ +From ca17db384762be0ec38373a12460081d22a8b42d Mon Sep 17 00:00:00 2001 +From: Jan Kara <jack@suse.cz> +Date: Wed, 18 May 2022 11:33:28 +0200 +Subject: [PATCH] ext4: verify dir block before splitting it + +commit 46c116b920ebec58031f0a78c5ea9599b0d2a371 upstream. + +Before splitting a directory block verify its directory entries are sane +so that the splitting code does not access memory it should not. + +Cc: stable@vger.kernel.org +Signed-off-by: Jan Kara <jack@suse.cz> +Link: https://lore.kernel.org/r/20220518093332.13986-1-jack@suse.cz +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + fs/ext4/namei.c | 32 +++++++++++++++++++++----------- + 1 file changed, 21 insertions(+), 11 deletions(-) + +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 7f8abd77bc0f79..1deeaf56645130 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -277,9 +277,9 @@ static struct dx_frame *dx_probe(struct ext4_filename *fname, + struct dx_hash_info *hinfo, + struct dx_frame *frame); + static void dx_release(struct dx_frame *frames); +-static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de, +- unsigned blocksize, struct dx_hash_info *hinfo, +- struct dx_map_entry map[]); ++static int dx_make_map(struct inode *dir, struct buffer_head *bh, ++ struct dx_hash_info *hinfo, ++ struct dx_map_entry *map_tail); + static void dx_sort_map(struct dx_map_entry *map, unsigned count); + static struct ext4_dir_entry_2 *dx_move_dirents(struct inode *dir, char *from, + char *to, struct dx_map_entry *offsets, +@@ -1249,15 +1249,23 @@ static inline int search_dirblock(struct buffer_head *bh, + * Create map of hash values, offsets, and sizes, stored at end of block. + * Returns number of entries mapped. + */ +-static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de, +- unsigned blocksize, struct dx_hash_info *hinfo, ++static int dx_make_map(struct inode *dir, struct buffer_head *bh, ++ struct dx_hash_info *hinfo, + struct dx_map_entry *map_tail) + { + int count = 0; +- char *base = (char *) de; ++ struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *)bh->b_data; ++ unsigned int buflen = bh->b_size; ++ char *base = bh->b_data; + struct dx_hash_info h = *hinfo; + +- while ((char *) de < base + blocksize) { ++ if (ext4_has_metadata_csum(dir->i_sb)) ++ buflen -= sizeof(struct ext4_dir_entry_tail); ++ ++ while ((char *) de < base + buflen) { ++ if (ext4_check_dir_entry(dir, NULL, de, bh, base, buflen, ++ ((char *)de) - base)) ++ return -EFSCORRUPTED; + if (de->name_len && de->inode) { + if (ext4_hash_in_dirent(dir)) + h.hash = EXT4_DIRENT_HASH(de); +@@ -1270,8 +1278,7 @@ static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de, + count++; + cond_resched(); + } +- /* XXX: do we need to check rec_len == 0 case? -Chris */ +- de = ext4_next_entry(de, blocksize); ++ de = ext4_next_entry(de, dir->i_sb->s_blocksize); + } + return count; + } +@@ -1943,8 +1950,11 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, + + /* create map in the end of data2 block */ + map = (struct dx_map_entry *) (data2 + blocksize); +- count = dx_make_map(dir, (struct ext4_dir_entry_2 *) data1, +- blocksize, hinfo, map); ++ count = dx_make_map(dir, *bh, hinfo, map); ++ if (count < 0) { ++ err = count; ++ goto journal_error; ++ } + map -= count; + dx_sort_map(map, count); + /* Ensure that neither split block is over half full */ diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1729.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1729.patch new file mode 100644 index 000000000..074be5ec4 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1729.patch @@ -0,0 +1,71 @@ +From e085354dde254bc6c83ee604ea66c2b36f9f9067 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra <peterz@infradead.org> +Date: Fri, 20 May 2022 20:38:06 +0200 +Subject: [PATCH] perf: Fix sys_perf_event_open() race against self + +commit 3ac6487e584a1eb54071dbe1212e05b884136704 upstream. + +Norbert reported that it's possible to race sys_perf_event_open() such +that the looser ends up in another context from the group leader, +triggering many WARNs. + +The move_group case checks for races against itself, but the +!move_group case doesn't, seemingly relying on the previous +group_leader->ctx == ctx check. However, that check is racy due to not +holding any locks at that time. + +Therefore, re-check the result after acquiring locks and bailing +if they no longer match. + +Additionally, clarify the not_move_group case from the +move_group-vs-move_group race. + +Fixes: f63a8daa5812 ("perf: Fix event->ctx locking") +Reported-by: Norbert Slusarek <nslusarek@gmx.net> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + kernel/events/core.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 7c891a8eb32341..565910de92e9b6 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -12283,6 +12283,9 @@ SYSCALL_DEFINE5(perf_event_open, + * Do not allow to attach to a group in a different task + * or CPU context. If we're moving SW events, we'll fix + * this up later, so allow that. ++ * ++ * Racy, not holding group_leader->ctx->mutex, see comment with ++ * perf_event_ctx_lock(). + */ + if (!move_group && group_leader->ctx != ctx) + goto err_context; +@@ -12348,6 +12351,7 @@ SYSCALL_DEFINE5(perf_event_open, + } else { + perf_event_ctx_unlock(group_leader, gctx); + move_group = 0; ++ goto not_move_group; + } + } + +@@ -12364,7 +12368,17 @@ SYSCALL_DEFINE5(perf_event_open, + } + } else { + mutex_lock(&ctx->mutex); ++ ++ /* ++ * Now that we hold ctx->lock, (re)validate group_leader->ctx == ctx, ++ * see the group_leader && !move_group test earlier. ++ */ ++ if (group_leader && group_leader->ctx != ctx) { ++ err = -EINVAL; ++ goto err_locked; ++ } + } ++not_move_group: + + if (ctx->task == TASK_TOMBSTONE) { + err = -ESRCH; diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1998.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1998.patch new file mode 100644 index 000000000..3af84d90d --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1998.patch @@ -0,0 +1,52 @@ +From 60765e43e40fbf7a1df828116172440510fcc3e4 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Fri, 28 Jan 2022 22:57:01 +0300 +Subject: [PATCH] fanotify: Fix stale file descriptor in copy_event_to_user() + +commit ee12595147ac1fbfb5bcb23837e26dd58d94b15d upstream. + +This code calls fd_install() which gives the userspace access to the fd. +Then if copy_info_records_to_user() fails it calls put_unused_fd(fd) but +that will not release it and leads to a stale entry in the file +descriptor table. + +Generally you can't trust the fd after a call to fd_install(). The fix +is to delay the fd_install() until everything else has succeeded. + +Fortunately it requires CAP_SYS_ADMIN to reach this code so the security +impact is less. + +Fixes: f644bc449b37 ("fanotify: fix copy_event_to_user() fid error clean up") +Link: https://lore.kernel.org/r/20220128195656.GA26981@kili +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Reviewed-by: Mathias Krause <minipli@grsecurity.net> +Signed-off-by: Jan Kara <jack@suse.cz> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + fs/notify/fanotify/fanotify_user.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c +index 6facdf476255d1..84ec851211d91c 100644 +--- a/fs/notify/fanotify/fanotify_user.c ++++ b/fs/notify/fanotify/fanotify_user.c +@@ -611,9 +611,6 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, + if (fanotify_is_perm_event(event->mask)) + FANOTIFY_PERM(event)->fd = fd; + +- if (f) +- fd_install(fd, f); +- + if (info_mode) { + ret = copy_info_records_to_user(event, info, info_mode, pidfd, + buf, count); +@@ -621,6 +618,9 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, + goto out_close_fd; + } + ++ if (f) ++ fd_install(fd, f); ++ + return metadata.event_len; + + out_close_fd: diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-20008.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-20008.patch new file mode 100644 index 000000000..1ac478c67 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-20008.patch @@ -0,0 +1,83 @@ +From f3ff5f75d8f6367eac7556c9db1227bb43e5c615 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20L=C3=B6hle?= <CLoehle@hyperstone.com> +Date: Fri, 4 Feb 2022 15:11:37 +0000 +Subject: [PATCH] mmc: block: fix read single on recovery logic + +commit 54309fde1a352ad2674ebba004a79f7d20b9f037 upstream. + +On reads with MMC_READ_MULTIPLE_BLOCK that fail, +the recovery handler will use MMC_READ_SINGLE_BLOCK for +each of the blocks, up to MMC_READ_SINGLE_RETRIES times each. +The logic for this is fixed to never report unsuccessful reads +as success to the block layer. + +On command error with retries remaining, blk_update_request was +called with whatever value error was set last to. +In case it was last set to BLK_STS_OK (default), the read will be +reported as success, even though there was no data read from the device. +This could happen on a CRC mismatch for the response, +a card rejecting the command (e.g. again due to a CRC mismatch). +In case it was last set to BLK_STS_IOERR, the error is reported correctly, +but no retries will be attempted. + +Fixes: 81196976ed946c ("mmc: block: Add blk-mq support") +Cc: stable@vger.kernel.org +Signed-off-by: Christian Loehle <cloehle@hyperstone.com> +Reviewed-by: Adrian Hunter <adrian.hunter@intel.com> +Link: https://lore.kernel.org/r/bc706a6ab08c4fe2834ba0c05a804672@hyperstone.com +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/mmc/core/block.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c +index 431af5e8be2f89..b575d0bfd0d68c 100644 +--- a/drivers/mmc/core/block.c ++++ b/drivers/mmc/core/block.c +@@ -1682,31 +1682,31 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req) + struct mmc_card *card = mq->card; + struct mmc_host *host = card->host; + blk_status_t error = BLK_STS_OK; +- int retries = 0; + + do { + u32 status; + int err; ++ int retries = 0; + +- mmc_blk_rw_rq_prep(mqrq, card, 1, mq); ++ while (retries++ <= MMC_READ_SINGLE_RETRIES) { ++ mmc_blk_rw_rq_prep(mqrq, card, 1, mq); + +- mmc_wait_for_req(host, mrq); ++ mmc_wait_for_req(host, mrq); + +- err = mmc_send_status(card, &status); +- if (err) +- goto error_exit; +- +- if (!mmc_host_is_spi(host) && +- !mmc_ready_for_data(status)) { +- err = mmc_blk_fix_state(card, req); ++ err = mmc_send_status(card, &status); + if (err) + goto error_exit; +- } + +- if (mrq->cmd->error && retries++ < MMC_READ_SINGLE_RETRIES) +- continue; ++ if (!mmc_host_is_spi(host) && ++ !mmc_ready_for_data(status)) { ++ err = mmc_blk_fix_state(card, req); ++ if (err) ++ goto error_exit; ++ } + +- retries = 0; ++ if (!mrq->cmd->error) ++ break; ++ } + + if (mrq->cmd->error || + mrq->data->error || diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-20368.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-20368.patch new file mode 100644 index 000000000..99a7655bd --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-20368.patch @@ -0,0 +1,114 @@ +From a055f5f2841f7522b44a2b1eccb1951b4b03d51a Mon Sep 17 00:00:00 2001 +From: Eric Dumazet <edumazet@google.com> +Date: Sat, 12 Mar 2022 15:29:58 -0800 +Subject: [PATCH] net/packet: fix slab-out-of-bounds access in packet_recvmsg() + +[ Upstream commit c700525fcc06b05adfea78039de02628af79e07a ] + +syzbot found that when an AF_PACKET socket is using PACKET_COPY_THRESH +and mmap operations, tpacket_rcv() is queueing skbs with +garbage in skb->cb[], triggering a too big copy [1] + +Presumably, users of af_packet using mmap() already gets correct +metadata from the mapped buffer, we can simply make sure +to clear 12 bytes that might be copied to user space later. + +BUG: KASAN: stack-out-of-bounds in memcpy include/linux/fortify-string.h:225 [inline] +BUG: KASAN: stack-out-of-bounds in packet_recvmsg+0x56c/0x1150 net/packet/af_packet.c:3489 +Write of size 165 at addr ffffc9000385fb78 by task syz-executor233/3631 + +CPU: 0 PID: 3631 Comm: syz-executor233 Not tainted 5.17.0-rc7-syzkaller-02396-g0b3660695e80 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + <TASK> + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 + print_address_description.constprop.0.cold+0xf/0x336 mm/kasan/report.c:255 + __kasan_report mm/kasan/report.c:442 [inline] + kasan_report.cold+0x83/0xdf mm/kasan/report.c:459 + check_region_inline mm/kasan/generic.c:183 [inline] + kasan_check_range+0x13d/0x180 mm/kasan/generic.c:189 + memcpy+0x39/0x60 mm/kasan/shadow.c:66 + memcpy include/linux/fortify-string.h:225 [inline] + packet_recvmsg+0x56c/0x1150 net/packet/af_packet.c:3489 + sock_recvmsg_nosec net/socket.c:948 [inline] + sock_recvmsg net/socket.c:966 [inline] + sock_recvmsg net/socket.c:962 [inline] + ____sys_recvmsg+0x2c4/0x600 net/socket.c:2632 + ___sys_recvmsg+0x127/0x200 net/socket.c:2674 + __sys_recvmsg+0xe2/0x1a0 net/socket.c:2704 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x44/0xae +RIP: 0033:0x7fdfd5954c29 +Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 41 15 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007ffcf8e71e48 EFLAGS: 00000246 ORIG_RAX: 000000000000002f +RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fdfd5954c29 +RDX: 0000000000000000 RSI: 0000000020000500 RDI: 0000000000000005 +RBP: 0000000000000000 R08: 000000000000000d R09: 000000000000000d +R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffcf8e71e60 +R13: 00000000000f4240 R14: 000000000000c1ff R15: 00007ffcf8e71e54 + </TASK> + +addr ffffc9000385fb78 is located in stack of task syz-executor233/3631 at offset 32 in frame: + ____sys_recvmsg+0x0/0x600 include/linux/uio.h:246 + +this frame has 1 object: + [32, 160) 'addr' + +Memory state around the buggy address: + ffffc9000385fa80: 00 04 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 + ffffc9000385fb00: 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 +>ffffc9000385fb80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f3 + ^ + ffffc9000385fc00: f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 f1 + ffffc9000385fc80: f1 f1 f1 00 f2 f2 f2 00 f2 f2 f2 00 00 00 00 00 +================================================================== + +Fixes: 0fb375fb9b93 ("[AF_PACKET]: Allow for > 8 byte hardware addresses.") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: syzbot <syzkaller@googlegroups.com> +Link: https://lore.kernel.org/r/20220312232958.3535620-1-eric.dumazet@gmail.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + net/packet/af_packet.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index e00c38f242c320..c0d4a65931de56 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2281,8 +2281,11 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, + copy_skb = skb_get(skb); + skb_head = skb->data; + } +- if (copy_skb) ++ if (copy_skb) { ++ memset(&PACKET_SKB_CB(copy_skb)->sa.ll, 0, ++ sizeof(PACKET_SKB_CB(copy_skb)->sa.ll)); + skb_set_owner_r(copy_skb, sk); ++ } + } + snaplen = po->rx_ring.frame_size - macoff; + if ((int)snaplen < 0) { +@@ -3434,6 +3437,8 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, + sock_recv_ts_and_drops(msg, sk, skb); + + if (msg->msg_name) { ++ const size_t max_len = min(sizeof(skb->cb), ++ sizeof(struct sockaddr_storage)); + int copy_len; + + /* If the address length field is there to be filled +@@ -3456,6 +3461,10 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, + msg->msg_namelen = sizeof(struct sockaddr_ll); + } + } ++ if (WARN_ON_ONCE(copy_len > max_len)) { ++ copy_len = max_len; ++ msg->msg_namelen = copy_len; ++ } + memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len); + } + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2503.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2503.patch new file mode 100644 index 000000000..189b6ce19 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2503.patch @@ -0,0 +1,35 @@ +From 69712b170237ec5979f168149cd31e851a465853 Mon Sep 17 00:00:00 2001 +From: Sarthak Kukreti <sarthakkukreti@google.com> +Date: Tue, 31 May 2022 15:56:40 -0400 +Subject: [PATCH] dm verity: set DM_TARGET_IMMUTABLE feature flag + +commit 4caae58406f8ceb741603eee460d79bacca9b1b5 upstream. + +The device-mapper framework provides a mechanism to mark targets as +immutable (and hence fail table reloads that try to change the target +type). Add the DM_TARGET_IMMUTABLE flag to the dm-verity target's +feature flags to prevent switching the verity target with a different +target type. + +Fixes: a4ffc152198e ("dm: add verity target") +Cc: stable@vger.kernel.org +Signed-off-by: Sarthak Kukreti <sarthakkukreti@google.com> +Reviewed-by: Kees Cook <keescook@chromium.org> +Signed-off-by: Mike Snitzer <snitzer@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/md/dm-verity-target.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c +index 88288c8d6bc8c0..426299ceb33d7d 100644 +--- a/drivers/md/dm-verity-target.c ++++ b/drivers/md/dm-verity-target.c +@@ -1312,6 +1312,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv) + + static struct target_type verity_target = { + .name = "verity", ++ .features = DM_TARGET_IMMUTABLE, + .version = {1, 8, 0}, + .module = THIS_MODULE, + .ctr = verity_ctr, diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2938.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2938.patch new file mode 100644 index 000000000..5f231cfe4 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2938.patch @@ -0,0 +1,249 @@ +From d3e4c61e143e69671803ef3f52140cf7a7258ee7 Mon Sep 17 00:00:00 2001 +From: Suren Baghdasaryan <surenb@google.com> +Date: Tue, 11 Jan 2022 15:23:09 -0800 +Subject: [PATCH] psi: Fix uaf issue when psi trigger is destroyed while being + polled + +commit a06247c6804f1a7c86a2e5398a4c1f1db1471848 upstream. + +With write operation on psi files replacing old trigger with a new one, +the lifetime of its waitqueue is totally arbitrary. Overwriting an +existing trigger causes its waitqueue to be freed and pending poll() +will stumble on trigger->event_wait which was destroyed. +Fix this by disallowing to redefine an existing psi trigger. If a write +operation is used on a file descriptor with an already existing psi +trigger, the operation will fail with EBUSY error. +Also bypass a check for psi_disabled in the psi_trigger_destroy as the +flag can be flipped after the trigger is created, leading to a memory +leak. + +Fixes: 0e94682b73bf ("psi: introduce psi monitor") +Reported-by: syzbot+cdb5dd11c97cc532efad@syzkaller.appspotmail.com +Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> +Analyzed-by: Eric Biggers <ebiggers@kernel.org> +Signed-off-by: Suren Baghdasaryan <surenb@google.com> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Reviewed-by: Eric Biggers <ebiggers@google.com> +Acked-by: Johannes Weiner <hannes@cmpxchg.org> +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20220111232309.1786347-1-surenb@google.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + Documentation/accounting/psi.rst | 3 +- + include/linux/psi.h | 2 +- + include/linux/psi_types.h | 3 -- + kernel/cgroup/cgroup.c | 11 ++++-- + kernel/sched/psi.c | 66 ++++++++++++++------------------ + 5 files changed, 40 insertions(+), 45 deletions(-) + +diff --git a/Documentation/accounting/psi.rst b/Documentation/accounting/psi.rst +index f2b3439edcc2cc..860fe651d6453e 100644 +--- a/Documentation/accounting/psi.rst ++++ b/Documentation/accounting/psi.rst +@@ -92,7 +92,8 @@ Triggers can be set on more than one psi metric and more than one trigger + for the same psi metric can be specified. However for each trigger a separate + file descriptor is required to be able to poll it separately from others, + therefore for each trigger a separate open() syscall should be made even +-when opening the same psi interface file. ++when opening the same psi interface file. Write operations to a file descriptor ++with an already existing psi trigger will fail with EBUSY. + + Monitors activate only when system enters stall state for the monitored + psi metric and deactivates upon exit from the stall state. While system is +diff --git a/include/linux/psi.h b/include/linux/psi.h +index 65eb1476ac7056..74f7148dfb9f4c 100644 +--- a/include/linux/psi.h ++++ b/include/linux/psi.h +@@ -32,7 +32,7 @@ void cgroup_move_task(struct task_struct *p, struct css_set *to); + + struct psi_trigger *psi_trigger_create(struct psi_group *group, + char *buf, size_t nbytes, enum psi_res res); +-void psi_trigger_replace(void **trigger_ptr, struct psi_trigger *t); ++void psi_trigger_destroy(struct psi_trigger *t); + + __poll_t psi_trigger_poll(void **trigger_ptr, struct file *file, + poll_table *wait); +diff --git a/include/linux/psi_types.h b/include/linux/psi_types.h +index 0819c82dba920a..6f190002a20224 100644 +--- a/include/linux/psi_types.h ++++ b/include/linux/psi_types.h +@@ -140,9 +140,6 @@ struct psi_trigger { + * events to one per window + */ + u64 last_event_time; +- +- /* Refcounting to prevent premature destruction */ +- struct kref refcount; + }; + + struct psi_group { +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index bb1a78ff14374e..de8b4fa1e1fd68 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -3642,6 +3642,12 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf, + cgroup_get(cgrp); + cgroup_kn_unlock(of->kn); + ++ /* Allow only one trigger per file descriptor */ ++ if (ctx->psi.trigger) { ++ cgroup_put(cgrp); ++ return -EBUSY; ++ } ++ + psi = cgroup_ino(cgrp) == 1 ? &psi_system : &cgrp->psi; + new = psi_trigger_create(psi, buf, nbytes, res); + if (IS_ERR(new)) { +@@ -3649,8 +3655,7 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf, + return PTR_ERR(new); + } + +- psi_trigger_replace(&ctx->psi.trigger, new); +- ++ smp_store_release(&ctx->psi.trigger, new); + cgroup_put(cgrp); + + return nbytes; +@@ -3689,7 +3694,7 @@ static void cgroup_pressure_release(struct kernfs_open_file *of) + { + struct cgroup_file_ctx *ctx = of->priv; + +- psi_trigger_replace(&ctx->psi.trigger, NULL); ++ psi_trigger_destroy(ctx->psi.trigger); + } + + bool cgroup_psi_enabled(void) +diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c +index 69b19d3af690ff..ab460f8b77d13a 100644 +--- a/kernel/sched/psi.c ++++ b/kernel/sched/psi.c +@@ -1162,7 +1162,6 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, + t->event = 0; + t->last_event_time = 0; + init_waitqueue_head(&t->event_wait); +- kref_init(&t->refcount); + + mutex_lock(&group->trigger_lock); + +@@ -1191,15 +1190,19 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, + return t; + } + +-static void psi_trigger_destroy(struct kref *ref) ++void psi_trigger_destroy(struct psi_trigger *t) + { +- struct psi_trigger *t = container_of(ref, struct psi_trigger, refcount); +- struct psi_group *group = t->group; ++ struct psi_group *group; + struct task_struct *task_to_destroy = NULL; + +- if (static_branch_likely(&psi_disabled)) ++ /* ++ * We do not check psi_disabled since it might have been disabled after ++ * the trigger got created. ++ */ ++ if (!t) + return; + ++ group = t->group; + /* + * Wakeup waiters to stop polling. Can happen if cgroup is deleted + * from under a polling process. +@@ -1235,9 +1238,9 @@ static void psi_trigger_destroy(struct kref *ref) + mutex_unlock(&group->trigger_lock); + + /* +- * Wait for both *trigger_ptr from psi_trigger_replace and +- * poll_task RCUs to complete their read-side critical sections +- * before destroying the trigger and optionally the poll_task ++ * Wait for psi_schedule_poll_work RCU to complete its read-side ++ * critical section before destroying the trigger and optionally the ++ * poll_task. + */ + synchronize_rcu(); + /* +@@ -1254,18 +1257,6 @@ static void psi_trigger_destroy(struct kref *ref) + kfree(t); + } + +-void psi_trigger_replace(void **trigger_ptr, struct psi_trigger *new) +-{ +- struct psi_trigger *old = *trigger_ptr; +- +- if (static_branch_likely(&psi_disabled)) +- return; +- +- rcu_assign_pointer(*trigger_ptr, new); +- if (old) +- kref_put(&old->refcount, psi_trigger_destroy); +-} +- + __poll_t psi_trigger_poll(void **trigger_ptr, + struct file *file, poll_table *wait) + { +@@ -1275,24 +1266,15 @@ __poll_t psi_trigger_poll(void **trigger_ptr, + if (static_branch_likely(&psi_disabled)) + return DEFAULT_POLLMASK | EPOLLERR | EPOLLPRI; + +- rcu_read_lock(); +- +- t = rcu_dereference(*(void __rcu __force **)trigger_ptr); +- if (!t) { +- rcu_read_unlock(); ++ t = smp_load_acquire(trigger_ptr); ++ if (!t) + return DEFAULT_POLLMASK | EPOLLERR | EPOLLPRI; +- } +- kref_get(&t->refcount); +- +- rcu_read_unlock(); + + poll_wait(file, &t->event_wait, wait); + + if (cmpxchg(&t->event, 1, 0) == 1) + ret |= EPOLLPRI; + +- kref_put(&t->refcount, psi_trigger_destroy); +- + return ret; + } + +@@ -1316,14 +1298,24 @@ static ssize_t psi_write(struct file *file, const char __user *user_buf, + + buf[buf_size - 1] = '\0'; + +- new = psi_trigger_create(&psi_system, buf, nbytes, res); +- if (IS_ERR(new)) +- return PTR_ERR(new); +- + seq = file->private_data; ++ + /* Take seq->lock to protect seq->private from concurrent writes */ + mutex_lock(&seq->lock); +- psi_trigger_replace(&seq->private, new); ++ ++ /* Allow only one trigger per file descriptor */ ++ if (seq->private) { ++ mutex_unlock(&seq->lock); ++ return -EBUSY; ++ } ++ ++ new = psi_trigger_create(&psi_system, buf, nbytes, res); ++ if (IS_ERR(new)) { ++ mutex_unlock(&seq->lock); ++ return PTR_ERR(new); ++ } ++ ++ smp_store_release(&seq->private, new); + mutex_unlock(&seq->lock); + + return nbytes; +@@ -1358,7 +1350,7 @@ static int psi_fop_release(struct inode *inode, struct file *file) + { + struct seq_file *seq = file->private_data; + +- psi_trigger_replace(&seq->private, NULL); ++ psi_trigger_destroy(seq->private); + return single_release(inode, file); + } + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2959.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2959.patch new file mode 100644 index 000000000..f8117d0a7 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2959.patch @@ -0,0 +1,97 @@ +From 189b0ddc245139af81198d1a3637cac74f96e13a Mon Sep 17 00:00:00 2001 +From: David Howells <dhowells@redhat.com> +Date: Thu, 26 May 2022 07:34:52 +0100 +Subject: [PATCH] pipe: Fix missing lock in pipe_resize_ring() + +pipe_resize_ring() needs to take the pipe->rd_wait.lock spinlock to +prevent post_one_notification() from trying to insert into the ring +whilst the ring is being replaced. + +The occupancy check must be done after the lock is taken, and the lock +must be taken after the new ring is allocated. + +The bug can lead to an oops looking something like: + + BUG: KASAN: use-after-free in post_one_notification.isra.0+0x62e/0x840 + Read of size 4 at addr ffff88801cc72a70 by task poc/27196 + ... + Call Trace: + post_one_notification.isra.0+0x62e/0x840 + __post_watch_notification+0x3b7/0x650 + key_create_or_update+0xb8b/0xd20 + __do_sys_add_key+0x175/0x340 + __x64_sys_add_key+0xbe/0x140 + do_syscall_64+0x5c/0xc0 + entry_SYSCALL_64_after_hwframe+0x44/0xae + +Reported by Selim Enes Karaduman @Enesdex working with Trend Micro Zero +Day Initiative. + +Fixes: c73be61cede5 ("pipe: Add general notification queue support") +Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-17291 +Signed-off-by: David Howells <dhowells@redhat.com> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +--- + fs/pipe.c | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +diff --git a/fs/pipe.c b/fs/pipe.c +index e140ea150bbb14..11358569a7779a 100644 +--- a/fs/pipe.c ++++ b/fs/pipe.c +@@ -1245,30 +1245,33 @@ unsigned int round_pipe_size(unsigned long size) + + /* + * Resize the pipe ring to a number of slots. ++ * ++ * Note the pipe can be reduced in capacity, but only if the current ++ * occupancy doesn't exceed nr_slots; if it does, EBUSY will be ++ * returned instead. + */ + int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots) + { + struct pipe_buffer *bufs; + unsigned int head, tail, mask, n; + +- /* +- * We can shrink the pipe, if arg is greater than the ring occupancy. +- * Since we don't expect a lot of shrink+grow operations, just free and +- * allocate again like we would do for growing. If the pipe currently +- * contains more buffers than arg, then return busy. +- */ +- mask = pipe->ring_size - 1; +- head = pipe->head; +- tail = pipe->tail; +- n = pipe_occupancy(pipe->head, pipe->tail); +- if (nr_slots < n) +- return -EBUSY; +- + bufs = kcalloc(nr_slots, sizeof(*bufs), + GFP_KERNEL_ACCOUNT | __GFP_NOWARN); + if (unlikely(!bufs)) + return -ENOMEM; + ++ spin_lock_irq(&pipe->rd_wait.lock); ++ mask = pipe->ring_size - 1; ++ head = pipe->head; ++ tail = pipe->tail; ++ ++ n = pipe_occupancy(head, tail); ++ if (nr_slots < n) { ++ spin_unlock_irq(&pipe->rd_wait.lock); ++ kfree(bufs); ++ return -EBUSY; ++ } ++ + /* + * The pipe array wraps around, so just start the new one at zero + * and adjust the indices. +@@ -1300,6 +1303,8 @@ int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots) + pipe->tail = tail; + pipe->head = head; + ++ spin_unlock_irq(&pipe->rd_wait.lock); ++ + /* This might have made more room for writers */ + wake_up_interruptible(&pipe->wr_wait); + return 0; diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-30594.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-30594.patch new file mode 100644 index 000000000..9e9da26d0 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-30594.patch @@ -0,0 +1,103 @@ +From ee1fee900537b5d9560e9f937402de5ddc8412f3 Mon Sep 17 00:00:00 2001 +From: Jann Horn <jannh@google.com> +Date: Sat, 19 Mar 2022 02:08:37 +0100 +Subject: [PATCH] ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on + PTRACE_SEIZE + +Setting PTRACE_O_SUSPEND_SECCOMP is supposed to be a highly privileged +operation because it allows the tracee to completely bypass all seccomp +filters on kernels with CONFIG_CHECKPOINT_RESTORE=y. It is only supposed to +be settable by a process with global CAP_SYS_ADMIN, and only if that +process is not subject to any seccomp filters at all. + +However, while these permission checks were done on the PTRACE_SETOPTIONS +path, they were missing on the PTRACE_SEIZE path, which also sets +user-specified ptrace flags. + +Move the permissions checks out into a helper function and let both +ptrace_attach() and ptrace_setoptions() call it. + +Cc: stable@kernel.org +Fixes: 13c4a90119d2 ("seccomp: add ptrace options for suspend/resume") +Signed-off-by: Jann Horn <jannh@google.com> +Link: https://lkml.kernel.org/r/20220319010838.1386861-1-jannh@google.com +Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> +--- + kernel/ptrace.c | 47 ++++++++++++++++++++++++++++++++--------------- + 1 file changed, 32 insertions(+), 15 deletions(-) + +diff --git a/kernel/ptrace.c b/kernel/ptrace.c +index eea265082e9752..ccc4b465775b82 100644 +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -371,6 +371,26 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode) + return !err; + } + ++static int check_ptrace_options(unsigned long data) ++{ ++ if (data & ~(unsigned long)PTRACE_O_MASK) ++ return -EINVAL; ++ ++ if (unlikely(data & PTRACE_O_SUSPEND_SECCOMP)) { ++ if (!IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) || ++ !IS_ENABLED(CONFIG_SECCOMP)) ++ return -EINVAL; ++ ++ if (!capable(CAP_SYS_ADMIN)) ++ return -EPERM; ++ ++ if (seccomp_mode(¤t->seccomp) != SECCOMP_MODE_DISABLED || ++ current->ptrace & PT_SUSPEND_SECCOMP) ++ return -EPERM; ++ } ++ return 0; ++} ++ + static int ptrace_attach(struct task_struct *task, long request, + unsigned long addr, + unsigned long flags) +@@ -382,8 +402,16 @@ static int ptrace_attach(struct task_struct *task, long request, + if (seize) { + if (addr != 0) + goto out; ++ /* ++ * This duplicates the check in check_ptrace_options() because ++ * ptrace_attach() and ptrace_setoptions() have historically ++ * used different error codes for unknown ptrace options. ++ */ + if (flags & ~(unsigned long)PTRACE_O_MASK) + goto out; ++ retval = check_ptrace_options(flags); ++ if (retval) ++ return retval; + flags = PT_PTRACED | PT_SEIZED | (flags << PT_OPT_FLAG_SHIFT); + } else { + flags = PT_PTRACED; +@@ -654,22 +682,11 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds + static int ptrace_setoptions(struct task_struct *child, unsigned long data) + { + unsigned flags; ++ int ret; + +- if (data & ~(unsigned long)PTRACE_O_MASK) +- return -EINVAL; +- +- if (unlikely(data & PTRACE_O_SUSPEND_SECCOMP)) { +- if (!IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) || +- !IS_ENABLED(CONFIG_SECCOMP)) +- return -EINVAL; +- +- if (!capable(CAP_SYS_ADMIN)) +- return -EPERM; +- +- if (seccomp_mode(¤t->seccomp) != SECCOMP_MODE_DISABLED || +- current->ptrace & PT_SUSPEND_SECCOMP) +- return -EPERM; +- } ++ ret = check_ptrace_options(data); ++ if (ret) ++ return ret; + + /* Avoid intermediate state when all opts are cleared */ + flags = child->ptrace; diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-32296.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-32296.patch new file mode 100644 index 000000000..5772f7e13 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-32296.patch @@ -0,0 +1,61 @@ +From dff5a6126ede802f8df7485b122bf265ad7c69aa Mon Sep 17 00:00:00 2001 +From: Manish Baing <manish.baing@intel.com> +Date: Tue, 21 Jun 2022 05:44:53 +0000 +Subject: [PATCH] tcp: increase source port perturb table to 2^16 + +Moshe Kol, Amit Klein, and Yossi Gilad reported being able to accurately +identify a client by forcing it to emit only 40 times more connections +than there are entries in the table_perturb[] table. The previous two +improvements consisting in resalting the secret every 10s and adding +randomness to each port selection only slightly improved the situation, +and the current value of 2^8 was too small as it's not very difficult +to make a client emit 10k connections in less than 10 seconds. + +Thus we're increasing the perturb table from 2^8 to 2^16 so that the +same precision now requires 2.6M connections, which is more difficult in +this time frame and harder to hide as a background activity. The impact +is that the table now uses 256 kB instead of 1 kB, which could mostly +affect devices making frequent outgoing connections. However such +components usually target a small set of destinations (load balancers, +database clients, perf assessment tools), and in practice only a few +entries will be visited, like before. + +A live test at 1 million connections per second showed no performance +difference from the previous value. + +Reported-by: Moshe Kol <moshe.kol@mail.huji.ac.il> +Reported-by: Yossi Gilad <yossi.gilad@mail.huji.ac.il> +Reported-by: Amit Klein <aksecurity@gmail.com> +Reviewed-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: Willy Tarreau <w@1wt.eu> +Signed-off-by: Jakub Kicinski <kuba@kernel.org> + +Source: https://github.com/openbmc/linux/commit/4c2c8f03a5ab7cb04ec64724d7d176d00bcc91e5 +--- + net/ipv4/inet_hashtables.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index bfb522e51346..86efce0cf4eb 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -715,11 +715,12 @@ EXPORT_SYMBOL_GPL(inet_unhash); + * Note that we use 32bit integers (vs RFC 'short integers') + * because 2^16 is not a multiple of num_ephemeral and this + * property might be used by clever attacker. +- * RFC claims using TABLE_LENGTH=10 buckets gives an improvement, +- * we use 256 instead to really give more isolation and +- * privacy, this only consumes 1 KB of kernel memory. ++ * RFC claims using TABLE_LENGTH=10 buckets gives an improvement, though ++ * attacks were since demonstrated, thus we use 65536 instead to really ++ * give more isolation and privacy, at the expense of 256kB of kernel ++ * memory. + */ +-#define INET_TABLE_PERTURB_SHIFT 8 ++#define INET_TABLE_PERTURB_SHIFT 16 + static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT]; + + int __inet_hash_connect(struct inet_timewait_death_row *death_row, +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-40476.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-40476.patch new file mode 100644 index 000000000..66f34dcb1 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-40476.patch @@ -0,0 +1,35 @@ +From 3746d62ecf1c872a520c4866118edccb121c44fd Mon Sep 17 00:00:00 2001 +From: Jens Axboe <axboe@kernel.dk> +Date: Thu, 23 Jun 2022 11:06:43 -0600 +Subject: [PATCH] io_uring: use original request task for inflight tracking + +commit 386e4fb6962b9f248a80f8870aea0870ca603e89 upstream. + +In prior kernels, we did file assignment always at prep time. This meant +that req->task == current. But after deferring that assignment and then +pushing the inflight tracking back in, we've got the inflight tracking +using current when it should in fact now be using req->task. + +Fixup that error introduced by adding the inflight tracking back after +file assignments got modifed. + +Fixes: 9cae36a094e7 ("io_uring: reinstate the inflight tracking") +Signed-off-by: Jens Axboe <axboe@kernel.dk> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + fs/io_uring.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/io_uring.c b/fs/io_uring.c +index 0ce1587df43221..89f24b54fe5e8d 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -1405,7 +1405,7 @@ static void io_req_track_inflight(struct io_kiocb *req) + { + if (!(req->flags & REQ_F_INFLIGHT)) { + req->flags |= REQ_F_INFLIGHT; +- atomic_inc(¤t->io_uring->inflight_tracked); ++ atomic_inc(&req->task->io_uring->inflight_tracked); + } + } + |