我从 WineHQ 为我的 Ubuntu 16.04 机器安装了 Wine,但出现以下错误:
/opt/wine-stable/bin/wine: error while loading shared libraries: libwine.so.1: cannot create shared object descriptor: Operation not permitted.
答案1
简短回答——运行这个:
sudo sysctl -w vm.mmap_min_addr=0
较长的答案:
升级后,我一天前遇到了完全相同的错误从Ubuntu 16.04 到 18.04(并从 WineHQ 重新安装 wine-staging)。
我发现这种情况仅在尝试通过 Wine(在 64 位系统上)运行 32 位 Windows 可执行文件时才会发生。
经过大量的调试后,我尝试运行以下 Wine notepad.exe 得到了一条线索strace
:
$ strace /usr/bin/wine notepad.exe
execve("/usr/bin/wine", ["/usr/bin/wine", "notepad.exe"], 0x7ffc266e8478 /* 55 vars */) = 0
strace: [ Process PID=19507 runs in 32 bit mode. ]
brk(NULL) = 0x7c423000
[ … 140 lines snipped … ]
openat(AT_FDCWD, "/opt/wine-staging/lib/libwine.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220d\0\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=1832828, ...}) = 0
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 EPERM (Operation not permitted)
close(3) = 0
writev(2, [{iov_base="/opt/wine-staging/bin/wine", iov_len=26}, {iov_base=": ", iov_len=2}, {iov_base="error while loading shared libra"..., iov_len=36}, {iov_base=": ", iov_len=2}, {iov_base="libwine.so.1", iov_len=12}, {iov_base=": ", iov_len=2}, {iov_base="cannot create shared object desc"..., iov_len=38}, {iov_base=": ", iov_len=2}, {iov_base="Operation not permitted", iov_len=23}, {iov_base="\n", iov_len=1}], 10/opt/wine-staging/bin/wine: error while loading shared libraries: libwine.so.1: cannot create shared object descriptor: Operation not permitted
) = 144
exit_group(127) = ?
+++ exited with 127 +++
关键是失败mmap2
。读完之后手册mmap2
页(进而手册mmap
页),它似乎只是试图映射一个 8192 字节的匿名块 - 甚至没有链接到磁盘上的文件。这看起来非常无聊,不应该失败。
所以我想我会调查一下这些sysctl
设置,看看在我的 Ubuntu 16.04 → 18.04 升级过程中是否有任何可能发生的变化,特别是任何可能影响mmap2
或只是的变化mmap
。
我在以下位置找到了可能的候选人/etc/sysctl.d/10-zeropage.conf
:
# Protect the zero page of memory from userspace mmap to prevent kernel
# NULL-dereference attacks against potential future kernel security
# vulnerabilities. (Added in kernel 2.6.23.)
#
# While this default is built into the Ubuntu kernel, there is no way to
# restore the kernel default if the value is changed during runtime; for
# example via package removal (e.g. wine, dosemu). Therefore, this value
# is reset to the secure default each time the sysctl values are loaded.
vm.mmap_min_addr = 65536
该候选名单看起来非常有力,主要原因是名单中提到了 Wine。
之后,我在 WineHQ Wiki 上找到了这个页面:预加载器页面零问题。
虽然该页面没有明确地提到我们遇到的错误,它还提到了很多听起来可疑相关的事情。
因此我尝试了其推荐的“正确的解决方法”,也就是说,sudo sysctl -w vm.mmap_min_addr=0
——突然间我可以在 Wine 下再次运行 Windows 32 位应用程序了!:-)
注意:WineHQ Wiki 页面还提供了使该更改永久生效的说明,但这样做可能会对系统安全造成一些影响。