diff -Nru u-boot-2021.01+dfsg/debian/changelog u-boot-2021.01+dfsg/debian/changelog --- u-boot-2021.01+dfsg/debian/changelog 2021-09-21 15:55:38.000000000 +0000 +++ u-boot-2021.01+dfsg/debian/changelog 2022-11-25 14:51:54.000000000 +0000 @@ -1,3 +1,35 @@ +u-boot (2021.01+dfsg-3ubuntu0~20.04.5) focal-security; urgency=medium + + * SECURITY UPDATE: unchecked length field in DFU implementation + - debian/patches/CVE-2022-2347-pre1.patch: handle short frame result of + UPLOAD in state_dfu_idle in drivers/usb/gadget/f_dfu.c. + - debian/patches/CVE-2022-2347.patch: fix the unchecked length field in + drivers/usb/gadget/f_dfu.c. + - CVE-2022-2347 + * SECURITY UPDATE: buffer overflow via invalid packets + - debian/patches/CVE-2022-30552_30790.patch: check for the minimum IP + fragmented datagram size in include/net.h, net/net.c. + - CVE-2022-30552 + - CVE-2022-30790 + * SECURITY UPDATE: incomplete fix for CVE-2019-14196 + - debian/patches/CVE-2022-30767.patch: switch length to unsigned int in + net/nfs.c. + - CVE-2022-30767 + * SECURITY UPDATE: out of bounds write via sqfs_readdir() + - debian/patches/CVE-2022-33103.patch: prevent arbitrary code execution + in fs/squashfs/sqfs.c, include/fs.h. + - CVE-2022-33103 + * SECURITY UPDATE: heap buffer overflow in metadata reading + - debian/patches/CVE-2022-33967.patch: use kcalloc when relevant in + fs/squashfs/sqfs.c. + - CVE-2022-33967 + * SECURITY UPDATE: stack overflow in i2c md command + - debian/patches/CVE-2022-34835.patch: switch to unsigned int in + cmd/i2c.c. + - CVE-2022-34835 + + -- Marc Deslauriers Fri, 25 Nov 2022 09:51:54 -0500 + u-boot (2021.01+dfsg-3ubuntu0~20.04.4) focal; urgency=medium * Raise CPU frequency to 1.2 GHz as used in upstream U-Boot in diff -Nru u-boot-2021.01+dfsg/debian/patches/CVE-2022-2347.patch u-boot-2021.01+dfsg/debian/patches/CVE-2022-2347.patch --- u-boot-2021.01+dfsg/debian/patches/CVE-2022-2347.patch 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-2021.01+dfsg/debian/patches/CVE-2022-2347.patch 2022-11-25 14:49:44.000000000 +0000 @@ -0,0 +1,124 @@ +From fbce985e28eaca3af82afecc11961aadaf971a7e Mon Sep 17 00:00:00 2001 +From: Venkatesh Yadav Abbarapu +Date: Thu, 3 Nov 2022 09:37:48 +0530 +Subject: [PATCH] usb: gadget: dfu: Fix the unchecked length field + +DFU implementation does not bound the length field in USB +DFU download setup packets, and it does not verify that +the transfer direction. Fixing the length and transfer +direction. + +CVE-2022-2347 + +Signed-off-by: Venkatesh Yadav Abbarapu +Reviewed-by: Marek Vasut +--- + drivers/usb/gadget/f_dfu.c | 58 ++++++++++++++++++++++++-------------- + 1 file changed, 37 insertions(+), 21 deletions(-) + +diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c +index e9340ff5cb4d..33ef62f8babe 100644 +--- a/drivers/usb/gadget/f_dfu.c ++++ b/drivers/usb/gadget/f_dfu.c +@@ -321,23 +321,29 @@ static int state_dfu_idle(struct f_dfu *f_dfu, + u16 len = le16_to_cpu(ctrl->wLength); + int value = 0; + ++ len = len > DFU_USB_BUFSIZ ? DFU_USB_BUFSIZ : len; ++ + switch (ctrl->bRequest) { + case USB_REQ_DFU_DNLOAD: +- if (len == 0) { +- f_dfu->dfu_state = DFU_STATE_dfuERROR; +- value = RET_STALL; +- break; ++ if (ctrl->bRequestType == USB_DIR_OUT) { ++ if (len == 0) { ++ f_dfu->dfu_state = DFU_STATE_dfuERROR; ++ value = RET_STALL; ++ break; ++ } ++ f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC; ++ f_dfu->blk_seq_num = w_value; ++ value = handle_dnload(gadget, len); + } +- f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC; +- f_dfu->blk_seq_num = w_value; +- value = handle_dnload(gadget, len); + break; + case USB_REQ_DFU_UPLOAD: +- f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE; +- f_dfu->blk_seq_num = 0; +- value = handle_upload(req, len); +- if (value >= 0 && value < len) +- f_dfu->dfu_state = DFU_STATE_dfuIDLE; ++ if (ctrl->bRequestType == USB_DIR_IN) { ++ f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE; ++ f_dfu->blk_seq_num = 0; ++ value = handle_upload(req, len); ++ if (value >= 0 && value < len) ++ f_dfu->dfu_state = DFU_STATE_dfuIDLE; ++ } + break; + case USB_REQ_DFU_ABORT: + /* no zlp? */ +@@ -426,11 +432,15 @@ static int state_dfu_dnload_idle(struct f_dfu *f_dfu, + u16 len = le16_to_cpu(ctrl->wLength); + int value = 0; + ++ len = len > DFU_USB_BUFSIZ ? DFU_USB_BUFSIZ : len; ++ + switch (ctrl->bRequest) { + case USB_REQ_DFU_DNLOAD: +- f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC; +- f_dfu->blk_seq_num = w_value; +- value = handle_dnload(gadget, len); ++ if (ctrl->bRequestType == USB_DIR_OUT) { ++ f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC; ++ f_dfu->blk_seq_num = w_value; ++ value = handle_dnload(gadget, len); ++ } + break; + case USB_REQ_DFU_ABORT: + f_dfu->dfu_state = DFU_STATE_dfuIDLE; +@@ -513,13 +523,17 @@ static int state_dfu_upload_idle(struct f_dfu *f_dfu, + u16 len = le16_to_cpu(ctrl->wLength); + int value = 0; + ++ len = len > DFU_USB_BUFSIZ ? DFU_USB_BUFSIZ : len; ++ + switch (ctrl->bRequest) { + case USB_REQ_DFU_UPLOAD: +- /* state transition if less data then requested */ +- f_dfu->blk_seq_num = w_value; +- value = handle_upload(req, len); +- if (value >= 0 && value < len) +- f_dfu->dfu_state = DFU_STATE_dfuIDLE; ++ if (ctrl->bRequestType == USB_DIR_IN) { ++ /* state transition if less data then requested */ ++ f_dfu->blk_seq_num = w_value; ++ value = handle_upload(req, len); ++ if (value >= 0 && value < len) ++ f_dfu->dfu_state = DFU_STATE_dfuIDLE; ++ } + break; + case USB_REQ_DFU_ABORT: + f_dfu->dfu_state = DFU_STATE_dfuIDLE; +@@ -595,6 +609,8 @@ dfu_handle(struct usb_function *f, const struct usb_ctrlrequest *ctrl) + int value = 0; + u8 req_type = ctrl->bRequestType & USB_TYPE_MASK; + ++ len = len > DFU_USB_BUFSIZ ? DFU_USB_BUFSIZ : len; ++ + debug("w_value: 0x%x len: 0x%x\n", w_value, len); + debug("req_type: 0x%x ctrl->bRequest: 0x%x f_dfu->dfu_state: 0x%x\n", + req_type, ctrl->bRequest, f_dfu->dfu_state); +@@ -614,7 +630,7 @@ dfu_handle(struct usb_function *f, const struct usb_ctrlrequest *ctrl) + value = dfu_state[f_dfu->dfu_state] (f_dfu, ctrl, gadget, req); + + if (value >= 0) { +- req->length = value; ++ req->length = value > DFU_USB_BUFSIZ ? DFU_USB_BUFSIZ : value; + req->zero = value < len; + value = usb_ep_queue(gadget->ep0, req, 0); + if (value < 0) { diff -Nru u-boot-2021.01+dfsg/debian/patches/CVE-2022-2347-pre1.patch u-boot-2021.01+dfsg/debian/patches/CVE-2022-2347-pre1.patch --- u-boot-2021.01+dfsg/debian/patches/CVE-2022-2347-pre1.patch 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-2021.01+dfsg/debian/patches/CVE-2022-2347-pre1.patch 2022-11-25 14:49:37.000000000 +0000 @@ -0,0 +1,53 @@ +From 86b6a38863bebb70a65a53f93a1ffafc4a472169 Mon Sep 17 00:00:00 2001 +From: Patrick Delaunay +Date: Wed, 13 Oct 2021 17:01:37 +0200 +Subject: [PATCH] dfu: handle short frame result of UPLOAD in state_dfu_idle + +In DFU v1.1 specification [1] the DFU_UPLOAD (Short Frame) +is handled only in dfuUPLOADIDLE state: + +- Figure A.1 Interface state transition diagram + +- the state description in chapter A.2 + +A.2.3 State 2 dfuIDLE + on Receipt of the DFU_UPLOAD request,and bitCanUpload = 1 + the Next State is dfuUPLOADIDLE + +A.2.10 State 9 dfuUPLOAD-IDLE + When the length of the data transferred by the device in response + to a DFU_UPLOAD request is less than wLength. (Short frame) + the Next State is dfuIDLE + +In current code, when an UPLOAD is completely performed after the first +request (for example with wLength=200 and data read = 9), the DFU state +stay at dfuUPLOADIDLE until receiving a DFU_UPLOAD or a DFU_ABORT request +even it is unnecessary as the previous DFU_UPLOAD request already reached +the EOF. + +This patch proposes to finish the DFU uploading (don't go to dfuUPLOADIDLE) +and completes the control-read operation (go to DFU_STATE_dfuIDLE) when +the first UPLOAD response has a short frame as an end of file (EOF) +indicator even if it is not explicitly allowed in the DFU specification +but this seems logical. + +[1] https://www.usb.org/sites/default/files/DFU_1.1.pdf + +Signed-off-by: Patrick Delaunay +--- + drivers/usb/gadget/f_dfu.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c +index 4bedc7d3a190..e9340ff5cb4d 100644 +--- a/drivers/usb/gadget/f_dfu.c ++++ b/drivers/usb/gadget/f_dfu.c +@@ -336,6 +336,8 @@ static int state_dfu_idle(struct f_dfu *f_dfu, + f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE; + f_dfu->blk_seq_num = 0; + value = handle_upload(req, len); ++ if (value >= 0 && value < len) ++ f_dfu->dfu_state = DFU_STATE_dfuIDLE; + break; + case USB_REQ_DFU_ABORT: + /* no zlp? */ diff -Nru u-boot-2021.01+dfsg/debian/patches/CVE-2022-30552_30790.patch u-boot-2021.01+dfsg/debian/patches/CVE-2022-30552_30790.patch --- u-boot-2021.01+dfsg/debian/patches/CVE-2022-30552_30790.patch 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-2021.01+dfsg/debian/patches/CVE-2022-30552_30790.patch 2022-11-25 14:49:57.000000000 +0000 @@ -0,0 +1,195 @@ +From b85d130ea0cac152c21ec38ac9417b31d41b5552 Mon Sep 17 00:00:00 2001 +From: Fabio Estevam +Date: Thu, 26 May 2022 11:14:37 -0300 +Subject: [PATCH] net: Check for the minimum IP fragmented datagram size + +Nicolas Bidron and Nicolas Guigo reported the two bugs below: + +" +----------BUG 1---------- + +In compiled versions of U-Boot that define CONFIG_IP_DEFRAG, a value of +`ip->ip_len` (IP packet header's Total Length) higher than `IP_HDR_SIZE` +and strictly lower than `IP_HDR_SIZE+8` will lead to a value for `len` +comprised between `0` and `7`. This will ultimately result in a +truncated division by `8` resulting value of `0` forcing the hole +metadata and fragment to point to the same location. The subsequent +memcopy will overwrite the hole metadata with the fragment data. Through +a second fragment, this can be exploited to write to an arbitrary offset +controlled by that overwritten hole metadata value. + +This bug is only exploitable locally as it requires crafting two packets +the first of which would most likely be dropped through routing due to +its unexpectedly low Total Length. However, this bug can potentially be +exploited to root linux based embedded devices locally. + +```C +static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp) +{ + static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN); + static u16 first_hole, total_len; + struct hole *payload, *thisfrag, *h, *newh; + struct ip_udp_hdr *localip = (struct ip_udp_hdr *)pkt_buff; + uchar *indata = (uchar *)ip; + int offset8, start, len, done = 0; + u16 ip_off = ntohs(ip->ip_off); + + /* payload starts after IP header, this fragment is in there */ + payload = (struct hole *)(pkt_buff + IP_HDR_SIZE); + offset8 = (ip_off & IP_OFFS); + thisfrag = payload + offset8; + start = offset8 * 8; + len = ntohs(ip->ip_len) - IP_HDR_SIZE; +``` + +The last line of the previous excerpt from `u-boot/net/net.c` shows how +the attacker can control the value of `len` to be strictly lower than +`8` by issuing a packet with `ip_len` between `21` and `27` +(`IP_HDR_SIZE` has a value of `20`). + +Also note that `offset8` here is `0` which leads to `thisfrag = payload`. + +```C + } else if (h >= thisfrag) { + /* overlaps with initial part of the hole: move this hole */ + newh = thisfrag + (len / 8); + *newh = *h; + h = newh; + if (h->next_hole) + payload[h->next_hole].prev_hole = (h - payload); + if (h->prev_hole) + payload[h->prev_hole].next_hole = (h - payload); + else + first_hole = (h - payload); + + } else { +``` + +Lower down the same function, execution reaches the above code path. +Here, `len / 8` evaluates to `0` leading to `newh = thisfrag`. Also note +that `first_hole` here is `0` since `h` and `payload` point to the same +location. + +```C + /* finally copy this fragment and possibly return whole packet */ + memcpy((uchar *)thisfrag, indata + IP_HDR_SIZE, len); +``` + +Finally, in the above excerpt the `memcpy` overwrites the hole metadata +since `thisfrag` and `h` both point to the same location. The hole +metadata is effectively overwritten with arbitrary data from the +fragmented IP packet data. If `len` was crafted to be `6`, `last_byte`, +`next_hole`, and `prev_hole` of the `first_hole` can be controlled by +the attacker. + +Finally the arbitrary offset write occurs through a second fragment that +only needs to be crafted to write data in the hole pointed to by the +previously controlled hole metadata (`next_hole`) from the first packet. + + ### Recommendation + +Handle cases where `len` is strictly lower than 8 by preventing the +overwrite of the hole metadata during the memcpy of the fragment. This +could be achieved by either: +* Moving the location where the hole metadata is stored when `len` is +lower than `8`. +* Or outright rejecting fragmented IP datagram with a Total Length +(`ip_len`) lower than 28 bytes which is the minimum valid fragmented IP +datagram size (as defined as the minimum fragment of 8 octets in the IP +Specification Document: +[RFC791](https://datatracker.ietf.org/doc/html/rfc791) page 25). + +----------BUG 2---------- + +In compiled versions of U-Boot that define CONFIG_IP_DEFRAG, a value of +`ip->ip_len` (IP packet header's Total Length) lower than `IP_HDR_SIZE` +will lead to a negative value for `len` which will ultimately result in +a buffer overflow during the subsequent `memcpy` that uses `len` as it's +`count` parameter. + +This bug is only exploitable on local ethernet as it requires crafting +an invalid packet to include an unexpected `ip_len` value in the IP UDP +header that's lower than the minimum accepted Total Length of a packet +(21 as defined in the IP Specification Document: +[RFC791](https://datatracker.ietf.org/doc/html/rfc791)). Such packet +would in all likelihood be dropped while being routed to its final +destination through most routing equipment and as such requires the +attacker to be in a local position in order to be exploited. + +```C +static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp) +{ + static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN); + static u16 first_hole, total_len; + struct hole *payload, *thisfrag, *h, *newh; + struct ip_udp_hdr *localip = (struct ip_udp_hdr *)pkt_buff; + uchar *indata = (uchar *)ip; + int offset8, start, len, done = 0; + u16 ip_off = ntohs(ip->ip_off); + + /* payload starts after IP header, this fragment is in there */ + payload = (struct hole *)(pkt_buff + IP_HDR_SIZE); + offset8 = (ip_off & IP_OFFS); + thisfrag = payload + offset8; + start = offset8 * 8; + len = ntohs(ip->ip_len) - IP_HDR_SIZE; +``` + +The last line of the previous excerpt from `u-boot/net/net.c` shows +where the underflow to a negative `len` value occurs if `ip_len` is set +to a value strictly lower than 20 (`IP_HDR_SIZE` being 20). Also note +that in the above excerpt the `pkt_buff` buffer has a size of +`CONFIG_NET_MAXDEFRAG` which defaults to 16 KB but can range from 1KB to +64 KB depending on configurations. + +```C + /* finally copy this fragment and possibly return whole packet */ + memcpy((uchar *)thisfrag, indata + IP_HDR_SIZE, len); +``` + +In the above excerpt the `memcpy` overflows the destination by +attempting to make a copy of nearly 4 gigabytes in a buffer that's +designed to hold `CONFIG_NET_MAXDEFRAG` bytes at most which leads to a DoS. + + ### Recommendation + +Stop processing of the packet if `ip_len` is lower than 21 (as defined +by the minimum length of a data carrying datagram in the IP +Specification Document: +[RFC791](https://datatracker.ietf.org/doc/html/rfc791) page 34)." + +Add a check for ip_len lesser than 28 and stop processing the packet +in this case. + +Such a check covers the two reported bugs. + +Reported-by: Nicolas Bidron +Signed-off-by: Fabio Estevam +--- + include/net.h | 2 ++ + net/net.c | 3 +++ + 2 files changed, 5 insertions(+) + +--- a/include/net.h ++++ b/include/net.h +@@ -395,6 +395,8 @@ struct ip_hdr { + + #define IP_HDR_SIZE (sizeof(struct ip_hdr)) + ++#define IP_MIN_FRAG_DATAGRAM_SIZE (IP_HDR_SIZE + 8) ++ + /* + * Internet Protocol (IP) + UDP header. + */ +--- a/net/net.c ++++ b/net/net.c +@@ -907,6 +907,9 @@ static struct ip_udp_hdr *__net_defragme + int offset8, start, len, done = 0; + u16 ip_off = ntohs(ip->ip_off); + ++ if (ip->ip_len < IP_MIN_FRAG_DATAGRAM_SIZE) ++ return NULL; ++ + /* payload starts after IP header, this fragment is in there */ + payload = (struct hole *)(pkt_buff + IP_HDR_SIZE); + offset8 = (ip_off & IP_OFFS); diff -Nru u-boot-2021.01+dfsg/debian/patches/CVE-2022-30767.patch u-boot-2021.01+dfsg/debian/patches/CVE-2022-30767.patch --- u-boot-2021.01+dfsg/debian/patches/CVE-2022-30767.patch 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-2021.01+dfsg/debian/patches/CVE-2022-30767.patch 2022-11-25 14:50:02.000000000 +0000 @@ -0,0 +1,39 @@ +From bdbf7a05e26f3c5fd437c99e2755ffde186ddc80 Mon Sep 17 00:00:00 2001 +From: Andrea zi0Black Cappa +Date: Wed, 18 May 2022 16:30:08 +0000 +Subject: [PATCH] net: nfs: Fix CVE-2022-30767 (old CVE-2019-14196) + +This patch mitigates the vulnerability identified via CVE-2019-14196. + +The previous patch was bypassed/ineffective, and now the vulnerability +is identified via CVE-2022-30767. The patch removes the sanity check +introduced to mitigate CVE-2019-14196 since it's ineffective. +filefh3_length is changed to unsigned type integer, preventing negative +numbers from being used during comparison with positive values during +size sanity checks. + +Signed-off-by: Andrea zi0Black Cappa +--- + net/nfs.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/net/nfs.c ++++ b/net/nfs.c +@@ -57,7 +57,7 @@ static ulong nfs_timeout = NFS_TIMEOUT; + + static char dirfh[NFS_FHSIZE]; /* NFSv2 / NFSv3 file handle of directory */ + static char filefh[NFS3_FHSIZE]; /* NFSv2 / NFSv3 file handle */ +-static int filefh3_length; /* (variable) length of filefh when NFSv3 */ ++static unsigned int filefh3_length; /* (variable) length of filefh when NFSv3 */ + + static enum net_loop_state nfs_download_state; + static struct in_addr nfs_server_ip; +@@ -578,8 +578,6 @@ static int nfs_lookup_reply(uchar *pkt, + filefh3_length = ntohl(rpc_pkt.u.reply.data[1]); + if (filefh3_length > NFS3_FHSIZE) + filefh3_length = NFS3_FHSIZE; +- if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + filefh3_length) > len) +- return -NFS_RPC_DROP; + memcpy(filefh, rpc_pkt.u.reply.data + 2, filefh3_length); + } + diff -Nru u-boot-2021.01+dfsg/debian/patches/CVE-2022-33103.patch u-boot-2021.01+dfsg/debian/patches/CVE-2022-33103.patch --- u-boot-2021.01+dfsg/debian/patches/CVE-2022-33103.patch 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-2021.01+dfsg/debian/patches/CVE-2022-33103.patch 2022-11-25 14:50:52.000000000 +0000 @@ -0,0 +1,70 @@ +Backport of: + +From 2ac0baab4aff1a0b45067d0b62f00c15f4e86856 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Thu, 9 Jun 2022 16:02:06 +0200 +Subject: [PATCH] fs/squashfs: sqfs_read: Prevent arbitrary code execution + +Following Jincheng's report, an out-of-band write leading to arbitrary +code execution is possible because on one side the squashfs logic +accepts directory names up to 65535 bytes (u16), while U-Boot fs logic +accepts directory names up to 255 bytes long. + +Prevent such an exploit from happening by capping directory name sizes +to 255. Use a define for this purpose so that developers can link the +limitation to its source and eventually kill it some day by dynamically +allocating this array (if ever desired). + +Link: https://lore.kernel.org/all/CALO=DHFB+yBoXxVr5KcsK0iFdg+e7ywko4-e+72kjbcS8JBfPw@mail.gmail.com +Reported-by: Jincheng Wang +Signed-off-by: Miquel Raynal +Tested-by: Jincheng Wang +--- + fs/squashfs/sqfs.c | 8 +++++--- + include/fs.h | 4 +++- + 2 files changed, 8 insertions(+), 4 deletions(-) + +--- a/fs/squashfs/sqfs.c ++++ b/fs/squashfs/sqfs.c +@@ -973,6 +973,7 @@ int sqfs_readdir(struct fs_dir_stream *f + int i_number, offset = 0, ret; + struct fs_dirent *dent; + unsigned char *ipos; ++ u16 name_size; + + dirs = (struct squashfs_dir_stream *)fs_dirs; + if (!dirs->size) { +@@ -1055,9 +1056,10 @@ int sqfs_readdir(struct fs_dir_stream *f + return -SQFS_STOP_READDIR; + } + +- /* Set entry name */ +- strncpy(dent->name, dirs->entry->name, dirs->entry->name_size + 1); +- dent->name[dirs->entry->name_size + 1] = '\0'; ++ /* Set entry name (capped at FS_DIRENT_NAME_LEN which is a U-Boot limitation) */ ++ name_size = min_t(u16, dirs->entry->name_size + 1, FS_DIRENT_NAME_LEN - 1); ++ strncpy(dent->name, dirs->entry->name, name_size); ++ dent->name[name_size] = '\0'; + + offset = dirs->entry->name_size + 1 + SQFS_ENTRY_BASE_LENGTH; + dirs->entry_count--; +--- a/include/fs.h ++++ b/include/fs.h +@@ -137,6 +137,8 @@ int fs_size(const char *filename, loff_t + int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, + loff_t *actread); + ++#define FS_DIRENT_NAME_LEN 256 ++ + /** + * fs_write() - write file to the partition previously set by fs_set_blk_dev() + * +@@ -167,7 +169,7 @@ int fs_write(const char *filename, ulong + struct fs_dirent { + unsigned type; /* one of FS_DT_x (not a mask) */ + loff_t size; /* size in bytes */ +- char name[256]; ++ char name[FS_DIRENT_NAME_LEN]; + }; + + /* Note: fs_dir_stream should be treated as opaque to the user of fs layer */ diff -Nru u-boot-2021.01+dfsg/debian/patches/CVE-2022-33967.patch u-boot-2021.01+dfsg/debian/patches/CVE-2022-33967.patch --- u-boot-2021.01+dfsg/debian/patches/CVE-2022-33967.patch 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-2021.01+dfsg/debian/patches/CVE-2022-33967.patch 2022-11-25 14:51:09.000000000 +0000 @@ -0,0 +1,56 @@ +Backport of: + +From 7f7fb9937c6cb49dd35153bd6708872b390b0a44 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Mon, 27 Jun 2022 12:20:03 +0200 +Subject: [PATCH] fs/squashfs: Use kcalloc when relevant + +A crafted squashfs image could embed a huge number of empty metadata +blocks in order to make the amount of malloc()'d memory overflow and be +much smaller than expected. Because of this flaw, any random code +positioned at the right location in the squashfs image could be memcpy'd +from the squashfs structures into U-Boot code location while trying to +access the rearmost blocks, before being executed. + +In order to prevent this vulnerability from being exploited in eg. a +secure boot environment, let's add a check over the amount of data +that is going to be allocated. Such a check could look like: + +if (!elem_size || n > SIZE_MAX / elem_size) + return NULL; + +The right way to do it would be to enhance the calloc() implementation +but this is quite an impacting change for such a small fix. Another +solution would be to add the check before the malloc call in the +squashfs implementation, but this does not look right. So for now, let's +use the kcalloc() compatibility function from Linux, which has this +check. + +Fixes: c5100613037 ("fs/squashfs: new filesystem") +Reported-by: Tatsuhiko Yasumatsu +Signed-off-by: Miquel Raynal +Tested-by: Tatsuhiko Yasumatsu +--- + fs/squashfs/sqfs.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/squashfs/sqfs.c ++++ b/fs/squashfs/sqfs.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -725,7 +726,8 @@ static int sqfs_read_inode_table(unsigne + goto free_itb; + } + +- *inode_table = malloc(metablks_count * SQFS_METADATA_BLOCK_SIZE); ++ *inode_table = kcalloc(metablks_count, SQFS_METADATA_BLOCK_SIZE, ++ GFP_KERNEL); + if (!*inode_table) { + ret = -ENOMEM; + goto free_itb; diff -Nru u-boot-2021.01+dfsg/debian/patches/CVE-2022-34835.patch u-boot-2021.01+dfsg/debian/patches/CVE-2022-34835.patch --- u-boot-2021.01+dfsg/debian/patches/CVE-2022-34835.patch 1970-01-01 00:00:00.000000000 +0000 +++ u-boot-2021.01+dfsg/debian/patches/CVE-2022-34835.patch 2022-11-25 14:51:24.000000000 +0000 @@ -0,0 +1,116 @@ +From 8f8c04bf1ebbd2f72f1643e7ad9617dafa6e5409 Mon Sep 17 00:00:00 2001 +From: Nicolas Iooss +Date: Fri, 10 Jun 2022 14:50:25 +0000 +Subject: [PATCH] i2c: fix stack buffer overflow vulnerability in i2c md + command + +When running "i2c md 0 0 80000100", the function do_i2c_md parses the +length into an unsigned int variable named length. The value is then +moved to a signed variable: + + int nbytes = length; + #define DISP_LINE_LEN 16 + int linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; + ret = dm_i2c_read(dev, addr, linebuf, linebytes); + +On systems where integers are 32 bits wide, 0x80000100 is a negative +value to "nbytes > DISP_LINE_LEN" is false and linebytes gets assigned +0x80000100 instead of 16. + +The consequence is that the function which reads from the i2c device +(dm_i2c_read or i2c_read) is called with a 16-byte stack buffer to fill +but with a size parameter which is too large. In some cases, this could +trigger a crash. But with some i2c drivers, such as drivers/i2c/nx_i2c.c +(used with "nexell,s5pxx18-i2c" bus), the size is actually truncated to +a 16-bit integer. This is because function i2c_transfer expects an +unsigned short length. In such a case, an attacker who can control the +response of an i2c device can overwrite the return address of a function +and execute arbitrary code through Return-Oriented Programming. + +Fix this issue by using unsigned integers types in do_i2c_md. While at +it, make also alen unsigned, as signed sizes can cause vulnerabilities +when people forgot to check that they can be negative. + +Signed-off-by: Nicolas Iooss +Reviewed-by: Heiko Schocher +--- + cmd/i2c.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/cmd/i2c.c ++++ b/cmd/i2c.c +@@ -248,10 +248,10 @@ int i2c_set_bus_speed(unsigned int speed + * + * Returns the address length. + */ +-static uint get_alen(char *arg, int default_len) ++static uint get_alen(char *arg, uint default_len) + { +- int j; +- int alen; ++ uint j; ++ uint alen; + + alen = default_len; + for (j = 0; j < 8; j++) { +@@ -295,7 +295,7 @@ static int do_i2c_read(struct cmd_tbl *c + { + uint chip; + uint devaddr, length; +- int alen; ++ uint alen; + u_char *memaddr; + int ret; + #ifdef CONFIG_DM_I2C +@@ -349,7 +349,7 @@ static int do_i2c_write(struct cmd_tbl * + { + uint chip; + uint devaddr, length; +- int alen; ++ uint alen; + u_char *memaddr; + int ret; + #ifdef CONFIG_DM_I2C +@@ -517,8 +517,8 @@ static int do_i2c_md(struct cmd_tbl *cmd + { + uint chip; + uint addr, length; +- int alen; +- int j, nbytes, linebytes; ++ uint alen; ++ uint j, nbytes, linebytes; + int ret; + #ifdef CONFIG_DM_I2C + struct udevice *dev; +@@ -637,9 +637,9 @@ static int do_i2c_mw(struct cmd_tbl *cmd + { + uint chip; + ulong addr; +- int alen; ++ uint alen; + uchar byte; +- int count; ++ uint count; + int ret; + #ifdef CONFIG_DM_I2C + struct udevice *dev; +@@ -724,8 +724,8 @@ static int do_i2c_crc(struct cmd_tbl *cm + { + uint chip; + ulong addr; +- int alen; +- int count; ++ uint alen; ++ uint count; + uchar byte; + ulong crc; + ulong err; +@@ -1033,7 +1033,7 @@ static int do_i2c_loop(struct cmd_tbl *c + char *const argv[]) + { + uint chip; +- int alen; ++ uint alen; + uint addr; + uint length; + u_char bytes[16]; diff -Nru u-boot-2021.01+dfsg/debian/patches/series u-boot-2021.01+dfsg/debian/patches/series --- u-boot-2021.01+dfsg/debian/patches/series 2021-07-27 09:51:09.000000000 +0000 +++ u-boot-2021.01+dfsg/debian/patches/series 2022-11-25 14:51:18.000000000 +0000 @@ -78,3 +78,10 @@ rpi-cm4-sdhci.patch rpi-8gb-pci.patch rpi-maxargs.patch +CVE-2022-2347-pre1.patch +CVE-2022-2347.patch +CVE-2022-30552_30790.patch +CVE-2022-30767.patch +CVE-2022-33103.patch +CVE-2022-33967.patch +CVE-2022-34835.patch