Unix/Linux编程:改变进程的根目录------chroot()

每个进程都有一个根目录,该目录是解释绝对路径时的起点。默认情况下,这是文件系统的真实根目录(新进程从其父进程处继承根目录)。有些场合需要改变一个进程的根目录,而特权级(CAP_SYS_CHROOT)进程通过 chroot()系统调用能够做到这一点

NAME
       chroot - change root directory

SYNOPSIS
       #include <unistd.h>

       int chroot(const char *path);

chroot()系统调用将进程的根目录改为由path指定的目录(如果path是符合链接,还将对其解引用)。自此,对所有绝对路径名的解释都将以该文件系统的这一位置作为起点。鉴于这会将应用程序限定于文件系统的特定区域,有时也将此称为设立了一个chroot监禁区。

  • 借助于chroot()系统调用,chroot命令可以在chroot监禁区中执行shell命令
  • 通过读取(readlink())Linux专有/proc/PID/root符合链接的内容,可以获取任何进程的根目录
    在这里插入图片描述
    ftp程序就是应用chroot()的典型实例之一。作为一种安全措施,当用户匿名登录ftp时,ftp程序将使用chroot()为新进程设置根目录------一个专门预留给匿名登录用户的目录。调用chroot()之后,用户将受困于文件系统中新根目录下的子树中(这里所依赖的事实是根目录是其自身的父目录。也就是说/…是/的一个链接,所以改变目录到/后再执行 cd …命令时,用户依然会待在同一目录下。)

通常情况下,不是随便什么程序都可以在chroot监禁区中运行的,因为大多数程序与共享库之间采用的是动态链接的方式。因此,要么只能局限于运行静态链接程序,要么就在监禁区中复制一套标准的共享库系统目录。

chroot()系统调用从未被视为一个完全安全的监禁机制。首先,特权级程序可以在随后对chroot()的进一步调用中利用种种手段而越狱成功。比如,特权限程序可以使用mknod()来创建一个内存设备,并通过该设备来访问RAM的内容,到那时,就一切皆有可能的。通常,最好不要在chroot监禁区文件系统内放置set-user-ID-root程序。

即使是无特权程序,也必须小心防范如下几条可能的越狱路线

  • 调用chroot()并未改变进程的当前工作目录。因此,通常应该在调用chroot()之前或者之后调用一次chdir()函数(例如,chroot()调用之后执行 chdir("/"))。如果没有这么做,那么进程就能够使用相对路径去访问监狱之外的文件和目录。(一些 BSD 的衍生系统杜绝了这一可能性—如果当前工作目录位于新的根目录树之外,那么 chroot()调用会将其修改为与根目录一致。
  • 如果进程针对监禁区之外的某一目录持有一打开文件描述符,那么结合fchdir()和chroot()就可以越狱成功:
int fd;

fd = open("/", O_RDONLY);
chroot("/home/ocea");  //jailed
fchdir(fd);
chroot(".");   //out of jail

为了防止这种可能性,必须关闭所有指向监禁区外目录的文件描述符。(其他一些 UNIX实现提供了 fchroot()系统调用,可用于获得与上述代码片段类似的结果。

  • 即使针对上述可能性采取了防范措施,仍不足以阻止任意非特权程序(即无法控制其操作的程序)越狱成功。遭到囚禁的进程仍然能够利用 UNIX 域套接字来接受(自另一进程处)指向监禁区外目录的文件描述符。将这一文件描述指定为 fchdir()调用的入参,程序即可将其当前工作目录置于监禁区外,之后再通过相对路径来随意访问文件和目录。

一些 BSD 衍生系统提供的 jail()系统调用解决了包括上述问题在内的不少问题,其所创建的监禁区即使针对特权级进程也是安全的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值