LinuxÄÚºËAF_VSOCKÌ×½Ó×ÖǰÌᾺÕù·ì϶£¨CVE-2021-26708£©·ÖÎö
°ä²¼¹¦·ò 2021-03-10·ì϶²¼¾°
½üÆÚ£¬¹ú±í°²È«×êÑÐÈËÔ±ÔÚoss-securityÉÏÅû¶ÁËÒ»¸öAF_VSOCKÌ×½Ó×ÖǰÌᾺÕù¸ßΣ·ì϶CVE-2021-26708£¨CNVD-2021-10822¡¢CNNVD-202102-529£©¡£Æ¾¾ÝÅû¶ϸ½Ú£¬¸Ã·ì϶ÊÇÓÉÓÚÃýÎó¼ÓËøµ¼Ö£¬Äܹ»ÔÚµÍȨÏÞÏ´¥·¢²¢×Ô¶¯¼ÓÔØÒ×Êܹ¥»÷Çý¶¯Ä£¿é´´½¨AF_VSOCKÌ×½Ó×Ö£¬½ø¶øµ¼Ö±¾µØÈ¨ÏÞÌáÉý¡£¸Ã·ì϶²¹¶¡ÒѾ¹é²¢µ½LinuxÄÚºËÖ÷ÏßÖС£
VSOCK½éÉܺͼܹ¹
VSOCK½éÉÜ
VMÌ×½Ó×Ö×îÔçÊÇÓÉVmware¿ª·¢²¢Ìá½»µ½LinuxÄÚºËÖ÷ÏßÖС£VMÌ×½Ó×ÖÔÊÐíÐé¹¹»úÓëÐé¹¹»úÖÎÀí·¨Ê½Ö®¼ä½øÐÐͨѶ¡£Ðé¹¹»úºÍÖ÷»úÉϵÄÓû§¼¶ÀûÓ÷¨Ê½¶¼Äܹ»Ê¹ÓÃVM Ì×½Ó×ÖAPI£¬´Ó¶øÍƽøguestÐé¹¹»úÓëÆähostÖ®¼äµÄ¼±¾çÓÐЧͨѶ¡£¸Ã»úÔìÌṩÁËÒ»¸övsockÌ×½Ó×ÖµØÖ·ÏµÁм°Æävmci´«Ê䣬ּÔÚÓë½Ó¿Ú¼¶´ËÍâUDPºÍTCP¼æÈÝ¡£VSOCK»úÔìËæ¼´µÃµ½LinuxÉçÇøµÄÏìÓ¦£¬RedhatÔÚVSOCKÖÐΪvsockÔö³¤ÁËvirtio´«Ê䣬QEMU/KVMÐé¹¹»úÖÎÀíÌṩ֧³Ö£¬MicrosoftÔö³¤ÁËHyperV´«Êä¡£
VSOCK¼Ü¹¹
VMÌ×½Ó×ÖÓëÆäËûÌ×½Ó×ÖÀàÐÍÀàËÆ£¬ÀýÈçBerkeley UNIXÌ×½Ó×Ö½Ó¿Ú¡£VMÌ×½Ó×ÖÄ£¿éÖ§³ÖÃæÏòÏνӵÄÁ÷Ì×½Ó×Ö£¨ÀýÈçTCP£©ºÍÎÞÏνÓÊý¾Ý±¨Ì×½Ó×Ö£¨ÀýÈçUDP£©¡£VMÌ×½Ó×ÖºÍ̸ϵÁнç˵Ϊ¡°AF_VSOCK¡±£¬²¢ÇÒÌ×½Ó×Ö²Ù×÷·ÖΪSOCK_DGRAMºÍSOCK_STREAM¡£ÈçÏÂͼËùʾ£º

VSOCKÖ§³Ösocket API¡£AF_SOCKµØÖ·´ØÔ̺¬Á½¸öÉí·Ö£ºCIDºÍport¡£CIDΪContextIdentifier£¬¸ßµÍÎıêʶ·û£»portΪ¶Ë¿Ú¡£TCP/IPÀûÓ÷¨Ê½ÏÕЩ²»±ØÒª¸ü¸Ä¾ÍÄܹ»ÊÊÅ䣬ÿһ¸öµØÖ·°µÊ¾Îª

Transportƾ¾Ý´«Êä·½Ïò·ÖΪÁ½ÖÖ£¨ÒÔSOCK_STREAMÀàÐÍΪÀý£©£¬Ò»ÖÖΪG2H transport£¬°µÊ¾guestµ½hostµÄ´«ÊäÀàÐÍ£¬ÔËÐÐÔÚguestÖС£ÁíÒ»ÖÖΪH2G transport£¬°µÊ¾hostµ½guestµÄ´«ÊäÀàÐÍ¡£ÒÔQEMU/KVM´«ÊäΪÀý£¬ÈçÏÂͼËùʾ£º

¸Ã´«ÊäÌṩÌ×½Ó×Ö²ã½Ó¿ÚµÄÇý¶¯·ÖΪÁ½¸ö²¿ÃÅ£ºÒ»¸öÊÇÔËÐÐÔÚguestÖеÄvirtio-transport£¬ÓÃÓÚ¹²Í¬guest½øÐÐÊý¾Ý´«Ê䣻ÁíÒ»¸öÊÇÔËÐÐÔÚhostÖеÄvhost-transport£¬ÓÃÓÚ¹²Í¬host½øÐÐÊý¾Ý´«Êä¡£VSOCK transport»¹Ìṩ¶à´«Êäͨ·ģʽ£¬¸ÃÖ°ÄÜÊÇΪÁËÖ§³ÖǶÌ×Ðé¹¹»úÖеÄVSOCKÖ°ÄÜ¡£ÈçÏÂͼËùʾ£º

Ö§³ÖL1Ðé¹¹»úͬʱ¼ÓÔØH2GºÍG2HÁ½¸ö´«Êäͨ·£¬´ËʱL1Ðé¹¹»ú¼´ÊÇhostÒ²ÊÇguest£¬Í¨¹ýH2G´«Êäͨ·ºÍL2ǶÌ×Ðé¹¹»úͨѶ£¬Í¨¹ýG2H´«Êäͨ·ºÍL0 hostͨѶ¡£VSOCK transport»¹Ö§³Ö±¾µØ»·»Ø´«Êäͨ·ģʽ£¬²»±ØÒªÓÐÐé¹¹»ú¡£ÈçÏÂͼËùʾ£º

¸ÃģʽÓÃÓÚ²âÊԺ͵÷ÊÔ£¬ÓÉvsock-loopbackÌṩ֧³Ö£¬²¢¶ÔµØÖ·´ØÖеÄCID½øÐÐÁË·ÖÀ࣬Ô̺¬Á½ÖÖÀàÐÍ£ºÒ»ÖÖÊÇVMADDR_CID_LOCAL£¬°µÊ¾±¾µØ»·»Ø£»Ò»ÖÖΪVMADDR_CID_HOST£¬°µÊ¾H2G´«Êäͨ·¼ÓÔØ£¬G2H´«Êäͨ·δ¼ÓÔØ¡£
·ì϶·ÖÎöÓë´¥·¢¹ý³Ì
·ì϶·ÖÎö
¸Ã·ì϶´¥·¢ÔÒòÊÇÃýÎó¼ÓËøµ¼ÖÂǰÌᾺÕù£¬Æ¾¾Ý²¹¶¡¿ÉÖª£¬´æÔÚ¶à´¦ÃýÎó¼ÓËø£¬ÕâÀïÒÔvsock_stream_setsockopt()º¯Êý²¹¶¡ÎªÀý£¬ÈçÏÂͼËùʾ£º

²¹¶¡ºÜ¼ò½à£¬½«µÚ1564ÐдúÂëÒÆ¶¯µ½µÚ1571ÐУ¬ÖÐÑë¾Í¸ô×ŵÚ1569ÐдúÂ룺lock_sock(sk)¡£¼ÓËøÇ°£¬vsk->transportÒѾ¸³Öµµ½transport±äÁ¿ÖУ¬ÕâÀï²úÉúÁËÒ»¸öÒýÓ㬶øºó²Å½øÐÐlock_sock(sk)½«skËø¶¨¡£µ«ÊÇvsk->transport»áÔÚ¶à´¦±»Å²ÓÃÉõÖÁ±»¿ªÊÍ£¬Õâ¾ÍÓпÉÄÜͨ¹ýǰÌᾺÕùÔì³ÉUse After Free¡£
´¥·¢¹ý³Ì
Ê×ÏÈÕÒµ½Åú¸Ä»ò¿ªÊÍvsk->transportµÄŲÓÃõè¾¶£¬À´¿´¹Ø¼üº¯Êývsock_assign_transport()µÄʵÏÖ¡£¶ÔÓÚ¶à´«Êäģʽ£¬¸Ãº¯ÊýÓÃÓÚÆ¾¾Ý·ÖÆçCID·ÖÅä·ÖÆçµÄ´«Êäͨ·¡£ÊµÏÖ´úÂëÈçÏÂͼËùʾ£º

ƾ¾Ýsk->sk_type·ÖΪSOCK_DGRAMºÍSOCK_STREAM£¬ÔÚSOCK_STREAMÖУ¬·ÖΪÈýÖÖ´«Êäͨ·¡£ÕâÀïÄܹ»Í¨¹ý½«CIDÉèÖÃΪ±¾µØ»·»ØÄ£Ê½£¬µÃµ½transport_local´«Êäͨ·¡£½ÓÏÂÀ´ÈçÏÂͼËùʾ£º

ÈôÊÇvsk->transport²»Îª¿Õ£¬Ôò½øÈëifÓï¾ä¡£ÏÈÅжÏvsk->transportÊÇ·ñµÅ×Únew_transport£¬ÈôÊǵÅ×ÚÖ±½Ó·µ»Ø£¬ÔÚ´¥·¢¹ý³ÌÖУ¬Òª±£ÕÏÄÜ×ßµ½vsock_deassign_transport()º¯Êý£¬¸Ãº¯ÊýÊÇÎö¹¹º¯Êý£¬ÓÃÓÚ¿ªÊÍtransport¡£ÈçÏ´úÂëËùʾ£º

ÐÐ411£¬Å²ÓÃvsk->transport->destruct()£¬ÒªÃ÷ȷʹÓÃtransportÀàÐÍ£¬Ç°ÎÄÒѾȷ¶¨Ê¹ÓÃtransport_local¡£Transport_localΪȫ¾Ö±äÁ¿£¬»áÔÚvsock_core_register()º¯ÊýÖб»³õʼ»¯¡£¸Ãº¯Êý±»Å²ÓÃÇé¿öÈçÏÂͼËùʾ£º

*_init()º¯ÊýÓÃÀ´³õʼ»¯transportµÄ»Øµ÷º¯Êý£¬Æ¾¾ÝµÚ¶þ²¿ÃŽéÉÜ£¬vhost_vsock_init()¡¢virtio_vsock_init()ºÍvsock_loopback_init()º¯ÊýΪQEMU/KVM»·¾³ÏµÄÖ§³Öº¯Êý¡£ÎÒÃÇ·¢ÏÖtransport->destruct()º¯ÊýµÄ×îºóʵÏÖ¶¼ÊÇͳһ¸öº¯Êý¡£ÈçÏÂͼËùʾ£º

¸Ãdestruct()º¯Êý¿ªÊÍvsk->trans£¬ÈçÏÂͼËùʾ£º

¶øvsk->transÖ¸ÕëÊÇÖ¸ÏòtransportµÄ¡£½á¹¹Ìåvsock_sock½ç˵ÈçÏÂËùʾ£º

×îÖÕÄܹ»»ú¹ØÒ»¸ö¿ªÊÍtransportµÄº¯Êýõ辶Ϊ£ºvsock_stream_connect-> vsock_assign_transport->virtio_transport_destrcut¡£
ÕÒµ½ÁË¿ªÊÍõè¾¶£¬ÏÂÒ»²½ÕÒʹÓÃõè¾¶£¬virtio_transport_notify_buffer_size()º¯Êý»áʹÓÃtransport¡£ÈçÏÂͼËùʾ£º

µÚ492ÐУ¬Í¨¹ývsk->trans»ñȡָÏòtransportµÄÖ¸Õ룬µÚ497ÐУ¬½âÒýÓÃvvsÖ¸Õ룬¶Ôvvs->buf_alloc½øÐи³Öµ¡£¶øÅ²ÓÃvirtio_transport_notify_buffer_size()º¯Êý×îÖջᱻvsock_stream_setsockopt()º¯ÊýŲÓá£×îÖÕÄܹ»»ú¹ØÒ»¸öʹÓÃtransportµÄº¯Êýõ辶Ϊ£ºvsock_stream_setsockopt-> vsock_update_buffer_size->virtio_transport_notify_buffer_size¡£
½ÓÏÂÀ´¾ÍÊÇÓªÔìÒ»¸öÇÀËøµÄǰÌᾺÕù»·¾³£¬ºÜÏÔÖø±ØÐëÊÇconnect()ϵͳŲÓÃÏÈÇÀµ½Ëø¶Ôtransport½øÐпªÊÍ£¬¶øºóÔÙŲÓÃsetsockopt()ÄÜÁ¦´¥·¢·ì϶¡£Óпª·¢ÈËÔ±Ìá³öʹÓÃuserfaultfd»úÔìÏȽ«lock_sockËø¶¨£¬¶øºóÔÚÈ¥¿ªÊÍËø£¬½øÐÐǰÌᾺÕù¡£·ì϶´¥·¢¹ý³ÌÈçÏÂͼËùʾ£º

À¶¿òÖÐÊÇconnect()ŲÓùý³Ì£¬×îºóŲÓÃvirtio_transport_destruct()º¯Êý¿ªÊÍvsk->trans¡£ºì¿òÖÐÊÇsetsockopt()ŲÓùý³Ì£¬Å²ÓÃvirtio_transport_notify_buffer_size()º¯ÊýʹÓÃvvs£¬¸ÃÖµÊÇ0xffff888107a74500£¬ÔÚ0xffff888107a74500+0x28´¦»áдÈë4×Ö½Ú¡£
²Î¿¼Á´½Ó£º
[1]https://github.com/torvalds/linux/commit/d021c344051af91f42c5ba9fdedc176740cbd238
[2]https://static.sched.com/hosted_files/devconfcz2020a/b1/DevConf.CZ_2020_vsock_v1.1.pdf
[3]https://github.com/jordan9001/vsock_poc
[4]https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2020/04/18/vsock-internals
GA»Æ½ð¼×»ý¼«·ÀÓù³¢ÊÔÊÒ£¨ADLab£©
ADLab³ÉÁ¢ÓÚ1999Ä꣬ÊÇÖйú°²È«ÐÐÒµ×îÔç³ÉÁ¢µÄ¹¥·À¼¼Êõ×êÑг¢ÊÔÊÒÖ®Ò»£¬Î¢ÈíMAPP´òËãÖ÷Ìâ³ÉÔ±£¬¡°ºÚȸ¹¥»÷¡±¸ÅÏëÊ×ÍÆÕß¡£½ØÖ¹Ä¿Ç°£¬ADLabÒÑͨ¹ýCVEÀۼư䲼°²È«·ì϶½ü1100¸ö£¬Í¨¹ý CNVD/CNNVDÀۼư䲼°²È«·ì϶1000Óà¸ö£¬³ÖÐøÎ¬³Ö¹ú¼ÊÍøÂ簲ȫÁìÓòÒ»Á÷Ë®×¼¡£³¢ÊÔÊÒ×êÑз½Ïòº¸Ç²Ù×÷ϵͳÓëÀûÓÃϵͳ°²È«×êÑÓ×¢ÖÇÄÜÖն˰²È«×êÑÓ×¢ÎïÁªÍøÖÇÄÜÉ豸°²È«×êÑÓ×¢Web°²È«×êÑÓ×¢¹¤¿ØÏµÍ³°²È«×êÑÓ×¢ÔÆ°²È«×êÑС£×êÑгɾÍÀûÓÃÓÚ²úÆ·Ö÷Ìâ¼¼Êõ×êÑÓ×¢¹ú¶È³Áµã¿Æ¼¼ÏîÄ¿¹¥¹Ø¡¢×¨Òµ°²È«·þÎñµÈ¡£



¾©¹«Íø°²±¸11010802024551ºÅ