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()º¯Êý£¬¸Ãº¯Êý´úÂëʵÏÖÈçÏ£º
Ê×Ïȵ÷ÓÃ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()º¯Êý£¬¸Ãº¯ÊýʵÏÖ´úÂëÈçÏ£º
È»ºó¿ªÊ¼·ÖÅäpipe->bufs£¬Õý³£Ò»´ÎÐÔ·ÖÅä16¸öpipe_buffer£¬È»ºó³õʼ»¯pipeµÄÏà¹Ø³ÉÔ±£¬ÕâÀï²¢²»»á³õʼ»¯pipe_bufsÖеÄpipe_buffer¡£piper_buffer½á¹¹Ìå½ç˵ÈçÏ£º
Ê×ÏÈ´Ópipe->head¿ªÊ¼£¬ÅжÏpipeÊÇ·ñΪÂúµÄ¡£²»ÂúµÄÇé¿öÏ£¬ÄóöÒ»¸öpipe_buffer£¬ÅжÏpageÊÇ·ñÒÑ·ÖÅ䣬δ·ÖÅäËæ¼´·ÖÅäÒ»¸öÐÂpage£¬È»ºó³õʼ»¯Õâ¸öpipe_bufferÏà¹Ø³ÉÔ±£¬ÊµÏÖ´úÂëÈçÏ£º
·ÖÈýÖÖÇé¿ö£¬µÚÒ»ÖÖΪin/out¾ùΪpipeÀàÐÍ£¬µÚ¶þÖÖÊÇinΪpipeÀàÐÍ£¬µÚÈýÖÖÊÇoutΪpipeÀàÐÍ£¬ÕâÀïÎÒÃÇ·ÖÎöµÚÈýÖÖÇé¿ö¡£µ÷ÓÃspilce_file_tp_pipe()º¯Êý½«Êý¾ÝдÈëpipeÖУ¬¾ßÌå»áµ÷Óõ½generic_file_splice_read()º¯Êý£¬ÕâÀïÒÔlinux-2.6.17Äں˰汾ΪÀý£¬¸üÈÝÒ×Àí½âÁ㿽±´¹ý³Ì¡£¸Ãº¯ÊýʵÏÖÈçÏ£º
Ê×ÏÈ»ñÈ¡in->f_mapping£¬¸Ã½á¹¹ÌåÊÇÓÃÓÚ¹ÜÀíÎļþ£¨struct inode)Ó³Éäµ½ÄÚ´æµÄÒ³Ãæ(structpage)£¬Æäʵ¾ÍÊÇÿ¸öfile¶¼ÓÐÕâôһ¸ö½á¹¹£¬½«ÎļþϵͳÖÐÕâ¸öfile¶ÔÓ¦µÄÊý¾ÝÓëÕâ¸öfile¶ÔÓ¦µÄÄÚ´æ°ó¶¨µ½Ò»Æð¡£È»ºó½ç˵һ¸ösplice_pipe_desc½á¹¹Ì壬¸Ã½á¹¹ÌåÓÃÓÚÖÐתfile¶ÔÓ¦µÄÄÚ´æÒ³¡£½ÓÏÂÀ´¾ÍÊǽ«file¶ÔÓ¦µÄÄÚ´æÒ³ÃæÕûÀí·ÅÔÚspdÖУ¬¹ý³Ì±ÈÁ¦ÅÓ´ó£¬ÂÔ¹ý¡£×îºóµ÷ÓÃsplice_to_pipe()º¯Êý²Ù×÷pipeºÍspd£¬¸Ãº¯ÊýʵÏÖÒªº¦´úÂëÈçÏÂËùʾ£º
ÒÀ´ÎÑ»·µØ´Óspd->pagesÖÐÈ¡³öÄÚ´æÒ³·ÅÔÚ¶ÔÓ¦µÄbuf->pageÖС£¿ÉÒÔ¿´³öÕâÀï½ö½öÊǶÔÄÚ´æÒ³Ãæ½øÐÐתÒÆ£¬¶øûÓнøÐÐÈκÎÄڴ濽±´¡£
©¶´ÔÀíÓë²¹¶¡
3.1 ©¶´ÔÀí
ÔÚlinux-5.16.10ÄÚºËÖУ¬µ÷ÓÃsplice()º¯Êý½«Êý¾ÝдÈë¹ÜµÀʱ£¬µ÷Ó÷¾¶ÈçÏÂËùʾ£º
ÈçÇ°ÎÄËùÊö£¬´Ó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ÖжÔÓ¦µÄÄÚ´æÒ³Ãæ¡£
¸Ã©¶´²¹¶¡ÔÚcopy_page_to_iter_pipe()º¯ÊýºÍpush_pipe()º¯ÊýÖУ¬½«buf->flagsÖÃÁã¡£ÆäÖÐpush_pipe()º¯Êý¿ÉÔÚÆäËû·¾¶Öд¥·¢£¬²»ÔÙ׸Êö¡£
ÀûÓ÷ÖÎö
Ê×ÏÈ£¬µ÷ÓÃpipe´´½¨¹ÜµÀ²¢Í¨¹ýд¶Á²Ù×÷½«¹ÜµÀÖеÄbufferÀàÐÍÉèÖÃΪPIPE_BUF_FLAG_CAN_MERGE¡£
´¥·¢Â©¶´ºó£¬´Ëʱ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/