From 6ca708e5c377edcaaec9f45c90330c4826cba14c Mon Sep 17 00:00:00 2001 From: Ying Fang Date: Fri, 22 May 2020 11:13:22 +0800 Subject: [PATCH 1/3] arm: drop redunt patch Drop the redunt patch: ARM-KVM-Check-KVM_CAP_ARM_IRQ_LINE_LAYOUT_2-for-smp_.patch Signed-off-by: Ying Fang --- ...M_CAP_ARM_IRQ_LINE_LAYOUT_2-for-smp_.patch | 61 ------------------- 1 file changed, 61 deletions(-) delete mode 100644 ARM-KVM-Check-KVM_CAP_ARM_IRQ_LINE_LAYOUT_2-for-smp_.patch diff --git a/ARM-KVM-Check-KVM_CAP_ARM_IRQ_LINE_LAYOUT_2-for-smp_.patch b/ARM-KVM-Check-KVM_CAP_ARM_IRQ_LINE_LAYOUT_2-for-smp_.patch deleted file mode 100644 index 5727a1d..0000000 --- a/ARM-KVM-Check-KVM_CAP_ARM_IRQ_LINE_LAYOUT_2-for-smp_.patch +++ /dev/null @@ -1,61 +0,0 @@ -From f3c1fc4dce1582ccc1754899d5149d233e8629ff Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 3 Oct 2019 17:46:40 +0200 -Subject: [PATCH 3/3] ARM: KVM: Check KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 for - smp_cpus > 256 - -Host kernel within [4.18, 5.3] report an erroneous KVM_MAX_VCPUS=512 -for ARM. The actual capability to instantiate more than 256 vcpus -was fixed in 5.4 with the upgrade of the KVM_IRQ_LINE ABI to support -vcpu id encoded on 12 bits instead of 8 and a redistributor consuming -a single KVM IO device instead of 2. - -So let's check this capability when attempting to use more than 256 -vcpus within any ARM kvm accelerated machine. - -Signed-off-by: Eric Auger -Reviewed-by: Richard Henderson -Reviewed-by: Andrew Jones -Acked-by: Marc Zyngier -Message-id: 20191003154640.22451-4-eric.auger@redhat.com -Signed-off-by: Peter Maydell -(cherry-picked from commit fff9f5558d0e0813d4f80bfe1602acf225eca4fd) -[yu: Use the legacy smp_cpus instead of ms->smp.cpus, as we don't have - struct CpuTopology in MachineState at that time. See commit - edeeec911702 for details.] -Signed-off-by: Zenghui Yu ---- - target/arm/kvm.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/target/arm/kvm.c b/target/arm/kvm.c -index f60185ad..383423c4 100644 ---- a/target/arm/kvm.c -+++ b/target/arm/kvm.c -@@ -174,6 +174,7 @@ int kvm_arm_get_max_vm_ipa_size(MachineState *ms) - - int kvm_arch_init(MachineState *ms, KVMState *s) - { -+ int ret = 0; - /* For ARM interrupt delivery is always asynchronous, - * whether we are using an in-kernel VGIC or not. - */ -@@ -187,7 +188,14 @@ int kvm_arch_init(MachineState *ms, KVMState *s) - - cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE); - -- return 0; -+ if (smp_cpus > 256 && -+ !kvm_check_extension(s, KVM_CAP_ARM_IRQ_LINE_LAYOUT_2)) { -+ error_report("Using more than 256 vcpus requires a host kernel " -+ "with KVM_CAP_ARM_IRQ_LINE_LAYOUT_2"); -+ ret = -EINVAL; -+ } -+ -+ return ret; - } - - unsigned long kvm_arch_vcpu_id(CPUState *cpu) --- -2.19.1 - -- Gitee From ae206fbfdc338cb11350168c086af5c3067de870 Mon Sep 17 00:00:00 2001 From: Ying Fang Date: Fri, 22 May 2020 11:17:40 +0800 Subject: [PATCH 2/3] CVE: Fix CVE-2019-15890 this patch fix CVE-2019-15890, upstream patch url: https://gitlab.freedesktop.org/slirp/libslirp/commit/c5927943 Signed-off-by: Ying Fang --- ip_reass-Fix-use-after-free.patch | 40 +++++++++++++++++++++++++++++++ qemu.spec | 4 ++++ 2 files changed, 44 insertions(+) create mode 100644 ip_reass-Fix-use-after-free.patch diff --git a/ip_reass-Fix-use-after-free.patch b/ip_reass-Fix-use-after-free.patch new file mode 100644 index 0000000..b26e8af --- /dev/null +++ b/ip_reass-Fix-use-after-free.patch @@ -0,0 +1,40 @@ +From 63b07dfe20a0d4971b0929d27359f478ba2d816b Mon Sep 17 00:00:00 2001 +From: Samuel Thibault +Date: Fri, 22 May 2020 10:52:55 +0800 +Subject: [PATCH] ip_reass: Fix use after free + +Using ip_deq after m_free might read pointers from an allocation reuse. + +This would be difficult to exploit, but that is still related with +CVE-2019-14378 which generates fragmented IP packets that would trigger this +issue and at least produce a DoS. +Signed-off-by: Samuel Thibault's avatarSamuel Thibault + +diff --git a/slirp/src/ip_input.c b/slirp/src/ip_input.c +index 8c75d91..c07d7d4 100644 +--- a/slirp/src/ip_input.c ++++ b/slirp/src/ip_input.c +@@ -292,6 +292,7 @@ static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp) + */ + while (q != (struct ipasfrag *)&fp->frag_link && + ip->ip_off + ip->ip_len > q->ipf_off) { ++ struct ipasfrag *prev; + i = (ip->ip_off + ip->ip_len) - q->ipf_off; + if (i < q->ipf_len) { + q->ipf_len -= i; +@@ -299,9 +300,10 @@ static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp) + m_adj(dtom(slirp, q), i); + break; + } ++ prev = q; + q = q->ipf_next; +- m_free(dtom(slirp, q->ipf_prev)); +- ip_deq(q->ipf_prev); ++ ip_deq(prev); ++ m_free(dtom(slirp, prev)); + } + + insert: +-- +1.8.3.1 + diff --git a/qemu.spec b/qemu.spec index c6d487b..68cc7d6 100644 --- a/qemu.spec +++ b/qemu.spec @@ -165,6 +165,7 @@ Patch0152: arm-virt-Support-CPU-cold-plug.patch Patch0153: ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch Patch0154: ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch Patch0155: slirp-tftp-restrict-relative-path-access.patch +Patch0156: ip_reass-Fix-use-after-free.patch BuildRequires: flex BuildRequires: bison @@ -510,6 +511,9 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Fri May 22 2020 Huawei Technologies Co., Ltd. +- ip_reass: Fix use after free + * Fri May 15 2020 Huawei Technologies Co., Ltd. - ide: Fix incorrect handling of some PRDTs in ide_dma_cb() - ati-vga: Fix checks in ati_2d_blt() to avoid crash -- Gitee From 26cae7937deae4cb7c3a800fa586fcd4ae0922b3 Mon Sep 17 00:00:00 2001 From: Leo Fang Date: Fri, 22 May 2020 12:29:21 +0800 Subject: [PATCH 3/3] CVE: Fix CVE-2018-19665 upstream url: https://patchwork.kernel.org/patch/10688527/ Signed-off-by: Ying Fang --- ...pe-for-length-parameters-instead-of-.patch | 794 ++++++++++++++++++ qemu.spec | 2 + 2 files changed, 796 insertions(+) create mode 100644 bt-use-size_t-type-for-length-parameters-instead-of-.patch diff --git a/bt-use-size_t-type-for-length-parameters-instead-of-.patch b/bt-use-size_t-type-for-length-parameters-instead-of-.patch new file mode 100644 index 0000000..2005979 --- /dev/null +++ b/bt-use-size_t-type-for-length-parameters-instead-of-.patch @@ -0,0 +1,794 @@ +From f9ab92373813cfccd31f29c0d963232f65cb5f88 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Fri, 22 May 2020 12:22:26 +0800 +Subject: [PATCH] bt: use size_t type for length parameters instead of int + +From: Prasad J Pandit + +The length parameter values are not negative, thus use an unsigned +type 'size_t' for them. Many routines pass 'len' values to memcpy(3) +calls. If it was negative, it could lead to memory corruption issues. +Add check to avoid it. + +Reported-by: Arash TC +Signed-off-by: Prasad J Pandit + +diff --git a/bt-host.c b/bt-host.c +index 2f8f631..b73a44d 100644 +--- a/bt-host.c ++++ b/bt-host.c +@@ -43,7 +43,7 @@ struct bt_host_hci_s { + }; + + static void bt_host_send(struct HCIInfo *hci, +- int type, const uint8_t *data, int len) ++ int type, const uint8_t *data, size_t len) + { + struct bt_host_hci_s *s = (struct bt_host_hci_s *) hci; + uint8_t pkt = type; +@@ -63,17 +63,17 @@ static void bt_host_send(struct HCIInfo *hci, + } + } + +-static void bt_host_cmd(struct HCIInfo *hci, const uint8_t *data, int len) ++static void bt_host_cmd(struct HCIInfo *hci, const uint8_t *data, size_t len) + { + bt_host_send(hci, HCI_COMMAND_PKT, data, len); + } + +-static void bt_host_acl(struct HCIInfo *hci, const uint8_t *data, int len) ++static void bt_host_acl(struct HCIInfo *hci, const uint8_t *data, size_t len) + { + bt_host_send(hci, HCI_ACLDATA_PKT, data, len); + } + +-static void bt_host_sco(struct HCIInfo *hci, const uint8_t *data, int len) ++static void bt_host_sco(struct HCIInfo *hci, const uint8_t *data, size_t len) + { + bt_host_send(hci, HCI_SCODATA_PKT, data, len); + } +diff --git a/bt-vhci.c b/bt-vhci.c +index 886e146..32ef1c5 100644 +--- a/bt-vhci.c ++++ b/bt-vhci.c +@@ -89,7 +89,7 @@ static void vhci_read(void *opaque) + } + + static void vhci_host_send(void *opaque, +- int type, const uint8_t *data, int len) ++ int type, const uint8_t *data, size_t len) + { + struct bt_vhci_s *s = (struct bt_vhci_s *) opaque; + #if 0 +@@ -112,6 +112,7 @@ static void vhci_host_send(void *opaque, + static uint8_t buf[4096]; + + buf[0] = type; ++ assert(len < sizeof(buf)); + memcpy(buf + 1, data, len); + + while (write(s->fd, buf, len + 1) < 0) +@@ -124,13 +125,13 @@ static void vhci_host_send(void *opaque, + } + + static void vhci_out_hci_packet_event(void *opaque, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + vhci_host_send(opaque, HCI_EVENT_PKT, data, len); + } + + static void vhci_out_hci_packet_acl(void *opaque, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + vhci_host_send(opaque, HCI_ACLDATA_PKT, data, len); + } +diff --git a/hw/bt/core.c b/hw/bt/core.c +index dfb196e..f548b3d 100644 +--- a/hw/bt/core.c ++++ b/hw/bt/core.c +@@ -44,7 +44,7 @@ static void bt_dummy_lmp_disconnect_master(struct bt_link_s *link) + } + + static void bt_dummy_lmp_acl_resp(struct bt_link_s *link, +- const uint8_t *data, int start, int len) ++ const uint8_t *data, int start, size_t len) + { + error_report("%s: stray ACL response PDU, fixme", __func__); + exit(-1); +diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c +index 3d60654..f7a74c0 100644 +--- a/hw/bt/hci-csr.c ++++ b/hw/bt/hci-csr.c +@@ -103,7 +103,7 @@ static inline void csrhci_fifo_wake(struct csrhci_s *s) + } + + #define csrhci_out_packetz(s, len) memset(csrhci_out_packet(s, len), 0, len) +-static uint8_t *csrhci_out_packet(struct csrhci_s *s, int len) ++static uint8_t *csrhci_out_packet(struct csrhci_s *s, size_t len) + { + int off = s->out_start + s->out_len; + +@@ -112,14 +112,14 @@ static uint8_t *csrhci_out_packet(struct csrhci_s *s, int len) + + if (off < FIFO_LEN) { + if (off + len > FIFO_LEN && (s->out_size = off + len) > FIFO_LEN * 2) { +- error_report("%s: can't alloc %i bytes", __func__, len); ++ error_report("%s: can't alloc %zu bytes", __func__, len); + exit(-1); + } + return s->outfifo + off; + } + + if (s->out_len > s->out_size) { +- error_report("%s: can't alloc %i bytes", __func__, len); ++ error_report("%s: can't alloc %zu bytes", __func__, len); + exit(-1); + } + +@@ -127,7 +127,7 @@ static uint8_t *csrhci_out_packet(struct csrhci_s *s, int len) + } + + static inline uint8_t *csrhci_out_packet_csr(struct csrhci_s *s, +- int type, int len) ++ int type, size_t len) + { + uint8_t *ret = csrhci_out_packetz(s, len + 2); + +@@ -138,7 +138,7 @@ static inline uint8_t *csrhci_out_packet_csr(struct csrhci_s *s, + } + + static inline uint8_t *csrhci_out_packet_event(struct csrhci_s *s, +- int evt, int len) ++ int evt, size_t len) + { + uint8_t *ret = csrhci_out_packetz(s, + len + 1 + sizeof(struct hci_event_hdr)); +@@ -151,7 +151,7 @@ static inline uint8_t *csrhci_out_packet_event(struct csrhci_s *s, + } + + static void csrhci_in_packet_vendor(struct csrhci_s *s, int ocf, +- uint8_t *data, int len) ++ uint8_t *data, size_t len) + { + int offset; + uint8_t *rpkt; +@@ -320,18 +320,18 @@ static int csrhci_write(struct Chardev *chr, + struct csrhci_s *s = (struct csrhci_s *)chr; + int total = 0; + +- if (!s->enable) ++ if (!s->enable || len <= 0) + return 0; + + for (;;) { + int cnt = MIN(len, s->in_needed - s->in_len); +- if (cnt) { +- memcpy(s->inpkt + s->in_len, buf, cnt); +- s->in_len += cnt; +- buf += cnt; +- len -= cnt; +- total += cnt; +- } ++ assert(cnt > 0); ++ ++ memcpy(s->inpkt + s->in_len, buf, cnt); ++ s->in_len += cnt; ++ buf += cnt; ++ len -= cnt; ++ total += cnt; + + if (s->in_len < s->in_needed) { + break; +@@ -363,7 +363,7 @@ static int csrhci_write(struct Chardev *chr, + } + + static void csrhci_out_hci_packet_event(void *opaque, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + struct csrhci_s *s = (struct csrhci_s *) opaque; + uint8_t *pkt = csrhci_out_packet(s, (len + 2) & ~1); /* Align */ +@@ -375,7 +375,7 @@ static void csrhci_out_hci_packet_event(void *opaque, + } + + static void csrhci_out_hci_packet_acl(void *opaque, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + struct csrhci_s *s = (struct csrhci_s *) opaque; + uint8_t *pkt = csrhci_out_packet(s, (len + 2) & ~1); /* Align */ +diff --git a/hw/bt/hci.c b/hw/bt/hci.c +index c7958f6..9c4f957 100644 +--- a/hw/bt/hci.c ++++ b/hw/bt/hci.c +@@ -31,7 +31,7 @@ + + struct bt_hci_s { + uint8_t *(*evt_packet)(void *opaque); +- void (*evt_submit)(void *opaque, int len); ++ void (*evt_submit)(void *opaque, size_t len); + void *opaque; + uint8_t evt_buf[256]; + +@@ -61,7 +61,7 @@ struct bt_hci_s { + struct bt_hci_master_link_s { + struct bt_link_s *link; + void (*lmp_acl_data)(struct bt_link_s *link, +- const uint8_t *data, int start, int len); ++ const uint8_t *data, int start, size_t len); + QEMUTimer *acl_mode_timer; + } handle[HCI_HANDLES_MAX]; + uint32_t role_bmp; +@@ -433,7 +433,7 @@ static const uint8_t bt_event_reserved_mask[8] = { + }; + + +-static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len) ++static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, size_t len) + { + } + +@@ -451,13 +451,13 @@ struct HCIInfo null_hci = { + + + static inline uint8_t *bt_hci_event_start(struct bt_hci_s *hci, +- int evt, int len) ++ int evt, size_t len) + { + uint8_t *packet, mask; + int mask_byte; + + if (len > 255) { +- error_report("%s: HCI event params too long (%ib)", __func__, len); ++ error_report("%s: HCI event params too long (%zub)", __func__, len); + exit(-1); + } + +@@ -474,7 +474,7 @@ static inline uint8_t *bt_hci_event_start(struct bt_hci_s *hci, + } + + static inline void bt_hci_event(struct bt_hci_s *hci, int evt, +- void *params, int len) ++ void *params, size_t len) + { + uint8_t *packet = bt_hci_event_start(hci, evt, len); + +@@ -499,7 +499,7 @@ static inline void bt_hci_event_status(struct bt_hci_s *hci, int status) + } + + static inline void bt_hci_event_complete(struct bt_hci_s *hci, +- void *ret, int len) ++ void *ret, size_t len) + { + uint8_t *packet = bt_hci_event_start(hci, EVT_CMD_COMPLETE, + len + EVT_CMD_COMPLETE_SIZE); +@@ -1476,7 +1476,7 @@ static inline void bt_hci_event_num_comp_pkts(struct bt_hci_s *hci, + } + + static void bt_submit_hci(struct HCIInfo *info, +- const uint8_t *data, int length) ++ const uint8_t *data, size_t length) + { + struct bt_hci_s *hci = hci_from_info(info); + uint16_t cmd; +@@ -1970,7 +1970,7 @@ static void bt_submit_hci(struct HCIInfo *info, + break; + + short_hci: +- error_report("%s: HCI packet too short (%iB)", __func__, length); ++ error_report("%s: HCI packet too short (%zuB)", __func__, length); + bt_hci_event_status(hci, HCI_INVALID_PARAMETERS); + break; + } +@@ -1981,7 +1981,7 @@ static void bt_submit_hci(struct HCIInfo *info, + * know that a packet contained the last fragment of the SDU when the next + * SDU starts. */ + static inline void bt_hci_lmp_acl_data(struct bt_hci_s *hci, uint16_t handle, +- const uint8_t *data, int start, int len) ++ const uint8_t *data, int start, size_t len) + { + struct hci_acl_hdr *pkt = (void *) hci->acl_buf; + +@@ -1989,7 +1989,7 @@ static inline void bt_hci_lmp_acl_data(struct bt_hci_s *hci, uint16_t handle, + /* TODO: avoid memcpy'ing */ + + if (len + HCI_ACL_HDR_SIZE > sizeof(hci->acl_buf)) { +- error_report("%s: can't take ACL packets %i bytes long", ++ error_report("%s: can't take ACL packets %zu bytes long", + __func__, len); + return; + } +@@ -2003,7 +2003,7 @@ static inline void bt_hci_lmp_acl_data(struct bt_hci_s *hci, uint16_t handle, + } + + static void bt_hci_lmp_acl_data_slave(struct bt_link_s *btlink, +- const uint8_t *data, int start, int len) ++ const uint8_t *data, int start, size_t len) + { + struct bt_hci_link_s *link = (struct bt_hci_link_s *) btlink; + +@@ -2012,14 +2012,14 @@ static void bt_hci_lmp_acl_data_slave(struct bt_link_s *btlink, + } + + static void bt_hci_lmp_acl_data_host(struct bt_link_s *link, +- const uint8_t *data, int start, int len) ++ const uint8_t *data, int start, size_t len) + { + bt_hci_lmp_acl_data(hci_from_device(link->host), + link->handle, data, start, len); + } + + static void bt_submit_acl(struct HCIInfo *info, +- const uint8_t *data, int length) ++ const uint8_t *data, size_t length) + { + struct bt_hci_s *hci = hci_from_info(info); + uint16_t handle; +@@ -2027,7 +2027,7 @@ static void bt_submit_acl(struct HCIInfo *info, + struct bt_link_s *link; + + if (length < HCI_ACL_HDR_SIZE) { +- error_report("%s: ACL packet too short (%iB)", __func__, length); ++ error_report("%s: ACL packet too short (%zuB)", __func__, length); + return; + } + +@@ -2045,7 +2045,7 @@ static void bt_submit_acl(struct HCIInfo *info, + handle &= ~HCI_HANDLE_OFFSET; + + if (datalen > length) { +- error_report("%s: ACL packet too short (%iB < %iB)", ++ error_report("%s: ACL packet too short (%zuB < %iB)", + __func__, length, datalen); + return; + } +@@ -2087,7 +2087,7 @@ static void bt_submit_acl(struct HCIInfo *info, + } + + static void bt_submit_sco(struct HCIInfo *info, +- const uint8_t *data, int length) ++ const uint8_t *data, size_t length) + { + struct bt_hci_s *hci = hci_from_info(info); + uint16_t handle; +@@ -2106,7 +2106,7 @@ static void bt_submit_sco(struct HCIInfo *info, + } + + if (datalen > length) { +- error_report("%s: SCO packet too short (%iB < %iB)", ++ error_report("%s: SCO packet too short (%zuB < %iB)", + __func__, length, datalen); + return; + } +@@ -2127,7 +2127,7 @@ static uint8_t *bt_hci_evt_packet(void *opaque) + return s->evt_buf; + } + +-static void bt_hci_evt_submit(void *opaque, int len) ++static void bt_hci_evt_submit(void *opaque, size_t len) + { + /* TODO: notify upper layer */ + struct bt_hci_s *s = opaque; +diff --git a/hw/bt/hid.c b/hw/bt/hid.c +index 066ca99..fe15434 100644 +--- a/hw/bt/hid.c ++++ b/hw/bt/hid.c +@@ -95,7 +95,7 @@ struct bt_hid_device_s { + int data_type; + int intr_state; + struct { +- int len; ++ size_t len; + uint8_t buffer[1024]; + } dataother, datain, dataout, feature, intrdataout; + enum { +@@ -168,7 +168,7 @@ static void bt_hid_disconnect(struct bt_hid_device_s *s) + } + + static void bt_hid_send_data(struct bt_l2cap_conn_params_s *ch, int type, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + uint8_t *pkt, hdr = (BT_DATA << 4) | type; + int plen; +@@ -189,7 +189,7 @@ static void bt_hid_send_data(struct bt_l2cap_conn_params_s *ch, int type, + } + + static void bt_hid_control_transaction(struct bt_hid_device_s *s, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + uint8_t type, parameter; + int rlen, ret = -1; +@@ -361,7 +361,7 @@ static void bt_hid_control_transaction(struct bt_hid_device_s *s, + bt_hid_send_handshake(s, ret); + } + +-static void bt_hid_control_sdu(void *opaque, const uint8_t *data, int len) ++static void bt_hid_control_sdu(void *opaque, const uint8_t *data, size_t len) + { + struct bt_hid_device_s *hid = opaque; + +@@ -387,7 +387,7 @@ static void bt_hid_datain(HIDState *hs) + hid->datain.buffer, hid->datain.len); + } + +-static void bt_hid_interrupt_sdu(void *opaque, const uint8_t *data, int len) ++static void bt_hid_interrupt_sdu(void *opaque, const uint8_t *data, size_t len) + { + struct bt_hid_device_s *hid = opaque; + +diff --git a/hw/bt/l2cap.c b/hw/bt/l2cap.c +index d67098a..2f70a03 100644 +--- a/hw/bt/l2cap.c ++++ b/hw/bt/l2cap.c +@@ -31,10 +31,10 @@ struct l2cap_instance_s { + int role; + + uint8_t frame_in[65535 + L2CAP_HDR_SIZE] __attribute__ ((aligned (4))); +- int frame_in_len; ++ uint32_t frame_in_len; + + uint8_t frame_out[65535 + L2CAP_HDR_SIZE] __attribute__ ((aligned (4))); +- int frame_out_len; ++ uint32_t frame_out_len; + + /* Signalling channel timers. They exist per-request but we can make + * sure we have no more than one outstanding request at any time. */ +@@ -48,7 +48,7 @@ struct l2cap_instance_s { + struct bt_l2cap_conn_params_s params; + + void (*frame_in)(struct l2cap_chan_s *chan, uint16_t cid, +- const l2cap_hdr *hdr, int len); ++ const l2cap_hdr *hdr, size_t len); + int mps; + int min_mtu; + +@@ -67,7 +67,7 @@ struct l2cap_instance_s { + + /* Only flow-controlled, connection-oriented channels */ + uint8_t sdu[65536]; /* TODO: dynamically allocate */ +- int len_cur, len_total; ++ uint32_t len_cur, len_total; + int rexmit; + int monitor_timeout; + QEMUTimer *monitor_timer; +@@ -139,7 +139,7 @@ static const uint16_t l2cap_fcs16_table[256] = { + 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040, + }; + +-static uint16_t l2cap_fcs16(const uint8_t *message, int len) ++static uint16_t l2cap_fcs16(const uint8_t *message, size_t len) + { + uint16_t fcs = 0x0000; + +@@ -185,7 +185,7 @@ static void l2cap_monitor_timer_update(struct l2cap_chan_s *ch) + } + + static void l2cap_command_reject(struct l2cap_instance_s *l2cap, int id, +- uint16_t reason, const void *data, int plen) ++ uint16_t reason, const void *data, size_t plen) + { + uint8_t *pkt; + l2cap_cmd_hdr *hdr; +@@ -246,7 +246,7 @@ static void l2cap_connection_response(struct l2cap_instance_s *l2cap, + } + + static void l2cap_configuration_request(struct l2cap_instance_s *l2cap, +- int dcid, int flag, const uint8_t *data, int len) ++ int dcid, int flag, const uint8_t *data, size_t len) + { + uint8_t *pkt; + l2cap_cmd_hdr *hdr; +@@ -274,7 +274,7 @@ static void l2cap_configuration_request(struct l2cap_instance_s *l2cap, + } + + static void l2cap_configuration_response(struct l2cap_instance_s *l2cap, +- int scid, int flag, int result, const uint8_t *data, int len) ++ int scid, int flag, int result, const uint8_t *data, size_t len) + { + uint8_t *pkt; + l2cap_cmd_hdr *hdr; +@@ -321,7 +321,7 @@ static void l2cap_disconnection_response(struct l2cap_instance_s *l2cap, + } + + static void l2cap_echo_response(struct l2cap_instance_s *l2cap, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + uint8_t *pkt; + l2cap_cmd_hdr *hdr; +@@ -342,7 +342,7 @@ static void l2cap_echo_response(struct l2cap_instance_s *l2cap, + } + + static void l2cap_info_response(struct l2cap_instance_s *l2cap, int type, +- int result, const uint8_t *data, int len) ++ int result, const uint8_t *data, size_t len) + { + uint8_t *pkt; + l2cap_cmd_hdr *hdr; +@@ -365,16 +365,18 @@ static void l2cap_info_response(struct l2cap_instance_s *l2cap, int type, + l2cap->signalling_ch.params.sdu_submit(&l2cap->signalling_ch.params); + } + +-static uint8_t *l2cap_bframe_out(struct bt_l2cap_conn_params_s *parm, int len); ++static uint8_t *l2cap_bframe_out(struct bt_l2cap_conn_params_s *parm, ++ size_t len); + static void l2cap_bframe_submit(struct bt_l2cap_conn_params_s *parms); + #if 0 +-static uint8_t *l2cap_iframe_out(struct bt_l2cap_conn_params_s *parm, int len); ++static uint8_t *l2cap_iframe_out(struct bt_l2cap_conn_params_s *parm, ++ size_t len); + static void l2cap_iframe_submit(struct bt_l2cap_conn_params_s *parm); + #endif + static void l2cap_bframe_in(struct l2cap_chan_s *ch, uint16_t cid, +- const l2cap_hdr *hdr, int len); ++ const l2cap_hdr *hdr, size_t len); + static void l2cap_iframe_in(struct l2cap_chan_s *ch, uint16_t cid, +- const l2cap_hdr *hdr, int len); ++ const l2cap_hdr *hdr, size_t len); + + static int l2cap_cid_new(struct l2cap_instance_s *l2cap) + { +@@ -498,7 +500,7 @@ static void l2cap_channel_config_req_event(struct l2cap_instance_s *l2cap, + + static int l2cap_channel_config(struct l2cap_instance_s *l2cap, + struct l2cap_chan_s *ch, int flag, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + l2cap_conf_opt *opt; + l2cap_conf_opt_qos *qos; +@@ -683,7 +685,7 @@ static int l2cap_channel_config(struct l2cap_instance_s *l2cap, + } + + static void l2cap_channel_config_req_msg(struct l2cap_instance_s *l2cap, +- int flag, int cid, const uint8_t *data, int len) ++ int flag, int cid, const uint8_t *data, size_t len) + { + struct l2cap_chan_s *ch; + +@@ -715,7 +717,7 @@ static void l2cap_channel_config_req_msg(struct l2cap_instance_s *l2cap, + } + + static int l2cap_channel_config_rsp_msg(struct l2cap_instance_s *l2cap, +- int result, int flag, int cid, const uint8_t *data, int len) ++ int result, int flag, int cid, const uint8_t *data, size_t len) + { + struct l2cap_chan_s *ch; + +@@ -783,7 +785,7 @@ static void l2cap_info(struct l2cap_instance_s *l2cap, int type) + } + + static void l2cap_command(struct l2cap_instance_s *l2cap, int code, int id, +- const uint8_t *params, int len) ++ const uint8_t *params, size_t len) + { + int err; + +@@ -938,7 +940,7 @@ static void l2cap_rexmit_enable(struct l2cap_chan_s *ch, int enable) + } + + /* Command frame SDU */ +-static void l2cap_cframe_in(void *opaque, const uint8_t *data, int len) ++static void l2cap_cframe_in(void *opaque, const uint8_t *data, size_t len) + { + struct l2cap_instance_s *l2cap = opaque; + const l2cap_cmd_hdr *hdr; +@@ -966,7 +968,7 @@ static void l2cap_cframe_in(void *opaque, const uint8_t *data, int len) + } + + /* Group frame SDU */ +-static void l2cap_gframe_in(void *opaque, const uint8_t *data, int len) ++static void l2cap_gframe_in(void *opaque, const uint8_t *data, size_t len) + { + } + +@@ -977,7 +979,7 @@ static void l2cap_sframe_in(struct l2cap_chan_s *ch, uint16_t ctrl) + + /* Basic L2CAP mode Information frame */ + static void l2cap_bframe_in(struct l2cap_chan_s *ch, uint16_t cid, +- const l2cap_hdr *hdr, int len) ++ const l2cap_hdr *hdr, size_t len) + { + /* We have a full SDU, no further processing */ + ch->params.sdu_in(ch->params.opaque, hdr->data, len); +@@ -985,7 +987,7 @@ static void l2cap_bframe_in(struct l2cap_chan_s *ch, uint16_t cid, + + /* Flow Control and Retransmission mode frame */ + static void l2cap_iframe_in(struct l2cap_chan_s *ch, uint16_t cid, +- const l2cap_hdr *hdr, int len) ++ const l2cap_hdr *hdr, size_t len) + { + uint16_t fcs = lduw_le_p(hdr->data + len - 2); + +@@ -1076,7 +1078,7 @@ static void l2cap_frame_in(struct l2cap_instance_s *l2cap, + + /* "Recombination" */ + static void l2cap_pdu_in(struct l2cap_instance_s *l2cap, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + const l2cap_hdr *hdr = (void *) l2cap->frame_in; + +@@ -1123,7 +1125,7 @@ static inline void l2cap_pdu_submit(struct l2cap_instance_s *l2cap) + (l2cap->link, l2cap->frame_out, 1, l2cap->frame_out_len); + } + +-static uint8_t *l2cap_bframe_out(struct bt_l2cap_conn_params_s *parm, int len) ++static uint8_t *l2cap_bframe_out(struct bt_l2cap_conn_params_s *parm, size_t len) + { + struct l2cap_chan_s *chan = (struct l2cap_chan_s *) parm; + +@@ -1146,7 +1148,7 @@ static void l2cap_bframe_submit(struct bt_l2cap_conn_params_s *parms) + + #if 0 + /* Stub: Only used if an emulated device requests outgoing flow control */ +-static uint8_t *l2cap_iframe_out(struct bt_l2cap_conn_params_s *parm, int len) ++static uint8_t *l2cap_iframe_out(struct bt_l2cap_conn_params_s *parm, size_t len) + { + struct l2cap_chan_s *chan = (struct l2cap_chan_s *) parm; + +@@ -1291,7 +1293,7 @@ static void l2cap_lmp_disconnect_slave(struct bt_link_s *link) + } + + static void l2cap_lmp_acl_data_slave(struct bt_link_s *link, +- const uint8_t *data, int start, int len) ++ const uint8_t *data, int start, size_t len) + { + struct slave_l2cap_instance_s *l2cap = + (struct slave_l2cap_instance_s *) link; +@@ -1304,7 +1306,7 @@ static void l2cap_lmp_acl_data_slave(struct bt_link_s *link, + + /* Stub */ + static void l2cap_lmp_acl_data_host(struct bt_link_s *link, +- const uint8_t *data, int start, int len) ++ const uint8_t *data, int start, size_t len) + { + struct bt_l2cap_device_s *dev = (struct bt_l2cap_device_s *) link->host; + struct l2cap_instance_s *l2cap = +diff --git a/hw/bt/sdp.c b/hw/bt/sdp.c +index 2860d76..6bfb174 100644 +--- a/hw/bt/sdp.c ++++ b/hw/bt/sdp.c +@@ -496,7 +496,7 @@ static ssize_t sdp_svc_search_attr_get(struct bt_l2cap_sdp_state_s *sdp, + return end + 2; + } + +-static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, int len) ++static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, size_t len) + { + struct bt_l2cap_sdp_state_s *sdp = opaque; + enum bt_sdp_cmd pdu_id; +@@ -506,7 +506,7 @@ static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, int len) + int rsp_len = 0; + + if (len < 5) { +- error_report("%s: short SDP PDU (%iB).", __func__, len); ++ error_report("%s: short SDP PDU (%zuB).", __func__, len); + return; + } + +@@ -517,7 +517,7 @@ static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, int len) + len -= 5; + + if (len != plen) { +- error_report("%s: wrong SDP PDU length (%iB != %iB).", ++ error_report("%s: wrong SDP PDU length (%iB != %zuB).", + __func__, plen, len); + err = SDP_INVALID_PDU_SIZE; + goto respond; +diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c +index 670ba32..240a901 100644 +--- a/hw/usb/dev-bluetooth.c ++++ b/hw/usb/dev-bluetooth.c +@@ -265,7 +265,7 @@ static void usb_bt_fifo_reset(struct usb_hci_in_fifo_s *fifo) + } + + static void usb_bt_fifo_enqueue(struct usb_hci_in_fifo_s *fifo, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + int off = fifo->dstart + fifo->dlen; + uint8_t *buf; +@@ -274,13 +274,13 @@ static void usb_bt_fifo_enqueue(struct usb_hci_in_fifo_s *fifo, + if (off <= DFIFO_LEN_MASK) { + if (off + len > DFIFO_LEN_MASK + 1 && + (fifo->dsize = off + len) > (DFIFO_LEN_MASK + 1) * 2) { +- fprintf(stderr, "%s: can't alloc %i bytes\n", __func__, len); ++ fprintf(stderr, "%s: can't alloc %zu bytes\n", __func__, len); + exit(-1); + } + buf = fifo->data + off; + } else { + if (fifo->dlen > fifo->dsize) { +- fprintf(stderr, "%s: can't alloc %i bytes\n", __func__, len); ++ fprintf(stderr, "%s: can't alloc %zu bytes\n", __func__, len); + exit(-1); + } + buf = fifo->data + off - fifo->dsize; +@@ -319,7 +319,7 @@ static inline void usb_bt_fifo_dequeue(struct usb_hci_in_fifo_s *fifo, + + static inline void usb_bt_fifo_out_enqueue(struct USBBtState *s, + struct usb_hci_out_fifo_s *fifo, +- void (*send)(struct HCIInfo *, const uint8_t *, int), ++ void (*send)(struct HCIInfo *, const uint8_t *, size_t), + int (*complete)(const uint8_t *, int), + USBPacket *p) + { +@@ -478,7 +478,7 @@ static void usb_bt_handle_data(USBDevice *dev, USBPacket *p) + } + + static void usb_bt_out_hci_packet_event(void *opaque, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + struct USBBtState *s = (struct USBBtState *) opaque; + +@@ -489,7 +489,7 @@ static void usb_bt_out_hci_packet_event(void *opaque, + } + + static void usb_bt_out_hci_packet_acl(void *opaque, +- const uint8_t *data, int len) ++ const uint8_t *data, size_t len) + { + struct USBBtState *s = (struct USBBtState *) opaque; + +diff --git a/include/hw/bt.h b/include/hw/bt.h +index b5e11d4..bc362aa 100644 +--- a/include/hw/bt.h ++++ b/include/hw/bt.h +@@ -94,9 +94,9 @@ struct bt_device_s { + void (*lmp_disconnect_master)(struct bt_link_s *link); + void (*lmp_disconnect_slave)(struct bt_link_s *link); + void (*lmp_acl_data)(struct bt_link_s *link, const uint8_t *data, +- int start, int len); ++ int start, size_t len); + void (*lmp_acl_resp)(struct bt_link_s *link, const uint8_t *data, +- int start, int len); ++ int start, size_t len); + void (*lmp_mode_change)(struct bt_link_s *link); + + void (*handle_destroy)(struct bt_device_s *device); +@@ -148,12 +148,12 @@ struct bt_l2cap_device_s { + + struct bt_l2cap_conn_params_s { + /* Input */ +- uint8_t *(*sdu_out)(struct bt_l2cap_conn_params_s *chan, int len); ++ uint8_t *(*sdu_out)(struct bt_l2cap_conn_params_s *chan, size_t len); + void (*sdu_submit)(struct bt_l2cap_conn_params_s *chan); + int remote_mtu; + /* Output */ + void *opaque; +- void (*sdu_in)(void *opaque, const uint8_t *data, int len); ++ void (*sdu_in)(void *opaque, const uint8_t *data, size_t len); + void (*close)(void *opaque); + }; + +diff --git a/include/sysemu/bt.h b/include/sysemu/bt.h +index 2fd8c0f..df8fb63 100644 +--- a/include/sysemu/bt.h ++++ b/include/sysemu/bt.h +@@ -5,12 +5,12 @@ + + typedef struct HCIInfo { + int (*bdaddr_set)(struct HCIInfo *hci, const uint8_t *bd_addr); +- void (*cmd_send)(struct HCIInfo *hci, const uint8_t *data, int len); +- void (*sco_send)(struct HCIInfo *hci, const uint8_t *data, int len); +- void (*acl_send)(struct HCIInfo *hci, const uint8_t *data, int len); ++ void (*cmd_send)(struct HCIInfo *hci, const uint8_t *data, size_t len); ++ void (*sco_send)(struct HCIInfo *hci, const uint8_t *data, size_t len); ++ void (*acl_send)(struct HCIInfo *hci, const uint8_t *data, size_t len); + void *opaque; +- void (*evt_recv)(void *opaque, const uint8_t *data, int len); +- void (*acl_recv)(void *opaque, const uint8_t *data, int len); ++ void (*evt_recv)(void *opaque, const uint8_t *data, size_t len); ++ void (*acl_recv)(void *opaque, const uint8_t *data, size_t len); + } HCIInfo; + + /* bt-host.c */ +-- +1.8.3.1 + diff --git a/qemu.spec b/qemu.spec index 68cc7d6..7c8c416 100644 --- a/qemu.spec +++ b/qemu.spec @@ -166,6 +166,7 @@ Patch0153: ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch Patch0154: ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch Patch0155: slirp-tftp-restrict-relative-path-access.patch Patch0156: ip_reass-Fix-use-after-free.patch +Patch0157: bt-use-size_t-type-for-length-parameters-instead-of-.patch BuildRequires: flex BuildRequires: bison @@ -513,6 +514,7 @@ getent passwd qemu >/dev/null || \ %changelog * Fri May 22 2020 Huawei Technologies Co., Ltd. - ip_reass: Fix use after free +- bt: use size_t type for length parameters instead of int * Fri May 15 2020 Huawei Technologies Co., Ltd. - ide: Fix incorrect handling of some PRDTs in ide_dma_cb() -- Gitee