summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorSakib Sajal <sakib.sajal@windriver.com>2025-02-19 16:18:13 +0800
committerSteve Sakoman <steve@sakoman.com>2025-02-28 06:51:35 -0800
commit83e5ad004a73bf735f8e8ee56ccd4788ae35c3db (patch)
treecfa42ebfd1664c7bb41b866d3a8e5772c46fd9fe /meta
parentd552f8503771cea2aabbaf220e20678203d2bd75 (diff)
downloadpoky-83e5ad004a73bf735f8e8ee56ccd4788ae35c3db.tar.gz
u-boot: fix CVE-2022-2347 and CVE-2022-30790
Backport appropriate patches to fix CVE-2022-2347 and CVE-2022-30790. (From OE-Core rev: 7a5220a4877cd4d3766728e8a3525c157b6167fb) Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-bsp/u-boot/files/CVE-2022-2347_1.patch129
-rw-r--r--meta/recipes-bsp/u-boot/files/CVE-2022-2347_2.patch66
-rw-r--r--meta/recipes-bsp/u-boot/files/CVE-2022-30790.patch149
-rw-r--r--meta/recipes-bsp/u-boot/u-boot_2022.01.bb3
4 files changed, 347 insertions, 0 deletions
diff --git a/meta/recipes-bsp/u-boot/files/CVE-2022-2347_1.patch b/meta/recipes-bsp/u-boot/files/CVE-2022-2347_1.patch
new file mode 100644
index 0000000000..34ee82c3a5
--- /dev/null
+++ b/meta/recipes-bsp/u-boot/files/CVE-2022-2347_1.patch
@@ -0,0 +1,129 @@
1From 9d2d2deabc49dbedf93a7192b25f55d9933fcede Mon Sep 17 00:00:00 2001
2From: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com>
3Date: Thu, 3 Nov 2022 09:37:48 +0530
4Subject: [PATCH 1/2] usb: gadget: dfu: Fix the unchecked length field
5
6DFU implementation does not bound the length field in USB
7DFU download setup packets, and it does not verify that
8the transfer direction. Fixing the length and transfer
9direction.
10
11CVE-2022-2347
12
13Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com>
14Reviewed-by: Marek Vasut <marex@denx.de>
15
16CVE: CVE-2022-2347
17Upstream-Status: Backport [fbce985e28eaca3af82afecc11961aadaf971a7e]
18Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com>
19---
20 drivers/usb/gadget/f_dfu.c | 56 +++++++++++++++++++++++++-------------
21 1 file changed, 37 insertions(+), 19 deletions(-)
22
23diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c
24index 4bedc7d3a1..33ef62f8ba 100644
25--- a/drivers/usb/gadget/f_dfu.c
26+++ b/drivers/usb/gadget/f_dfu.c
27@@ -321,21 +321,29 @@ static int state_dfu_idle(struct f_dfu *f_dfu,
28 u16 len = le16_to_cpu(ctrl->wLength);
29 int value = 0;
30
31+ len = len > DFU_USB_BUFSIZ ? DFU_USB_BUFSIZ : len;
32+
33 switch (ctrl->bRequest) {
34 case USB_REQ_DFU_DNLOAD:
35- if (len == 0) {
36- f_dfu->dfu_state = DFU_STATE_dfuERROR;
37- value = RET_STALL;
38- break;
39+ if (ctrl->bRequestType == USB_DIR_OUT) {
40+ if (len == 0) {
41+ f_dfu->dfu_state = DFU_STATE_dfuERROR;
42+ value = RET_STALL;
43+ break;
44+ }
45+ f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
46+ f_dfu->blk_seq_num = w_value;
47+ value = handle_dnload(gadget, len);
48 }
49- f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
50- f_dfu->blk_seq_num = w_value;
51- value = handle_dnload(gadget, len);
52 break;
53 case USB_REQ_DFU_UPLOAD:
54- f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE;
55- f_dfu->blk_seq_num = 0;
56- value = handle_upload(req, len);
57+ if (ctrl->bRequestType == USB_DIR_IN) {
58+ f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE;
59+ f_dfu->blk_seq_num = 0;
60+ value = handle_upload(req, len);
61+ if (value >= 0 && value < len)
62+ f_dfu->dfu_state = DFU_STATE_dfuIDLE;
63+ }
64 break;
65 case USB_REQ_DFU_ABORT:
66 /* no zlp? */
67@@ -424,11 +432,15 @@ static int state_dfu_dnload_idle(struct f_dfu *f_dfu,
68 u16 len = le16_to_cpu(ctrl->wLength);
69 int value = 0;
70
71+ len = len > DFU_USB_BUFSIZ ? DFU_USB_BUFSIZ : len;
72+
73 switch (ctrl->bRequest) {
74 case USB_REQ_DFU_DNLOAD:
75- f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
76- f_dfu->blk_seq_num = w_value;
77- value = handle_dnload(gadget, len);
78+ if (ctrl->bRequestType == USB_DIR_OUT) {
79+ f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
80+ f_dfu->blk_seq_num = w_value;
81+ value = handle_dnload(gadget, len);
82+ }
83 break;
84 case USB_REQ_DFU_ABORT:
85 f_dfu->dfu_state = DFU_STATE_dfuIDLE;
86@@ -511,13 +523,17 @@ static int state_dfu_upload_idle(struct f_dfu *f_dfu,
87 u16 len = le16_to_cpu(ctrl->wLength);
88 int value = 0;
89
90+ len = len > DFU_USB_BUFSIZ ? DFU_USB_BUFSIZ : len;
91+
92 switch (ctrl->bRequest) {
93 case USB_REQ_DFU_UPLOAD:
94- /* state transition if less data then requested */
95- f_dfu->blk_seq_num = w_value;
96- value = handle_upload(req, len);
97- if (value >= 0 && value < len)
98- f_dfu->dfu_state = DFU_STATE_dfuIDLE;
99+ if (ctrl->bRequestType == USB_DIR_IN) {
100+ /* state transition if less data then requested */
101+ f_dfu->blk_seq_num = w_value;
102+ value = handle_upload(req, len);
103+ if (value >= 0 && value < len)
104+ f_dfu->dfu_state = DFU_STATE_dfuIDLE;
105+ }
106 break;
107 case USB_REQ_DFU_ABORT:
108 f_dfu->dfu_state = DFU_STATE_dfuIDLE;
109@@ -593,6 +609,8 @@ dfu_handle(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
110 int value = 0;
111 u8 req_type = ctrl->bRequestType & USB_TYPE_MASK;
112
113+ len = len > DFU_USB_BUFSIZ ? DFU_USB_BUFSIZ : len;
114+
115 debug("w_value: 0x%x len: 0x%x\n", w_value, len);
116 debug("req_type: 0x%x ctrl->bRequest: 0x%x f_dfu->dfu_state: 0x%x\n",
117 req_type, ctrl->bRequest, f_dfu->dfu_state);
118@@ -612,7 +630,7 @@ dfu_handle(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
119 value = dfu_state[f_dfu->dfu_state] (f_dfu, ctrl, gadget, req);
120
121 if (value >= 0) {
122- req->length = value;
123+ req->length = value > DFU_USB_BUFSIZ ? DFU_USB_BUFSIZ : value;
124 req->zero = value < len;
125 value = usb_ep_queue(gadget->ep0, req, 0);
126 if (value < 0) {
127--
1282.32.0
129
diff --git a/meta/recipes-bsp/u-boot/files/CVE-2022-2347_2.patch b/meta/recipes-bsp/u-boot/files/CVE-2022-2347_2.patch
new file mode 100644
index 0000000000..708c7923d2
--- /dev/null
+++ b/meta/recipes-bsp/u-boot/files/CVE-2022-2347_2.patch
@@ -0,0 +1,66 @@
1From 0f465b3e81baa095b62a154a739c5378285526db Mon Sep 17 00:00:00 2001
2From: Hugo SIMELIERE <hsimeliere.opensource@witekio.com>
3Date: Wed, 30 Nov 2022 09:29:16 +0100
4Subject: [PATCH 2/2] usb: gadget: dfu: Fix check of transfer direction
5
6Commit fbce985e28eaca3af82afecc11961aadaf971a7e to fix CVE-2022-2347
7blocks DFU usb requests.
8The verification of the transfer direction was done by an equality
9but it is a bit mask.
10
11Signed-off-by: Hugo SIMELIERE <hsimeliere.opensource@witekio.com>
12Reviewed-by: Fabio Estevam <festevam@denx.de>
13Reviewed-by: Sultan Qasim Khan <sultan.qasimkhan@nccgroup.com>
14Reviewed-by: Marek Vasut <marex@denx.de>
15Tested-by: Marek Vasut <marex@denx.de>
16
17CVE: CVE-2022-2347
18Upstream-Status: Backport [14dc0ab138988a8e45ffa086444ec8db48b3f103]
19Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com>
20---
21 drivers/usb/gadget/f_dfu.c | 8 ++++----
22 1 file changed, 4 insertions(+), 4 deletions(-)
23
24diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c
25index 33ef62f8ba..44877df4ec 100644
26--- a/drivers/usb/gadget/f_dfu.c
27+++ b/drivers/usb/gadget/f_dfu.c
28@@ -325,7 +325,7 @@ static int state_dfu_idle(struct f_dfu *f_dfu,
29
30 switch (ctrl->bRequest) {
31 case USB_REQ_DFU_DNLOAD:
32- if (ctrl->bRequestType == USB_DIR_OUT) {
33+ if (!(ctrl->bRequestType & USB_DIR_IN)) {
34 if (len == 0) {
35 f_dfu->dfu_state = DFU_STATE_dfuERROR;
36 value = RET_STALL;
37@@ -337,7 +337,7 @@ static int state_dfu_idle(struct f_dfu *f_dfu,
38 }
39 break;
40 case USB_REQ_DFU_UPLOAD:
41- if (ctrl->bRequestType == USB_DIR_IN) {
42+ if (ctrl->bRequestType & USB_DIR_IN) {
43 f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE;
44 f_dfu->blk_seq_num = 0;
45 value = handle_upload(req, len);
46@@ -436,7 +436,7 @@ static int state_dfu_dnload_idle(struct f_dfu *f_dfu,
47
48 switch (ctrl->bRequest) {
49 case USB_REQ_DFU_DNLOAD:
50- if (ctrl->bRequestType == USB_DIR_OUT) {
51+ if (!(ctrl->bRequestType & USB_DIR_IN)) {
52 f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
53 f_dfu->blk_seq_num = w_value;
54 value = handle_dnload(gadget, len);
55@@ -527,7 +527,7 @@ static int state_dfu_upload_idle(struct f_dfu *f_dfu,
56
57 switch (ctrl->bRequest) {
58 case USB_REQ_DFU_UPLOAD:
59- if (ctrl->bRequestType == USB_DIR_IN) {
60+ if (ctrl->bRequestType & USB_DIR_IN) {
61 /* state transition if less data then requested */
62 f_dfu->blk_seq_num = w_value;
63 value = handle_upload(req, len);
64--
652.32.0
66
diff --git a/meta/recipes-bsp/u-boot/files/CVE-2022-30790.patch b/meta/recipes-bsp/u-boot/files/CVE-2022-30790.patch
new file mode 100644
index 0000000000..e67cf391a8
--- /dev/null
+++ b/meta/recipes-bsp/u-boot/files/CVE-2022-30790.patch
@@ -0,0 +1,149 @@
1From 1817c3824a08bbad7fd2fbae1a6e73be896e8e5e Mon Sep 17 00:00:00 2001
2From: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
3Date: Fri, 14 Oct 2022 19:43:39 +0200
4Subject: [PATCH] net: (actually/better) deal with CVE-2022-{30790,30552}
5
6I hit a strange problem with v2022.10: Sometimes my tftp transfer
7would seemingly just hang. It only happened for some files. Moreover,
8changing tftpblocksize from 65464 to 65460 or 65000 made it work again
9for all the files I tried. So I started suspecting it had something to
10do with the file sizes and in particular the way the tftp blocks get
11fragmented and reassembled.
12
13v2022.01 showed no problems with any of the files or any value of
14tftpblocksize.
15
16Looking at what had changed in net.c or tftp.c since January showed
17only one remotely interesting thing, b85d130ea0ca.
18
19So I fired up wireshark on my host to see if somehow one of the
20packets would be too small. But no, with both v2022.01 and v2022.10,
21the exact same sequence of packets were sent, all but the last of size
221500, and the last being 1280 bytes.
23
24But then it struck me that 1280 is 5*256, so one of the two bytes
25on-the-wire is 0 and the other is 5, and when then looking at the code
26again the lack of endianness conversion becomes obvious. [ntohs is
27both applied to ip->ip_off just above, as well as to ip->ip_len just a
28little further down when the "len" is actually computed].
29
30IOWs the current code would falsely reject any packet which happens to
31be a multiple of 256 bytes in size, breaking tftp transfers somewhat
32randomly, and if it did get one of those "malicious" packets with
33ip_len set to, say, 27, it would be seen by this check as being 6912
34and hence not rejected.
35
36====
37
38Now, just adding the missing ntohs() would make my initial problem go
39away, in that I can now download the file where the last fragment ends
40up being 1280 bytes. But there's another bug in the code and/or
41analysis: The right-hand side is too strict, in that it is ok for the
42last fragment not to have a multiple of 8 bytes as payload - it really
43must be ok, because nothing in the IP spec says that IP datagrams must
44have a multiple of 8 bytes as payload. And comments in the code also
45mention this.
46
47To fix that, replace the comparison with <= IP_HDR_SIZE and add
48another check that len is actually a multiple of 8 when the "more
49fragments" bit is set - which it necessarily is for the case where
50offset8 ends up being 0, since we're only called when
51
52 (ip_off & (IP_OFFS | IP_FLAGS_MFRAG)).
53
54====
55
56So, does this fix CVE-2022-30790 for real? It certainly correctly
57rejects the POC code which relies on sending a packet of size 27 with
58the MFRAG flag set. Can the attack be carried out with a size 27
59packet that doesn't set MFRAG (hence must set a non-zero fragment
60offset)? I dunno. If we get a packet without MFRAG, we update
61h->last_byte in the hole we've found to be start+len, hence we'd enter
62one of
63
64 if ((h >= thisfrag) && (h->last_byte <= start + len)) {
65
66or
67
68 } else if (h->last_byte <= start + len) {
69
70and thus won't reach any of the
71
72 /* overlaps with initial part of the hole: move this hole */
73 newh = thisfrag + (len / 8);
74
75 /* fragment sits in the middle: split the hole */
76 newh = thisfrag + (len / 8);
77
78IOW these division are now guaranteed to be exact, and thus I think
79the scenario in CVE-2022-30790 cannot happen anymore.
80
81====
82
83However, there's a big elephant in the room, which has always been
84spelled out in the comments, and which makes me believe that one can
85still cause mayhem even with packets whose payloads are all 8-byte
86aligned:
87
88 This code doesn't deal with a fragment that overlaps with two
89 different holes (thus being a superset of a previously-received
90 fragment).
91
92Suppose each character below represents 8 bytes, with D being already
93received data, H being a hole descriptor (struct hole), h being
94non-populated chunks, and P representing where the payload of a just
95received packet should go:
96
97 DDDHhhhhDDDDHhhhDDDD
98 PPPPPPPPP
99
100I'm pretty sure in this case we'd end up with h being the first hole,
101enter the simple
102
103 } else if (h->last_byte <= start + len) {
104 /* overlaps with final part of the hole: shorten this hole */
105 h->last_byte = start;
106
107case, and thus in the memcpy happily overwrite the second H with our
108chosen payload. This is probably worth fixing...
109
110Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
111
112CVE: CVE-2022-30790
113Upstream-Status: Backport [1817c3824a08bbad7fd2fbae1a6e73be896e8e5e]
114Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com>
115---
116 net/net.c | 10 +++++++++-
117 1 file changed, 9 insertions(+), 1 deletion(-)
118
119diff --git a/net/net.c b/net/net.c
120index 434c3b411e..987c25931e 100644
121--- a/net/net.c
122+++ b/net/net.c
123@@ -924,7 +924,11 @@ static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp)
124 int offset8, start, len, done = 0;
125 u16 ip_off = ntohs(ip->ip_off);
126
127- if (ip->ip_len < IP_MIN_FRAG_DATAGRAM_SIZE)
128+ /*
129+ * Calling code already rejected <, but we don't have to deal
130+ * with an IP fragment with no payload.
131+ */
132+ if (ntohs(ip->ip_len) <= IP_HDR_SIZE)
133 return NULL;
134
135 /* payload starts after IP header, this fragment is in there */
136@@ -934,6 +938,10 @@ static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp)
137 start = offset8 * 8;
138 len = ntohs(ip->ip_len) - IP_HDR_SIZE;
139
140+ /* All but last fragment must have a multiple-of-8 payload. */
141+ if ((len & 7) && (ip_off & IP_FLAGS_MFRAG))
142+ return NULL;
143+
144 if (start + len > IP_MAXUDP) /* fragment extends too far */
145 return NULL;
146
147--
1482.25.1
149
diff --git a/meta/recipes-bsp/u-boot/u-boot_2022.01.bb b/meta/recipes-bsp/u-boot/u-boot_2022.01.bb
index cd40ad1a7d..62ebe40cb6 100644
--- a/meta/recipes-bsp/u-boot/u-boot_2022.01.bb
+++ b/meta/recipes-bsp/u-boot/u-boot_2022.01.bb
@@ -8,6 +8,9 @@ SRC_URI += " file://0001-riscv32-Use-double-float-ABI-for-rv32.patch \
8 file://0001-net-Check-for-the-minimum-IP-fragmented-datagram-siz.patch \ 8 file://0001-net-Check-for-the-minimum-IP-fragmented-datagram-siz.patch \
9 file://0001-fs-squashfs-Use-kcalloc-when-relevant.patch \ 9 file://0001-fs-squashfs-Use-kcalloc-when-relevant.patch \
10 file://0001-CVE-2022-30767.patch \ 10 file://0001-CVE-2022-30767.patch \
11 file://CVE-2022-30790.patch \
12 file://CVE-2022-2347_1.patch \
13 file://CVE-2022-2347_2.patch \
11 " 14 "
12 15
13DEPENDS += "bc-native dtc-native python3-setuptools-native" 16DEPENDS += "bc-native dtc-native python3-setuptools-native"