Commit 8a8ca905 authored by Prasad J Pandit's avatar Prasad J Pandit Committed by zhuyanting
Browse files

bt: use size_t type for length parameters instead of int



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: default avatarArash TC <tohidi.arash@gmail.com>
Signed-off-by: default avatarPrasad J Pandit <pjp@fedoraproject.org>
parent c7d70156
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -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);
}
+4 −3
Original line number Diff line number Diff line
@@ -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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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);
+16 −16
Original line number Diff line number Diff line
@@ -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) {
        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 */
+19 −19
Original line number Diff line number Diff line
@@ -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;
Loading