LinuxÄÚºËeBPF RINGBUFÔ½½ç½Ó¼û·ì϶£¨CVE-2021-3489£©ÀûÓ÷ÖÎö

°ä²¼¹¦·ò 2022-03-01

½üÄêÀ´ £¬ÔÚPWN2OWN½ÇÖðUbuntu×ÀÃæÏµÍ³ÆÆ½âÏîÄ¿ÖÐ £¬LinuxÄÚºËeBPF»úÔìÒ»ÏòÊÇÈȵãµÄ¹¥»÷Ãæ ¡£±¾ÎÄ·ÖÎöµÄCVE-2021-3489ÊÇÔÚPWN2OWN 2021½ÇÖðÖÐʹÓõķì϶ £¬¸ÃeBPF·ì϶ºÍÒÔÍùµÄÂß¼­ÑéÖ¤·ì϶·ÖÆç £¬·ì϶³Ê´Ë¿ÌÐÂÒýÈëµÄeBPF RINGBUFÖ°ÄÜÖÐ £¬µ¼ÖÂÄÚ´æ½Ó¼ûÔ½½ç £¬¿ÉʵÏÖÔ½½ç¶Áд´ïµ½È¨ÏÞÌáÉý ¡£


BPF»·Ðλº³åÇø¼°Ó³Éä


eBPFÌṩ¶àÖÖÀàÐ͵ÄÓ³Éä £¬»·Ðλº³åÇøÓ³Éä¾ÍÊÇÆäÖÐÖ®Ò» ¡£¸ÃʵÏֵ͝»úÖ®Ò»ÊÇͨ¹ýÔÚCPUÖ®¼ä¹²Ïí»·Ðλº³åÇøÀ´¸üÓÐЧµØÀûÓÃÄÚ´æ ¡£µ¥¸öRINGBUF»·Ðλº³åÇø×÷Ϊ BPF_MAP_TYPE_RINGBUFÀàÐ͵ÄBPFÓ³ÉäÊ·ý³öÏÖ¸øBPF·¨Ê½ ¡£»¹Ìṩ¶à¸öBPF_CALL½Ó¿Úº¯Êý £¬ÆäÖÐbpf_ringbuf_output()Ö°ÄÜΪÔÊÐí½«Êý¾Ý´ÓÒ»¸ö´¦Ëù¸´Ôìµ½»·Ðλº³åÇø £¬bpf_ringbuf_reserve()/bpf_ringbuf_commit()/bpf_ringbuf_discard()Õâ×麯Êý½«Õû¸ö¹ý³Ì·ÖΪÁ½¸ö²½Öè ¡£Ê×ÏÈ £¬Ô¤Áô¹Ì¶¨ÊýÁ¿µÄ¿Õ¼ä ¡£ÈôÊdzɹ¦ £¬Ôò·µ»ØÖ¸Ïò»·Ðλº³åÇøÊý¾ÝÇøÓòÄÚÊý¾ÝµÄÖ¸Õë £¬BPF·¨Ê½Äܹ»ÏñʹÓÃÊý×é/¹þÏ£Ó³ÉäÄÚµÄÊý¾ÝÒ»ÑùʹÓøÃÖ¸Õë ¡£Ò»µ©³ï±¸ºÃ £¬Õâ¿éÄÚ´æÒªÃ´±»Ìá½» £¬ÒªÃ´±»Åׯú ¡£discardÓëcommitÀàËÆ ¡£


ÔÚ´´½¨BPF_MAP_TYPE_RINGBUFÓ³Éäʱ £¬Äں˽«·ÖÅäÁ½¸öÄÚ´æÇøÓò ¡£Ò»¸öÊÇ bpf_ringbuf_map ½á¹¹ £¬ÀàËÆÓÚÆäËûµÄÓ³ÉäÀàÐÍ £¬ÁíÒ»¸öÊÇbpf_ringbuf½á¹¹ ¡£¸Ã½á¹¹½ç˵ÈçÏÂͼËùʾ£º


´úÂëÎļþ.png


ÆäÖÐ £¬pagesÊÇÄÚ´æ·ÖÅäµÄËùÓÐÒ³Ãæ¼¯ÖÐ £¬consumer_posΪÏû·ÑÕß¼ÆÊýÆ÷ £¬producer_posΪ³ö²úÕß¼ÆÊýÆ÷ £¬±ðÀë·ÅÔÚÏàÁڵĵ¥¶ÀµÄÒ³ÃæÖÐ £¬Ôڸ÷ì϶½¨¸´Ç° £¬ÕâÁ½¸öÒ³Ãæ¾ùÄܹ»Í¨¹ýMMAPÓ³Éäµ½Óû§¿Õ¼ä½øÐжÁд²Ù×÷µÄ ¡£bpf_ringbuf_alloc()º¯ÊýÊÇʵÏÖbpf_ringbuf²¢³õʼ»¯µÄ £¬ÊµÏÖ´úÂëÈçÏÂËùʾ£º


´úÂëÎļþ.png


ŲÓÃbpf_ringbuf_area_alloc()º¯Êý·ÖÅäbpf_ringbuf £¬¶øºó³õʼ»¯rb->spinlock £¬rb->waitqºÍrb->work £¬×îºóÉèÖÃrb->mask £¬rb->consumer_posºÍrb->producer_pos ¡£bpf_ringbuf_area_alloc()º¯ÊýÊÇÓÃÀ´¾ßÌå·ÖÅäringbufÄÚ´æÇøÓòµÄ £¬¸ÃʵÏÖÈçÏ´úÂëËùʾ£º


´úÂëÎļþ.png


µÚÒ»¸ö²ÎÊýdata_szΪÉêÇë·ÖÅäÄÚ´æµÄ´óÓ× £¬nr_meta_pagesΪԪÊý¾ÝÒ³ÃæÊý £¬Ô̺¬Ò»¸ö²»³ÉÓ³ÉäÒ³ÃæºÍÁ½¸ö¿ÉÓ³ÉäÒ³Ãæ £¬±ðÀëΪconsumer_posºÍproducer_pos £¬nr_data_pagesΪÏÖʵÉêÇë·ÖÅäÄÚ´æËùÐèµÄÄÚ´æÒ³ÃæÊý £¬nr_pagesΪnr_meta_pagesºÍnr_data_pagesÖ®ºÍ £¬pagesÓÃÓÚ´æ·ÅËùÓÐÒ³Ãæ¼¯ÖÐ £¬ÄÚ´æ·ÖÅäÈçÏ´úÂëËùʾ£º


´úÂëÎļþ.png

ŲÓÃbpf_map_area_alloc()º¯Êý·ÖÅäpagesÖ¸ÕëÊý×é £¬ÓÃÓÚ´æ·Å¼´½«·ÖÅäµÄÄÚ´æÒ³Ãæ ¡£¶øºóÑ­»·Å²ÓÃalloc_pages_node()º¯Êý·ÖÅäÒ³Ãæ²¢´æ·ÅÔÚpagesÖÐ £¬°ÑÎȵ½nr_data_pagesÊÇË«·ÝµÄ ¡£ÏÖʵÄÚ´æ²¼¾ÖÈçÏÂËùʾ£º


ʾÀýͼ.png

×îºó £¬Å²ÓÃvmmap()º¯Êý½«pagesÖеÄÒ³ÃæÓ³Éäµ½Â½ÐøÐé¹¹ÄÚ´æ¿Õ¼äÖÐ £¬ÈçÏ´úÂëËùʾ£º


´úÂëÎļþ.png

·ì϶µÀÀíÓ뽨¸´²¹¶¡


¸Ã·ì϶²úÉúÔÚ__bpf_ringbuf_reserve()º¯ÊýÖÐ £¬¸Ãº¯ÊýÄܹ»·µ»ØÖ¸Ïò»·Ðλº³åÇøÊý¾ÝÇøÓòÄÚÊý¾ÝµÄÖ¸Õë £¬µ«ÊDz¢Ã»ÓÐÅжϽӼû³¤¶È´óÓ× £¬µ¼ÖÂÄܹ»Ô½½ç½Ó¼ûÊý¾Ý ¡£¸Ãº¯Êý¹Ø¼üʵÏÖÈçÏ´úÂëËùʾ£º


´úÂëÎļþ.png


²ÎÊýsizeΪ½Ó¼û³¤¶È £¬Ê×ÏÈÅжÏsizeÊÇ·ñ´óÓÚ0x3fffffff £¬µ«ÊDz¢Ã»ÓÐÅжÏlenÊÇ·ñ´óÓÚringbufµÄdata_sz £¬¼´½Ó¼ûµÄÁìÓòÊÇ·ñ´óÓÚÏÖʵ·ÖÅäµÄringbufÄÚ´æÁìÓò ¡£¶øºó¶Ôsize+8ÉÏÏÞÈ¡ÕûΪlen £¬½ÓÏÂÀ´È¡³örb->producer_pos £¬Í¨¹ýprod_pos+lenÍÆËã³önew_prod_pos ¡£


´úÂëÎļþ.png


ÐÐ333 £¬Ê×ÏÈÅжÏеijö²úÕßµØÎ»²»³¬¹ýringbufµÄdata_sz-1 £¬È·±£ringbufÄÚ´æ¿Õ¼äÊdzä×ãµÄ ¡£¶øºóͨ¹ýrb->data+prod_posÍÆËã³öhdrµÄµØÎ» £¬×îºó½«rb->producer_pos¸üÐÂΪnew_prod_pos £¬·µ»Øhdr+8µØÎ»µÄÖ¸Õë £¬ÈçÏ´úÂëËùʾ£º


´úÂëÎļþ.png


ƾ¾ÝǰÎÄ·ÖÎö £¬rb->consumer_posºÍrb->producer_posµØµãÒ³ÃæÊÇ¿ÉÓ³ÉäµÄ £¬ÊǿɿصÄÇÒûÓв鳭 £¬size½Ó¼û³¤¶ÈÒ²ÊǿɿصÄ £¬Òò¶øÄܹ»»ú¹ØÈçÏÂǰÌá´ïµ½´óÁìÓòÔ½½ç½Ó¼û £¬Áîproducer_pos = 0 £¬consumer_pos= 0x3fffffffºÍsize=0x3fffffff ¡£ÕâÈý¸ö±äÁ¿Äܹ»ÈƹýËùÓв鳭 £¬×îºóÍÆËã³öµÄnew_prod_posΪ0x3fffffff+8 £¬ÕâÊǸöºÜ´óµÄÁìÓò ¡£


¸Ã·ì϶½¨¸´²¹¶¡ÓÐÁ½²¿ÃÅ £¬µÚÒ»²¿ÃÅÊǼÓÉÏÁ˺Ídata_sz´óÓ×µÄÅжÏ £¬Ô¤·À½Ó¼û³¤¶È³¬Ó¿ÏÖʵ·ÖÅäµÄ¿Õ¼äÁìÓò £¬ÈçÏ´úÂëËùʾ£º


´úÂëÎļþ.png


²»ÔÊÐí¶Ôrb->producer_posµØµãÄÚ´æÒ³Ãæ½øÐÐдӳÉä ¡£


·ì϶ÀûÓùý³Ì


£¨1£©Í¨¹ý¶ÑÅç»ú¹ØÂ½ÐøÄÚ´æ²¼¾Ö £¬¸øÔ½½ç¶ÁдÌṩ³¡¾°

Â½Ðø´´½¨¶à¸ösize=0x1000000µÄringbuf £¬ÕâÀïmapfdµÄringbufºÍvictimfdµÄringbufÊÇÂ½ÐøµÄ £¬ÖÐÑë¾àÀëÒ»¸öÒ³ÃæµÄguard page


´úÂëÎļþ.png

£¨2£©Í¨¹ýeBPFÖ¸Áî»ú¹Ø³öÔ½½ç¶ÁдԭÓï

ͨ¹ýeBPFÖ¸Áî½Ó¼ûmapfdµÄringbuf £¬²¢Å²ÓÃbpf_ringbuf_reserve()º¯Êý»ñÈ¡mapfdµÄringbuf->dataÖ¸Õë ¡£ÕâÀïSIZEΪ0x30000000´óÓÚÏÖʵ·ÖÅäµÄÄÚ´æ¿Õ¼ä ¡£


´úÂëÎļþ.png


Æ«ÒÆsize*2+0x1000Ìø¹ýmapfdµÄringbuf £¬ÔÙÆ«ÒÆ8´¦ÊÇvictimfdµÄringbuf->wait_queue_head->list_head £¬Æ«ÒÆ40´¦ÊÇringbuf-> irq_work->func £¬³õʼ»¯bpf_ringbufʱ £¬funcΪbpf_ringbuf_notify £¬Òò¶øÄܹ»ÍÆËã³öÄں˻ùµØÖ· ¡£


£¨4£©½Ù³Ö·µ»ØµØÖ·Ö´ÐдúÂë

ͨ¹ý´óÁ¿fork×Ó¹ý³Ì £¬ÔÚvictimfdÄÚ´æºóÃæµÃµ½Â½ÐøµÄtask_structÄÚ´æ²¼¾Ö ¡£


´úÂëÎļþ.png


ͬʱ £¬×Ó¹ý³ÌºÍ¸¸¹ý³Ìͨ¹ýpipe½øÐÐͨѶ £¬Õâ¸ö¹ý³ÌÖлáŲÓÃ__x64_sys_readºÍksys_readº¯Êý²¢´¦ÓÚ×èÈû״̬ £¬¶øºó²»ÐÝËÑË÷threadÄÚºËÕ» £¬ËÑË÷µ½ÕâÁ½¸öº¯Êý·µ»ØµØÖ·½«ÆäÅú¸Ä³Écommit_credsºÍprepare_kernel_cred £¬ÔÚ¸¸¹ý³ÌÖнâ³ý×èÈû״̬±ã¿É½Ù³ÖÁ÷³Ì½øÐÐÖ´ÐÐËÁÒâ´úÂë ¡£      


×ÛÉÏÀûÓùý³Ì £¬Í¨¹ý¾«ÐÄ»ú¹Ø¿ÉʵÏֶԸ÷ì϶µÄÌáȨ³ÉЧ ¡£


        

²Î¿¼Á´½Ó£º 

https://flatt.tech/reports/210401_pwn2own/