From: Liu Shixin <liushixin2(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I641XX
CVE: NA
--------------------------------
Patch 1378a5ee451a ("mm: store compound_nr as well as compound_order") add
a new member compound_nr in struct page, and use this new member insteal
of compound_order in hugetlb_cgroup_move_parent() to compute the nr_pages.
In free_hugepage_to_hugetlb(), we reset page->mapping to NULL for each
subpage. Since page->mapping and page->compound_nr is union, we reset
page->compound_nr too unexpectly. This will finally result the nr_pages
incorrect in hugetlb_cgroup_move_parent() and can't release hugetlb_cgroup.
Fix this problem by reset page->compound_nr using set_compound_order().
Signed-off-by: Liu Shixin <liushixin2(a)huawei.com>
Reviewed-by: Nanyong Sun <sunnanyong(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
mm/dynamic_hugetlb.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/dynamic_hugetlb.c b/mm/dynamic_hugetlb.c
index eb9b528b73de..8a985d816c07 100644
--- a/mm/dynamic_hugetlb.c
+++ b/mm/dynamic_hugetlb.c
@@ -799,7 +799,8 @@ static int free_hugepage_to_hugetlb(struct dhugetlb_pool *hpool)
p->mapping = NULL;
}
set_compound_page_dtor(page, HUGETLB_PAGE_DTOR);
-
+ /* compound_nr and mapping are union in page, reset it. */
+ set_compound_order(page, PUD_SHIFT - PAGE_SHIFT);
nid = page_to_nid(page);
SetHPageFreed(page);
list_move(&page->lru, &h->hugepage_freelists[nid]);
--
2.20.1
From: Li Nan <linan122(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 187584, https://gitee.com/openeuler/kernel/issues/I5QW2R
CVE: NA
--------------------------------
This reverts commit 36f5d7662495aa5ad4ec197443e69e01384eda3c.
There are two wbt_enable_default() in bfq_exit_queue(). Although it will
not lead to no fault, revert one.
Signed-off-by: Li Nan <linan122(a)huawei.com>
Reviewed-by: Jason Yan <yanaijie(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
block/bfq-iosched.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 4bfea5e5354e..1aec01c0a707 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -6418,8 +6418,6 @@ static void bfq_exit_queue(struct elevator_queue *e)
spin_unlock_irq(&bfqd->lock);
#endif
- wbt_enable_default(bfqd->queue);
-
kfree(bfqd);
/* Re-enable throttling in case elevator disabled it */
--
2.20.1
From: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
mainline inclusion
from mainline-v5.10-rc1
commit 719b8f2850d3d9b863cc5e4f08e9ef0206e45b26
category: bugfix
bugzilla: 188090, https://gitee.com/src-openeuler/kernel/issues/I6068W
CVE: CVE-2022-3903
--------------------------------
New core functions to make sending/receiving USB control messages easier
and saner.
In discussions, it turns out that the large majority of users of
usb_control_msg() do so in potentially incorrect ways. The most common
issue is where a "short" message is received, yet never detected
properly due to "incorrect" error handling.
Handle all of this in the USB core with two new functions to try to make
working with USB control messages simpler.
No more need for dynamic data, messages can be on the stack, and only
"complete" send/receive will work without causing an error.
Link: https://lore.kernel.org/r/20200914153756.3412156-3-gregkh@linuxfoundation.o…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
The parts related to usb_control_msg_send() and usb_control_msg_recv()
in commit USB: correct API of usb_control_msg_send/recv are added to
solve CVE. Commit USB: core: drop pipe-type check from new
control-message helpers is also added.
Signed-off-by: Zhang Peng <zhangpeng362(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/usb/core/message.c | 134 +++++++++++++++++++++++++++++++++++++
include/linux/usb.h | 8 +++
2 files changed, 142 insertions(+)
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index fcf84bfc08e3..0be20b17e754 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -161,6 +161,140 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
}
EXPORT_SYMBOL_GPL(usb_control_msg);
+/**
+ * usb_control_msg_send - Builds a control "send" message, sends it off and waits for completion
+ * @dev: pointer to the usb device to send the message to
+ * @endpoint: endpoint to send the message to
+ * @request: USB message request value
+ * @requesttype: USB message request type value
+ * @value: USB message value
+ * @index: USB message index value
+ * @driver_data: pointer to the data to send
+ * @size: length in bytes of the data to send
+ * @timeout: time in msecs to wait for the message to complete before timing
+ * out (if 0 the wait is forever)
+ * @memflags: the flags for memory allocation for buffers
+ *
+ * Context: !in_interrupt ()
+ *
+ * This function sends a control message to a specified endpoint that is not
+ * expected to fill in a response (i.e. a "send message") and waits for the
+ * message to complete, or timeout.
+ *
+ * Do not use this function from within an interrupt context. If you need
+ * an asynchronous message, or need to send a message from within interrupt
+ * context, use usb_submit_urb(). If a thread in your driver uses this call,
+ * make sure your disconnect() method can wait for it to complete. Since you
+ * don't have a handle on the URB used, you can't cancel the request.
+ *
+ * The data pointer can be made to a reference on the stack, or anywhere else,
+ * as it will not be modified at all. This does not have the restriction that
+ * usb_control_msg() has where the data pointer must be to dynamically allocated
+ * memory (i.e. memory that can be successfully DMAed to a device).
+ *
+ * Return: If successful, 0 is returned, Otherwise, a negative error number.
+ */
+int usb_control_msg_send(struct usb_device *dev, __u8 endpoint, __u8 request,
+ __u8 requesttype, __u16 value, __u16 index,
+ const void *driver_data, __u16 size, int timeout,
+ gfp_t memflags)
+{
+ unsigned int pipe = usb_sndctrlpipe(dev, endpoint);
+ int ret;
+ u8 *data = NULL;
+
+ if (size) {
+ data = kmemdup(driver_data, size, memflags);
+ if (!data)
+ return -ENOMEM;
+ }
+
+ ret = usb_control_msg(dev, pipe, request, requesttype, value, index,
+ data, size, timeout);
+ kfree(data);
+
+ if (ret < 0)
+ return ret;
+ if (ret == size)
+ return 0;
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(usb_control_msg_send);
+
+/**
+ * usb_control_msg_recv - Builds a control "receive" message, sends it off and waits for completion
+ * @dev: pointer to the usb device to send the message to
+ * @endpoint: endpoint to send the message to
+ * @request: USB message request value
+ * @requesttype: USB message request type value
+ * @value: USB message value
+ * @index: USB message index value
+ * @driver_data: pointer to the data to be filled in by the message
+ * @size: length in bytes of the data to be received
+ * @timeout: time in msecs to wait for the message to complete before timing
+ * out (if 0 the wait is forever)
+ * @memflags: the flags for memory allocation for buffers
+ *
+ * Context: !in_interrupt ()
+ *
+ * This function sends a control message to a specified endpoint that is
+ * expected to fill in a response (i.e. a "receive message") and waits for the
+ * message to complete, or timeout.
+ *
+ * Do not use this function from within an interrupt context. If you need
+ * an asynchronous message, or need to send a message from within interrupt
+ * context, use usb_submit_urb(). If a thread in your driver uses this call,
+ * make sure your disconnect() method can wait for it to complete. Since you
+ * don't have a handle on the URB used, you can't cancel the request.
+ *
+ * The data pointer can be made to a reference on the stack, or anywhere else
+ * that can be successfully written to. This function does not have the
+ * restriction that usb_control_msg() has where the data pointer must be to
+ * dynamically allocated memory (i.e. memory that can be successfully DMAed to a
+ * device).
+ *
+ * The "whole" message must be properly received from the device in order for
+ * this function to be successful. If a device returns less than the expected
+ * amount of data, then the function will fail. Do not use this for messages
+ * where a variable amount of data might be returned.
+ *
+ * Return: If successful, 0 is returned, Otherwise, a negative error number.
+ */
+int usb_control_msg_recv(struct usb_device *dev, __u8 endpoint, __u8 request,
+ __u8 requesttype, __u16 value, __u16 index,
+ void *driver_data, __u16 size, int timeout,
+ gfp_t memflags)
+{
+ unsigned int pipe = usb_rcvctrlpipe(dev, endpoint);
+ int ret;
+ u8 *data;
+
+ if (!size || !driver_data)
+ return -EINVAL;
+
+ data = kmalloc(size, memflags);
+ if (!data)
+ return -ENOMEM;
+
+ ret = usb_control_msg(dev, pipe, request, requesttype, value, index,
+ data, size, timeout);
+
+ if (ret < 0)
+ goto exit;
+
+ if (ret == size) {
+ memcpy(driver_data, data, size);
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+exit:
+ kfree(data);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(usb_control_msg_recv);
+
/**
* usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion
* @usb_dev: pointer to the usb device to send the message to
diff --git a/include/linux/usb.h b/include/linux/usb.h
index ff010d1fd1c7..3e1e31f73d0e 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1783,6 +1783,14 @@ extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
int timeout);
/* wrappers around usb_control_msg() for the most common standard requests */
+int usb_control_msg_send(struct usb_device *dev, __u8 endpoint, __u8 request,
+ __u8 requesttype, __u16 value, __u16 index,
+ const void *data, __u16 size, int timeout,
+ gfp_t memflags);
+int usb_control_msg_recv(struct usb_device *dev, __u8 endpoint, __u8 request,
+ __u8 requesttype, __u16 value, __u16 index,
+ void *data, __u16 size, int timeout,
+ gfp_t memflags);
extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype,
unsigned char descindex, void *buf, int size);
extern int usb_get_status(struct usb_device *dev,
--
2.25.1