这到底是做什么的?我不明白你如何用这个访问基本内存......看起来有点奇怪。安全吗?
dd if=/dev/urandom of=/dev/mem
答案1
不要在家里尝试这个!它可能会使您的系统崩溃,如果您真的不走运,它可能会损坏外围设备或使您的计算机无法启动。
实际上,在大多数平台上,它只是失败并出现错误,但这取决于硬件架构。除非您以非特权用户身份运行该命令,否则绝对不能保证这是无害的。对于非特权用户,该命令完全无害,因为您无法打开/dev/mem
.
当您以 root 身份运行命令时,您应该知道自己在做什么。内核将有时阻止你做危险的事情,但并非总是如此。/dev/mem
是那些潜在危险的事情之一,你真的应该知道自己在做什么。
我将介绍 write to/dev/mem
在 Linux 上的工作原理。一般原理在其他 Unice 上是相同的,但内核选项之类的东西完全不同。
当进程读取或写入设备文件时会发生什么由内核决定。对设备文件的访问会在处理该设备文件的驱动程序中运行一些代码。例如,写入/dev/mem
调用函数write_mem
在drivers/char/mem.c
。该函数有 4 个参数:表示打开文件的数据结构、指向要写入的数据的指针、要写入的字节数以及文件中的当前位置。
请注意,只有调用者一开始就有打开文件的权限,您才能做到这一点。设备文件通常遵循文件权限。的正常权限由 拥有/dev/mem
,因此如果您尝试在没有 root 身份的情况下打开它进行写入,您只会得到“权限被拒绝”(EACCESS)。但如果您是 root 用户(或者 root 更改了该文件的权限),则打开过程将完成,然后您可以尝试写入。crw-r-----
root:kmem
函数中的代码write_mem
会进行一些健全性检查,但这些检查不足以防范所有不良情况。它所做的第一件事是将当前文件位置转换*ppos
为物理地址。如果失败(实际上,因为您所在的平台具有 32 位物理地址,但文件偏移量为 64 位,并且文件偏移量大于 2^32),则写入会失败并显示 EFBIG(文件太大)。下一个检查是要写入的物理地址范围在此特定处理器架构上是否有效,如果失败会导致 EFAULT(错误地址)。
接下来,在 Sparc 和 m68k 上,第一个物理页中写入的任何部分都会被静默跳过。
我们现在已经达到了主循环它迭代可以容纳在一个块中的数据内存管理单元页。
/dev/mem
访问物理内存,而不是虚拟内存,但在内存中加载和存储数据的处理器指令使用虚拟地址,因此代码需要安排将物理内存映射到某个虚拟地址。在 Linux 上,根据处理器架构和内核配置,此映射要么永久存在,要么必须动态创建;这就是xlate_dev_mem_ptr
(并unxlate_dev_mem_ptr
撤消xlate_dev_mem_ptr
所做的一切)。然后该函数copy_from_user
从传递给系统调用的缓冲区中读取数据write
,然后写入物理内存当前映射的虚拟地址。该代码发出正常的内存存储指令,这意味着什么取决于硬件。
在讨论对物理地址的写入之前,我将讨论在写入之前发生的检查。在循环内部,page_is_allowed
如果内核配置选项,该函数会阻止对某些地址的访问CONFIG_STRICT_DEVMEM
已启用(默认情况下):仅允许的地址devmem_is_allowed
可以通过 访问/dev/mem
,对于其他人,写入失败并显示 EPERM(不允许操作)。该选项的描述指出:
如果打开此选项并且 IO_STRICT_DEVMEM=n,则 /dev/mem 文件仅允许用户空间访问 PCI 空间以及 BIOS 代码和数据区域。这对于dosemu 和X 以及/dev/mem 的所有普通用户来说已经足够了。
这是非常以 x86 为中心的描述。事实上,更一般地说,CONFIG_STRICT_DEVMEM
阻止访问映射到 RAM 的物理内存地址,但允许访问未映射到 RAM 的地址。允许的物理地址范围的详细信息取决于处理器架构,但所有这些都不包括存储内核和用户态进程数据的 RAM。附加选项CONFIG_IO_STRICT_DEVMEM
(从 Ubuntu 18.04 开始禁用)阻止对驱动程序声明的物理地址的访问。
映射到RAM的物理内存地址。那么是否存在未映射到 RAM 的物理内存地址?是的。这就是我上面承诺的关于写入地址意味着什么的讨论。
内存存储指令不一定写入 RAM。处理器分解地址并决定将存储分派到哪个外设。 (当我说“处理器”时,我涵盖了可能不是来自同一制造商的外围控制器。)RAM 只是这些外围设备之一。调度的完成方式很大程度上取决于处理器架构,但所有架构的基本原理或多或少是相同的。处理器基本上分解地址的较高位,并在一些基于硬编码信息、通过探测某些总线获得的信息以及软件配置的信息填充的表中查找它们。可能涉及大量的缓存和缓冲,但简而言之,在分解之后,处理器在某些上写入一些内容(对目标地址和正在存储的数据进行编码)公共汽车然后由外围设备来处理它。 (或者表查找的结果可能是该地址处没有外设,在这种情况下,处理器输入陷阱状态它在内核中执行一些代码,通常会导致信号总线用于调用过程。)
存储到映射到 RAM 的地址时,除了覆盖之前存储在该地址的值之外,不会“执行”任何操作,并承诺稍后在同一地址加载将返回最后存储的值。但即使是 RAM 也有一些地址不以这种方式运行:它有一些寄存器可以控制刷新率和电压等。
一般来说,对硬件寄存器的读取或写入会执行硬件编程执行的任何操作。大多数对硬件的访问都是这样工作的:软件(通常是内核代码)访问某个物理地址,到达将处理器连接到外设的总线,然后外设执行其操作。一些处理器(特别是 x86)还具有单独的 CPU 指令,这些指令会导致对与内存加载和存储不同的外设进行读/写,但即使在 x86 上,许多外设也是通过加载/存储来访问的。
该命令dd if=/dev/urandom of=/dev/mem
将随机数据写入映射到地址 0 的任何外设(以及后续地址,只要写入成功)。实际上,我预计在许多架构上,物理地址 0 没有任何外设映射到它,或者没有 RAM,因此第一次写入尝试会失败。但是,如果有一个外设映射到地址 0,或者如果您更改命令以写入不同的地址,则会在外设中触发一些不可预测的情况。随着地址不断增加的随机数据,它不太可能做一些有趣的事情,但原则上它可能会关闭计算机(实际上可能有一个地址可以做到这一点),覆盖一些BIOS设置,使其无法启动,甚至击中一些有缺陷的外围设备会损坏它。
alias Russian_roulette='dd if=/dev/urandom of=/dev/mem seek=$((4096*RANDOM+4096*32768*RANDOM))'
答案2
如果您正确配置了内核,那么它是安全的(安全是因为它不起作用)
根据手册页内存(4):
/dev/mem 是字符设备文件,是计算机主内存的映像。例如,它可用于检查(甚至修补)系统。
因此从理论上讲,dd if=/dev/urandom of=/dev/mem
应该覆盖您已安装的物理内存的整个地址空间,并且由于内核和其他程序从内存运行,因此应该有效地使系统崩溃。实际上,是有限制的。来自同一手册页:
从 Linux 2.6.26 开始,根据体系结构,CONFIG_STRICT_DEVMEM 内核配置选项限制了可以通过此文件访问的区域。
dd: writing to '/dev/mem': Operation not permitted
在虚拟机 Ubuntu 18.04 上尝试此操作,即使sudo
具有 root 权限,它也会返回错误crw-r-----
。从乌班图维基:
/dev/mem 保护
某些应用程序 (Xorg) 需要从用户空间直接访问物理内存。特殊文件 /dev/mem 的存在就是为了提供这种访问。过去,如果攻击者拥有 root 访问权限,就可以从此文件查看和更改内核内存。引入 CONFIG_STRICT_DEVMEM 内核选项来阻止非设备内存访问(最初名为 CONFIG_NONPROMISC_DEVMEM)。
所以从技术上讲,不,它不安全(因为它会使系统崩溃),如果CONFIG_STRICT_DEVMEM
禁用内核选项,这是一个安全漏洞,但从我到目前为止所看到的情况来看,如果启用该选项,该命令将不会运行。根据跨站点重复,重新启动将解决任何问题,但是当时 RAM 中的数据当然会丢失并且不会刷新到磁盘(如果有的话)。
对于之前链接的重复项,有一个建议的方法busybox devmem
,因此,如果您决定摆弄 RAM,也许还是有办法的。