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()Õâ×麯Êý½«Õû¸öÀú³Ì·ÖΪÁ½¸ö°ì·¨¡£Ê×ÏÈ£¬Ô¤ÁôÀο¿ÊýÄ¿µÄ¿Õ¼ä¡£ÈôÊÇÀֳɣ¬Ôò·µ»ØÖ¸Ïò»·Ðλº³åÇøÊý¾ÝÇøÓòÄÚÊý¾ÝµÄÖ¸Õ룬BPF³ÌÐò¿ÉÒÔÏñʹÓÃÊý×é/¹þÏ£Ó³ÉäÄÚµÄÊý¾ÝÒ»ÑùʹÓøÃÖ¸Õë¡£Ò»µ©×¼±¸ºÃ£¬Õâ¿éÄÚ´æҪô±»Ìá½»£¬ÒªÃ´±»ÑïÆú¡£discardÓëcommitÀàËÆ¡£
ÔÚ½¨ÉèBPF_MAP_TYPE_RINGBUFÓ³Éäʱ£¬Äں˽«·ÖÅÉÁ½¸öÄÚ´æÇøÓò¡£Ò»¸öÊÇ bpf_ringbuf_map ½á¹¹£¬ÀàËÆÓÚÆäËûµÄÓ³ÉäÀàÐÍ£¬ÁíÒ»¸öÊÇbpf_ringbuf½á¹¹¡£¸Ã½á¹¹½ç˵ÈçÏÂͼËùʾ£º
ÆäÖУ¬pagesÊÇÄÚ´æ·ÖÅɵÄËùÓÐÒ³ÃæÜöÝÍ£¬consumer_posΪÏûºÄÕß¼ÆÊýÆ÷£¬producer_posΪÉú²úÕß¼ÆÊýÆ÷£¬»®·Ö·ÅÔÚÏàÁڵĵ¥¶ÀµÄÒ³ÃæÖУ¬ÔÚ¸ÃÎó²îÐÞ¸´Ç°£¬ÕâÁ½¸öÒ³Ãæ¾ù¿ÉÒÔͨ¹ýMMAPÓ³Éäµ½Óû§¿Õ¼ä¾ÙÐжÁд²Ù×÷µÄ¡£bpf_ringbuf_alloc()º¯ÊýÊÇʵÏÖbpf_ringbuf²¢³õʼ»¯µÄ£¬ÊµÏÖ´úÂëÈçÏÂËùʾ£º
ŲÓÃ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ÄÚ´æÇøÓòµÄ£¬¸ÃʵÏÖÈçÏ´úÂëËùʾ£º
µÚÒ»¸ö²ÎÊýdata_szΪÉêÇë·ÖÅÉÄÚ´æµÄ¾Þϸ£¬nr_meta_pagesΪԪÊý¾ÝÒ³ÃæÊý£¬°üÀ¨Ò»¸ö²»¿ÉÓ³ÉäÒ³ÃæºÍÁ½¸ö¿ÉÓ³ÉäÒ³Ã棬»®·ÖΪconsumer_posºÍproducer_pos£¬nr_data_pagesΪÏÖʵÉêÇë·ÖÅÉÄÚ´æËùÐèµÄÄÚ´æÒ³ÃæÊý£¬nr_pagesΪnr_meta_pagesºÍnr_data_pagesÖ®ºÍ£¬pagesÓÃÓÚ´æ·ÅËùÓÐÒ³ÃæÜöÝÍ£¬ÄÚ´æ·ÖÅÉÈçÏ´úÂëËùʾ£º
ŲÓÃbpf_map_area_alloc()º¯Êý·ÖÅÉpagesÖ¸ÕëÊý×飬ÓÃÓÚ´æ·Å¼´½«·ÖÅɵÄÄÚ´æÒ³Ã档ȻºóÑ»·Å²ÓÃalloc_pages_node()º¯Êý·ÖÅÉÒ³Ãæ²¢´æ·ÅÔÚpagesÖУ¬×¢Öص½nr_data_pagesÊÇË«·ÝµÄ¡£ÏÖʵÄÚ´æ½á¹¹ÈçÏÂËùʾ£º
×îºó£¬Å²ÓÃvmmap()º¯Êý½«pagesÖеÄÒ³ÃæÓ³Éäµ½Ò»Á¬ÐéÄâÄÚ´æ¿Õ¼äÖУ¬ÈçÏ´úÂëËùʾ£º
Îó²îÔÀíÓëÐÞ¸´²¹¶¡
¸ÃÎó²î±¬·¢ÔÚ__bpf_ringbuf_reserve()º¯ÊýÖУ¬¸Ãº¯Êý¿ÉÒÔ·µ»ØÖ¸Ïò»·Ðλº³åÇøÊý¾ÝÇøÓòÄÚÊý¾ÝµÄÖ¸Õ룬¿ÉÊDz¢Ã»ÓÐÅжϻá¼û³¤¶È¾Þϸ£¬µ¼Ö¿ÉÒÔÔ½½ç»á¼ûÊý¾Ý¡£¸Ãº¯ÊýÒªº¦ÊµÏÖÈçÏ´úÂëËùʾ£º
²ÎÊýsizeΪ»á¼û³¤¶È£¬Ê×ÏÈÅжÏsizeÊÇ·ñ´óÓÚ0x3fffffff£¬¿ÉÊDz¢Ã»ÓÐÅжÏlenÊÇ·ñ´óÓÚringbufµÄdata_sz£¬¼´»á¼ûµÄ¹æÄ£ÊÇ·ñ´óÓÚÏÖʵ·ÖÅɵÄringbufÄÚ´æ¹æÄ£¡£È»ºó¶Ôsize+8ÉÏÏÞÈ¡ÕûΪlen£¬½ÓÏÂÀ´È¡³örb->producer_pos£¬Í¨¹ýprod_pos+lenÅÌËã³önew_prod_pos¡£
ÐÐ333£¬Ê×ÏÈÅжÏеÄÉú²úÕßλÖò»Áè¼ÝringbufµÄdata_sz-1£¬È·±£ringbufÄÚ´æ¿Õ¼äÊǸ»×ãµÄ¡£È»ºóͨ¹ýrb->data+prod_posÅÌËã³öhdrµÄλÖã¬×îºó½«rb->producer_pos¸üÐÂΪnew_prod_pos£¬·µ»Øhdr+8λÖõÄÖ¸Õ룬ÈçÏ´úÂëËùʾ£º
ƾ֤ǰÎÄÆÊÎö£¬rb->consumer_posºÍrb->producer_posËùÔÚÒ³ÃæÊÇ¿ÉÓ³ÉäµÄ£¬ÊǿɿصÄÇÒûÓмì²é£¬size»á¼û³¤¶ÈÒ²Êǿɿصģ¬Òò´Ë¿ÉÒԽṹÈçÏÂÌõ¼þµÖ´ï´ó¹æÄ£Ô½½ç»á¼û£¬Áîproducer_pos = 0£¬consumer_pos= 0x3fffffffºÍsize=0x3fffffff¡£ÕâÈý¸ö±äÁ¿¿ÉÒÔÈƹýËùÓмì²é£¬×îºóÅÌËã³öµÄnew_prod_posΪ0x3fffffff+8£¬ÕâÊǸöºÜ´óµÄ¹æÄ£¡£
¸ÃÎó²îÐÞ¸´²¹¶¡ÓÐÁ½²¿·Ö£¬µÚÒ»²¿·ÖÊǼÓÉÏÁ˺Ídata_sz¾ÞϸµÄÅжϣ¬±ÜÃâ»á¼û³¤¶ÈÁè¼ÝÏÖʵ·ÖÅɵĿռä¹æÄ££¬ÈçÏ´úÂëËùʾ£º
²»ÔÊÐí¶Ôrb->producer_posËùÔÚÄÚ´æÒ³Ãæ¾ÙÐÐдӳÉä¡£
Îó²îʹÓÃÀú³Ì
£¨1£©Í¨¹ý¶ÑÅç½á¹¹Ò»Á¬ÄÚ´æ½á¹¹£¬¸øÔ½½ç¶ÁдÌṩ³¡¾°
Ò»Á¬½¨Éè¶à¸ösize=0x1000000µÄringbuf£¬ÕâÀïmapfdµÄringbufºÍvictimfdµÄringbufÊÇÒ»Á¬µÄ£¬ÖÐÐľàÀëÒ»¸öÒ³ÃæµÄguard page
£¨2£©Í¨¹ýeBPFÖ¸Áî½á¹¹³öÔ½½ç¶ÁдÔÓï
ͨ¹ýeBPFÖ¸Áî»á¼ûmapfdµÄringbuf£¬²¢Å²ÓÃbpf_ringbuf_reserve()º¯Êý»ñÈ¡mapfdµÄringbuf->dataÖ¸Õë¡£ÕâÀïSIZEΪ0x30000000´óÓÚÏÖʵ·ÖÅɵÄÄÚ´æ¿Õ¼ä¡£
Æ«ÒÆ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ÄÚ´æ½á¹¹¡£
ͬʱ£¬×ÓÀú³ÌºÍ¸¸Àú³Ìͨ¹ýpipe¾ÙÐÐͨѶ£¬Õâ¸öÀú³ÌÖлáŲÓÃ__x64_sys_readºÍksys_readº¯Êý²¢´¦ÓÚÛÕ±Õ״̬£¬È»ºóÒ»Ö±ËÑË÷threadÄÚºËÕ»£¬ËÑË÷µ½ÕâÁ½¸öº¯Êý·µ»ØµØµã½«ÆäÐ޸ijÉcommit_credsºÍprepare_kernel_cred£¬ÔÚ¸¸Àú³ÌÖÐɨ³ýÛÕ±Õ״̬±ã¿ÉЮÖÆÁ÷³Ì¾ÙÐÐÖ´ÐÐí§Òâ´úÂë¡£
×ÛÉÏʹÓÃÀú³Ì£¬Í¨¹ýÈ«ÐĽṹ¿ÉʵÏÖ¶Ô¸ÃÎó²îµÄÌáȨЧ¹û¡£
²Î¿¼Á´½Ó£º
https://flatt.tech/reports/210401_pwn2own/