LinuxÄÚºËȨÏÞÌáÉýÎó²î¡°DirtyPipe¡±£¨CVE-2022-0847£©ÆÊÎö

Ðû²¼Ê±¼ä 2022-03-14

Îó²îÏêÇé


¿ËÈÕ£¬£¬ £¬£¬Ñо¿Ö°Ô±Åû¶ÁËÒ»¸öLinuxÄÚºËÍâµØÈ¨ÏÞÌáÉýÎó²î£¬£¬ £¬£¬·¢Ã÷ÔÚcopy_page_to_iter_pipeºÍ push_pipeº¯ÊýÖУ¬£¬ £¬£¬Ð·ÖÅɵÄpipe_buffer½á¹¹Ìå³ÉÔ±¡°flags¡±Î´±»×¼È·µØ³õʼ»¯£¬£¬ £¬£¬¿ÉÄܰüÀ¨¾ÉÖµPIPE_BUF_FLAG_CAN_MERGE¡£¡£¡£ ¡£¡£¹¥»÷Õß¿ÉʹÓôËÎó²îÏòÓÉÖ»¶ÁÎļþÖ§³ÖµÄÒ³Ãæ»º´æÖеÄÒ³ÃæÐ´ÈëÊý¾Ý£¬£¬ £¬£¬´Ó¶øÌáÉýȨÏÞ¡£¡£¡£ ¡£¡£¸ÃÎó²î±àºÅΪCVE-2022-0847£¬£¬ £¬£¬ÒòÎó²îÀàÐͺ͡°DirtyCow¡±£¨ÔàÅ££©ÀàËÆ£¬£¬ £¬£¬Òà³ÆÎª¡°DirtyPipe¡±¡£¡£¡£ ¡£¡£



Ïà¹ØÏµÍ³Å²ÓÃʵÏÖ


2.1 pipeϵͳŲÓÃʵÏÖ


ŲÓÃpipe()½¨ÉèÒ»¸ö¹ÜµÀ£¬£¬ £¬£¬·µ»ØÁ½¸öÎļþÐÎò·û£¬£¬ £¬£¬fd[1]Ϊ¶Á£¬£¬ £¬£¬fd[2]Ϊд¡£¡£¡£ ¡£¡£ÕâÀïÒÔlinux-5.16.10Äں˴úÂëΪÀý£¬£¬ £¬£¬Å²Óõ½__do_pipe_flags()º¯Êý£¬£¬ £¬£¬¸Ãº¯Êý´úÂëʵÏÖÈçÏ£º


´úÂëÎļþ.png


Ê×ÏÈŲÓÃcreate_pipe_files()£¬£¬ £¬£¬È»ºóŲÓÃget_unused_fd_flags()»®·Ö»ñȡδʹÓõÄÎļþÐÎò·ûfdrºÍfdw£¬£¬ £¬£¬²¢Ð´Èëµ½Ö¸ÕëfdÖС£¡£¡£ ¡£¡£create_pipe_files()º¯ÊýŲÓÃget_pipe_inode()º¯Êý»ñȡһ¸öinode£¬£¬ £¬£¬²¢³õʼ»¯Ïà¹ØÊý¾Ý½á¹¹¡£¡£¡£ ¡£¡£get_pipe_inode()º¯ÊýÓÖŲÓÃalloc_pipe_info()º¯Êý·ÖÅÉÒ»¸öpipe_inode_info£¬£¬ £¬£¬¸Ã½á¹¹ÌåÊÇÒ»¸öÄÚºËpipe½á¹¹Ì壬£¬ £¬£¬ÓÃÓڹܵÀµÄÖÎÀíºÍ²Ù×÷¡£¡£¡£ ¡£¡£Ïêϸ¿´ÏÂalloc_pipe_info()º¯Êý£¬£¬ £¬£¬¸Ãº¯ÊýʵÏÖ´úÂëÈçÏ£º


´úÂëÎļþ.png


È»ºó×îÏÈ·ÖÅÉpipe->bufs£¬£¬ £¬£¬Õý³£Ò»´ÎÐÔ·ÖÅÉ16¸öpipe_buffer£¬£¬ £¬£¬È»ºó³õʼ»¯pipeµÄÏà¹Ø³ÉÔ±£¬£¬ £¬£¬ÕâÀï²¢²»»á³õʼ»¯pipe_bufsÖеÄpipe_buffer¡£¡£¡£ ¡£¡£piper_buffer½á¹¹Ìå½ç˵ÈçÏ£º


´úÂëÎļþ.png

Ê×ÏÈ´Ópipe->head×îÏÈ£¬£¬ £¬£¬ÅжÏpipeÊÇ·ñΪÂúµÄ¡£¡£¡£ ¡£¡£²»ÂúµÄÇéÐÎÏ£¬£¬ £¬£¬ÄóöÒ»¸öpipe_buffer£¬£¬ £¬£¬ÅжÏpageÊÇ·ñÒÑ·ÖÅÉ£¬£¬ £¬£¬Î´·ÖÅÉËæ¼´·ÖÅÉÒ»¸öÐÂpage£¬£¬ £¬£¬È»ºó³õʼ»¯Õâ¸öpipe_bufferÏà¹Ø³ÉÔ±£¬£¬ £¬£¬ÊµÏÖ´úÂëÈçÏ£º


´úÂëÎļþ.png


´úÂëÎļþ.png


´úÂëÎļþ.png


·ÖÈýÖÖÇéÐΣ¬£¬ £¬£¬µÚÒ»ÖÖΪin/out¾ùΪpipeÀàÐÍ£¬£¬ £¬£¬µÚ¶þÖÖÊÇinΪpipeÀàÐÍ£¬£¬ £¬£¬µÚÈýÖÖÊÇoutΪpipeÀàÐÍ£¬£¬ £¬£¬ÕâÀïÎÒÃÇÆÊÎöµÚÈýÖÖÇéÐΡ£¡£¡£ ¡£¡£Å²ÓÃspilce_file_tp_pipe()º¯Êý½«Êý¾ÝдÈëpipeÖУ¬£¬ £¬£¬Ïêϸ»áŲÓõ½generic_file_splice_read()º¯Êý£¬£¬ £¬£¬ÕâÀïÒÔlinux-2.6.17Äں˰汾ΪÀý£¬£¬ £¬£¬¸üÈÝÒ×Ã÷È·Á㿽±´Àú³Ì¡£¡£¡£ ¡£¡£¸Ãº¯ÊýʵÏÖÈçÏ£º


´úÂëÎļþ.png


´úÂëÎļþ.png

Ê×ÏÈ»ñÈ¡in->f_mapping£¬£¬ £¬£¬¸Ã½á¹¹ÌåÊÇÓÃÓÚÖÎÀíÎļþ£¨struct inode)Ó³Éäµ½ÄÚ´æµÄÒ³Ãæ(structpage)£¬£¬ £¬£¬×Åʵ¾ÍÊÇÿ¸öfile¶¼ÓÐÕâôһ¸ö½á¹¹£¬£¬ £¬£¬½«ÎļþϵͳÖÐÕâ¸öfile¶ÔÓ¦µÄÊý¾ÝÓëÕâ¸öfile¶ÔÓ¦µÄÄÚ´æ°ó¶¨µ½Ò»Æð¡£¡£¡£ ¡£¡£È»ºó½ç˵һ¸ösplice_pipe_desc½á¹¹Ì壬£¬ £¬£¬¸Ã½á¹¹ÌåÓÃÓÚÖÐתfile¶ÔÓ¦µÄÄÚ´æÒ³¡£¡£¡£ ¡£¡£½ÓÏÂÀ´¾ÍÊǽ«file¶ÔÓ¦µÄÄÚ´æÒ³ÃæÕûÀí·ÅÔÚspdÖУ¬£¬ £¬£¬Àú³Ì½ÏÁ¿Öش󣬣¬ £¬£¬ÂÔ¹ý¡£¡£¡£ ¡£¡£×îºóŲÓÃsplice_to_pipe()º¯Êý²Ù×÷pipeºÍspd£¬£¬ £¬£¬¸Ãº¯ÊýʵÏÖÒªº¦´úÂëÈçÏÂËùʾ£º


´úÂëÎļþ.png


ÒÀ´ÎÑ­»·µØ´Óspd->pagesÖÐÈ¡³öÄÚ´æÒ³·ÅÔÚ¶ÔÓ¦µÄbuf->pageÖС£¡£¡£ ¡£¡£¿£¿£¿£¿£¿ÉÒÔ¿´³öÕâÀï½ö½öÊǶÔÄÚ´æÒ³Ãæ¾ÙÐÐ×ªÒÆ£¬£¬ £¬£¬¶øÃ»ÓоÙÐÐÈκÎÄڴ濽±´¡£¡£¡£ ¡£¡£


Îó²îÔ­ÀíÓë²¹¶¡


3.1 Îó²îÔ­Àí

ÔÚlinux-5.16.10ÄÚºËÖУ¬£¬ £¬£¬Å²ÓÃsplice()º¯Êý½«Êý¾ÝдÈë¹ÜµÀʱ£¬£¬ £¬£¬Å²Ó÷¾¶ÈçÏÂËùʾ£º


´úÂëÎļþ.png


ÈçǰÎÄËùÊö£¬£¬ £¬£¬´ÓpipeÖÐÈ¡³öbuf£¬£¬ £¬£¬Ö»ÊÇÌæ»»ÁËops£¬£¬ £¬£¬page£¬£¬ £¬£¬offsetºÍlen£¬£¬ £¬£¬²¢Ã»ÓÐÐÞ¸Äbuf->flags£¬£¬ £¬£¬Òò´Ë¸ÃbufferËù°üÀ¨µÄÒ³ÃæÊÇ¿ÉÒԺϲ¢µÄ¡£¡£¡£ ¡£¡£µ±ÔÙ´ÎÏò¹ÜµÀÖÐдÈëÊý¾Ýʱ£¬£¬ £¬£¬ÓÉÓÚpipe·ÇÊ×´ÎʹÓ㬣¬ £¬£¬Ê×ÏÈÅжÏҪдÈëµÄbufferÀàÐÍ£¬£¬ £¬£¬ÈôÊÇbuf->flagsΪPIPE_BUF_FLAG_CAN_MERGE£¬£¬ £¬£¬ÐÐ466£¬£¬ £¬£¬Ö±½ÓŲÓÃcopy_page_from_iter()º¯Êý¾ÙÐÐÄڴ濽±´£¬£¬ £¬£¬¶øÄ¿µÄµØµãΪbuf->page£¬£¬ £¬£¬Õâ¸öbuf->pageÏÖʵÉϾÍÊÇÀ´×ÔfileÖжÔÓ¦µÄÄÚ´æÒ³Ãæ¡£¡£¡£ ¡£¡£


´úÂëÎļþ.png


¸ÃÎó²î²¹¶¡ÔÚcopy_page_to_iter_pipe()º¯ÊýºÍpush_pipe()º¯ÊýÖУ¬£¬ £¬£¬½«buf->flagsÖÃÁã¡£¡£¡£ ¡£¡£ÆäÖÐpush_pipe()º¯Êý¿ÉÔÚÆäËû·¾¶Öд¥·¢£¬£¬ £¬£¬²»ÔÙ׸Êö¡£¡£¡£ ¡£¡£


´úÂëÎļþ.png


ʹÓÃÆÊÎö


Ê×ÏÈ£¬£¬ £¬£¬Å²ÓÃpipe½¨Éè¹ÜµÀ²¢Í¨¹ýд¶Á²Ù×÷½«¹ÜµÀÖеÄbufferÀàÐÍÉèÖÃΪPIPE_BUF_FLAG_CAN_MERGE¡£¡£¡£ ¡£¡£


´úÂëÎļþ.png


´¥·¢Îó²îºó£¬£¬ £¬£¬´ËʱpipeÖÐbufËù°üÀ¨µÄÄÚ´æÒ³Ãæ¾ùÊÇÖ¸Ïò/usr/bin/pkexecÎļþËùÊôµÄÄÚ´æÒ³Ã棬£¬ £¬£¬²¢ÇÒÄÚ´æÒ³Ãæ¶¼ÊÇ¿ÉÒԺϲ¢µÄ¡£¡£¡£ ¡£¡£×îºóÔÙ´ÎŲÓÃwrite()º¯Êý½«ÌáȨpayloadдÈëpipeÖУ¬£¬ £¬£¬¼´Ð´Èë/usr/bin/pkexecÎļþÖУ¬£¬ £¬£¬È»ºóÔËÐÐ/usr/bin/pkexecÌáÉýȨÏÞ¡£¡£¡£ ¡£¡£


²Î¿¼Á´½Ó£º


[1]https://dirtypipe.cm4all.com/


[2]https://haxx.in/files/dirtypipez.c


[3]https://lore.kernel.org/lkml/20220221100313.1504449-1-max.kellermann@ionos.com/