Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c59c56ed authored by Andre Eisenbach's avatar Andre Eisenbach
Browse files

Do not leak eventfd's for RFCOMM/AVDT/L2CAP

Various users of fixed_queue's do not free the lists properly after
using them. As a result two event fd's leak for each fixed_queue that
is not free'd, as fixed_queue contains two semaphores.

This can lead to run-away file descriptor allocation and an eventual
hard limit leading to various undefined behaviours.

Bug: 27731859
Change-Id: If9ce64b711083bf474d217aa537220065722ad3a
parent a06b623b
Loading
Loading
Loading
Loading
+13 −21
Original line number Diff line number Diff line
@@ -350,37 +350,29 @@ tAVCT_LCB *avct_lcb_alloc(BD_ADDR bd_addr)
*******************************************************************************/
void avct_lcb_dealloc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
{
    tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
    BOOLEAN     found = FALSE;
    int         i;
    UNUSED(p_data);

    AVCT_TRACE_DEBUG("avct_lcb_dealloc %d", p_lcb->allocated);
    AVCT_TRACE_DEBUG("%s allocated: %d", __func__, p_lcb->allocated);

    for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
    {
        /* if ccb allocated and */
        if (p_ccb->allocated)
    // Check if the LCB is still referenced

    tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
    for (size_t i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
    {
            if (p_ccb->p_lcb == p_lcb)
        if (p_ccb->allocated && p_ccb->p_lcb == p_lcb)
        {
                AVCT_TRACE_DEBUG("avct_lcb_dealloc used by ccb: %d", i);
                found = TRUE;
                break;
            }
            AVCT_TRACE_DEBUG("%s LCB in use; lcb index: %d", __func__, i);
            return;
        }
    }

    if (!found)
    {
        AVCT_TRACE_DEBUG("avct_lcb_dealloc now");
    // If not, de-allocate now...

        /* clear reassembled msg buffer if in use */
    AVCT_TRACE_DEBUG("%s Freeing LCB", __func__);
    osi_free(p_lcb->p_rx_msg);
    fixed_queue_free(p_lcb->tx_q, NULL);
    memset(p_lcb, 0, sizeof(tAVCT_LCB));
}
}

/*******************************************************************************
**
+1 −15
Original line number Diff line number Diff line
@@ -943,13 +943,7 @@ UINT16 AVDT_WriteReqOpt(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_
        evt.apiwrite.time_stamp = time_stamp;
        evt.apiwrite.m_pt = m_pt;
        evt.apiwrite.opt = opt;
#if AVDT_MULTIPLEXING == TRUE
        evt.apiwrite.frag_q = fixed_queue_new(SIZE_MAX);
#endif
        avdt_scb_event(p_scb, AVDT_SCB_API_WRITE_REQ_EVT, &evt);
#if AVDT_MULTIPLEXING == TRUE
        fixed_queue_free(evt.apiwrite.frag_q, NULL);
#endif
    }

    return result;
@@ -1192,18 +1186,10 @@ extern UINT16 AVDT_WriteDataReq(UINT8 handle, UINT8 *p_data, UINT32 data_len,
            break;
        }
        evt.apiwrite.p_buf = 0; /* it will indicate using of fragments queue frag_q */
        /* create queue of media fragments */
        evt.apiwrite.frag_q = fixed_queue_new(SIZE_MAX);

        /* compose fragments from media payload and put fragments into gueue */
        avdt_scb_queue_frags(p_scb, &p_data, &data_len, evt.apiwrite.frag_q);
        avdt_scb_queue_frags(p_scb, &p_data, &data_len);

        if (fixed_queue_is_empty(evt.apiwrite.frag_q))
        {
            AVDT_TRACE_WARNING("AVDT_WriteDataReq out of GKI buffers");
            result = AVDT_ERR_RESOURCE;
            break;
        }
        evt.apiwrite.data_len = data_len;
        evt.apiwrite.p_data = p_data;

+0 −4
Original line number Diff line number Diff line
@@ -63,12 +63,8 @@ static void avdt_ccb_clear_ccb(tAVDT_CCB *p_ccb)

    /* clear out response queue */
    while ((p_buf = (BT_HDR *) fixed_queue_try_dequeue(p_ccb->rsp_q)) != NULL)
    {
        osi_free(p_buf);
}
    fixed_queue_free(p_ccb->rsp_q, NULL);
    p_ccb->rsp_q = NULL;
}

/*******************************************************************************
**
+1 −3
Original line number Diff line number Diff line
@@ -458,7 +458,6 @@ typedef struct {
    BT_HDR      *p_buf;
    UINT32      time_stamp;
#if AVDT_MULTIPLEXING == TRUE
    fixed_queue_t *frag_q;              /* Queue for outgoing media fragments. p_buf should be 0 */
    UINT8       *p_data;
    UINT32      data_len;
#endif
@@ -677,8 +676,7 @@ extern void avdt_scb_clr_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_transport_channel_timer(tAVDT_SCB *p_scb,
                                             tAVDT_SCB_EVT *p_data);
extern void avdt_scb_clr_vars(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data);
extern void avdt_scb_queue_frags(tAVDT_SCB *p_scb, UINT8 **pp_data,
                                 UINT32 *p_data_len, fixed_queue_t *pq);
extern void avdt_scb_queue_frags(tAVDT_SCB *p_scb, UINT8 **pp_data, UINT32 *p_data_len);

/* msg function declarations */
extern BOOLEAN avdt_msg_send(tAVDT_CCB *p_ccb, BT_HDR *p_msg);
+1 −10
Original line number Diff line number Diff line
@@ -594,9 +594,6 @@ tAVDT_SCB *avdt_scb_alloc(tAVDT_CS *p_cs)
    {
        if (!p_scb->allocated)
        {
            alarm_free(p_scb->transport_channel_timer);
            p_scb->transport_channel_timer = NULL;
            fixed_queue_free(p_scb->frag_q, NULL);
            memset(p_scb,0,sizeof(tAVDT_SCB));
            p_scb->allocated = TRUE;
            p_scb->p_ccb = NULL;
@@ -646,20 +643,14 @@ tAVDT_SCB *avdt_scb_alloc(tAVDT_CS *p_cs)
*******************************************************************************/
void avdt_scb_dealloc(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
{
#if AVDT_MULTIPLEXING == TRUE
    void *p_buf;
#endif
    UNUSED(p_data);

    AVDT_TRACE_DEBUG("avdt_scb_dealloc hdl=%d", avdt_scb_to_hdl(p_scb));
    alarm_free(p_scb->transport_channel_timer);
    p_scb->transport_channel_timer = NULL;

#if AVDT_MULTIPLEXING == TRUE
    /* free fragments we're holding, if any; it shouldn't happen */
    while ((p_buf = fixed_queue_try_dequeue(p_scb->frag_q)) != NULL)
        osi_free(p_buf);
    fixed_queue_free(p_scb->frag_q, NULL);
    fixed_queue_free(p_scb->frag_q, osi_free);
#endif

    memset(p_scb, 0, sizeof(tAVDT_SCB));
Loading