在我的情况下,我需要每天从一个单独的文件系统启动一个进程,它的根目录在一个子目录中。因为它是文件系统上唯一的东西,所以我需要将其销毁。
另一个问题是我不能fork()
/clone()
进程,因为它在特权环中运行。
我想到了以下解决方案:
char *argv [] = {"/path2/sbin/the_program_to_be_launched","-option","value of option",NULL};
char *envp [] = {"HOME=/","SHELL=no_shell_available","LC_ALL=C",NULL};
mount(name, "/path/", fs, flags, data);
chroot("/path/");
execve("/path2/sbin/the_program_to_be_launched",argv,envp); // would not work because the program won’t be able find his libraries
umount("/"); // would never be called if execve() would have been called correctly
如果不执行流程,这样的事情也不会起作用。
mount(name, "/path/", fs, flags, data);
chroot("/path/path2/"):
umount("/"); // would not work since "/" is not the root of the device.
那么,如何在不更改父进程的情况下,用不同的根目录启动不同的子进程呢?
chrom可以启动启动实际程序的shell脚本。
在Linux中,"/"目录是所有文件系统的根目录。所以你肯定不想卸载它。请阅读有关装载/卸载的手册页。
您可以在fstab中为用户可挂载的文件系统放置一个适当的条目。那么挂载/卸载就相对简单了。
你可以创建一个脚本登录/注销的"受限"用户。
该用户可用于运行目标程序并执行装载/卸载操作。
crm运行的shell可以执行所有的CD等
为了让应用程序能够在不查看其"库"的情况下执行,也许可以将其链接为"静态"。也许用户的.profile包含$PATH变量的开发,以包含库的路径。
用户的登录可以使用busybox的版本,该版本只有用户运行目标程序所需的命令。
在类Unix系统上,创建新进程的唯一方法是系统调用fork
或clone
,而execv.
系列是启动可执行文件的唯一方法。确实还有其他类似system
的函数,但它们确实调用了这两个系统调用。
当然,在另一个系统上可能会有所不同。例如,在Windows上,启动新进程的API是CreateProcess
。
但在Unix或Linux上,必须使用clone
或fork
。您可以使用chroot
更改根文件系统,并使用setuid
或其dérivations删除特权(前提是调用进程为privilèges)。