在 Debian 上,运行时:
$ fakeroot cdebootstrap stable /tmp/foo
cdebootstrap 下载软件包,但是当它必须解压它们时,我收到此错误:
E: Failed to unshare: Operation not permitted
如何以非 root 身份运行 cdebootstrap?
取消共享手册中的这部分似乎相关,但我不确定如何:
EPERM (since Linux 3.9)
CLONE_NEWUSER was specified in flags and the caller is in a
chroot environment (i.e., the caller's root directory does not
match the root directory of the mount namespace in which it
resides).
答案1
问题
您的问题与权限继承有关。 cdbootstrap
将继承 的权限fakeroot
,可以通过 提升权限sudo
。问题:
sudo fakeroot cdbootstrap /tmp/foo
如果上述命令成功,则权限/tmp
问题。看/tmp 有哪些常见权利?我无意中将其全部递归设置为公开,默认权限应该是什么。一般来说,/tmp
向应用程序未放入的任何内容写入内容是一个坏主意,并且fakeroot
有其自身的问题。从手册页:
局限性
库版本
在 fakeroot 中执行的每个命令都需要链接到与 fakeroot 本身相同版本的 C 库。
open()
/create()
fakeroot
不换行open()
,create()
等等。所以,如果用户joost
这样做touch foo fakeroot ls -al foo
或者反过来,
fakeroot touch foo ls -al foo
fakeroot
无法知道在第一种情况下,
的 所有者foo
确实应该是 ,joost
而在第二种情况下,它应该
是root
。对于 Debian 打包,默认为
所有“未知”文件提供 uid=gid=0 总是可以的。解决这个问题的真正方法
是包装open()
和create()
,但这会产生其他
问题,如包所示libtricks
。这个包
包含了更多的功能,并尝试做比
fakeroot
.事实证明,libc 的小升级(从
函数stat()
不使用的升级open()
到函数使用stat()
(在某些情况下)使用的升级open()
)会导致无法解释的段错误(即 libc6stat()
称为wrappedopen()
,这将导致无法解释的段错误)。然后调用 libc6stat()
等)。
修复它们并不是那么容易,但是一旦修复,
另一个函数开始使用只是时间问题open()
,
更不用说尝试将其移植到不同的操作系统了。
因此,我决定使包裹的函数数量fakeroot
尽可能小,以限制“冲突”的可能性。
错误
它不包裹
open()
。这本身并不坏,但如果程序这样做open("file", O_WRONLY, 000)
,写入文件“file”,关闭它,然后再次尝试打开以读取该文件,那么该打开将失败,因为该文件的模式将为 000。错误在于,如果 root 执行相同的操作,open()
就会成功,因为根本不会检查 root 的文件权限。我选择不包装open()
,就像open()
libc 中的许多其他函数(也包括那些已经包装的函数)所使用的那样,从而创建循环(或当各种 libc 函数的实现略有变化时可能的未来循环)。
更好的解决方案
不要使用权限升级来实现您想要做的事情,请考虑使用适当的chroot
,如Ubuntu 的 DebootstrapChroot 文档, 或者DebBootStrap 的官方 Debian 文档。
答案2
也许 /tmp 是问题所在。尝试
$fakeroot cdebootstrap 稳定 $HOME/somedir