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/


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