載入共享庫時出錯

載入共享庫時出錯

我為我的 Ubuntu 16.04 機器從 WineHQ 安裝了 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

這看起來是一個強有力的候選者的主要原因是因為它提到了葡萄酒。

之後,我在 WineHQ Wiki 上找到了這個頁面:預載器頁面零問題

雖然該頁面沒有明確地提到我們遇到的錯誤,它提到了許多其他聽起來可疑相關的事情。

所以我嘗試了它推薦的“正確的解決方法”,即sudo sysctl -w vm.mmap_min_addr=0——突然間我可以再次在 Wine 下運行 Windows 32 位元應用程式了! :-)

注意:WineHQ Wiki 頁面也提供了使該變更永久化的說明,但如果這樣做可能會產生一些系統安全隱患。

相關內容