![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Сутінки вільного лайнуксного десктопу. Епізод #533
Останній раз я дивився на Wine > 10 років тому. Вчора знадобилося запустити "an app" з ери win2k, яка не працює ані у w10, ані у w7 vm (the compatibility mode не допоміг).
The app запрацювала, що мене неабияк вразило, але поведінка Wine у Fedora 25 засмутила.
По-1-ше, при 1-му запуску winecfg, воно навіженого почало щось
кудись копіювати: виникла дивна пауза, так що я подумав, може за ці
роки той Wine переписали на джаві. Свої dotfiles у $HOME я зберігаю у
the git repo, тому набравши git status
я побачив, що Wine створив
~/.wine
директорію. Але чому так повільно?
$ du -h ~/.wine | tail -1
516M /home/henry/.wine
I don't even.
По-2-ге, я помітив, що можу запускати win executables просто з bash'у, e.g.:
$ file -b ~/.wine/drive_c/Program\ Files/Internet\ Explorer/iexplore.exe
PE32+ executable (GUI) x86-64, for MS Windows
$ !$
запускає Wine'івську пародію на IE, незважаючи на те, що той файл не є лайнуксним ELF.
БОРЯ
Дівчата, катай сюди, дядя фокус покажет!
Ріта і Чіта подбігають ближче.
ЧІТА
А Ви умєєтє?
ЖОРА
(становиться раком)
Нєт нічєго прощє. Ейн, цвей, дрей!
На слові "дрей" приліта птеродактиль Гриша,
хапа хтивого павіана Жору за бордову сраку
і зникає в невідомому напрямку.
БОРЯ
(філософськи)
Жора хотів вам показать фокус, який називається "сєвєрноє сіяніє".
РІТА І ЧІТА
Как інтєрєсно! Чєм ето достігаєтся?
Т.я. екосистема Windows відома тотальною відсутністю malware і ransomware, а Wine--куленепробивною пісочницею, останнє що я хочу, це автоматичний запуск таких виконуваних файлів. Як відключити таку capability?
Якщо лайнуксне ядро зібрати з опцією CONFIG_BINFMT_MISC
, тоді у
execve(2) з'являється можливість
запускати винуковані файли у будь-якому форматі. Коли ядро натикається
на невідомий йому формат, то перед тим як здатися, воно питає
binfmt_misc підсистему, чи знає вона, наприклад, PE32+ (як у прикладі
вище). Щоб відповісти, binfmt_misc потребує спеціальної runtime
конфігурації.
Спочатку користувач маунтує /proc/sys/fs/binfmt_misc/
; щоб додати
нову проводку до бази даних binfmt_misc, він пише у файл
/proc/sys/fs/binfmt_misc/register
спеціально сформатований
рядок. Напр., для PE32+:
# echo :windows:M:0:MZ::/usr/bin/wine: > /proc/sys/fs/binfmt_misc/register
# cat !$:h/windows
enabled
interpreter /usr/bin/wine
flags:
offset 0
magic 4d5a
Тут 0:MZ
є приклад зсуву і послідовності байтів, за яким
визначається певний формат. Для віндюкових .exe це є 1-ші 2 байти:
$ hexdump -C -n10 iexplore.exe
00000000 4d 5a 40 00 01 00 00 00 06 00 |MZ@.......|
0000000a
Тобто, коли ми намагаємося виконати foo.exe, ядро виявляє, що foo.exe це
є the Windows app і робить facepalm.jpg, передаючи foo.exe як параметр
до /usr/bin/wine
.
Щоб видалити проводку з БД binfmt_misc, можна записати -1
в файл тої
проводки:
# echo -1 > /proc/sys/fs/binfmt_misc/windows
So far so good, але у Федорі 25, у нашу гру вступає systemd. До чого тут systemd?
systemd вважає, що маунтити і писати щось руками--то є нижче гідності
користувача, тому воно надає an early boot сервіс під назвою
systemd-binfmt.service, який маунтить binfmt_misc файлову систему і
читає .conf файли (напр. у /usr/lib/binfmt.d/
), за якими воно
самостійно додає проводки до БД binfmt_misc.
Моєю 1ю реацію на авто-виконання .exe файлів було видалити rpm, який відповідає за створення такого авто-виконання:
# rpm -qf /lib/binfmt.d/wine.conf
wine-systemd-2.3-1.fc25.noarch
# rpm --nodeps -e wine-systemd
# systemctl restart systemd-binfmt
На що може сподіватися a humble user після таких команд? На те, що systemd, який намагається за будь-який кошт захистити сором'язливого користувача від лячного лайнуксу, видаліть зайві проводки з БД binfmt_misc.
га-га-га (регоче)
$ ls -l /proc/sys/fs/binfmt_misc
total 0K
--w------- 1 root root 0 Mar 23 19:26 register
-rw-r--r-- 1 root root 0 Mar 23 19:26 status
-rw-r--r-- 1 root root 0 Mar 23 20:11 windows
-rw-r--r-- 1 root root 0 Mar 23 20:11 windowsPE
Все як і було після інсталляції Wine, і можно перезапускати systemd-binfmt хоч до завтра.
А якщо сором'язливий користувач не знає нічого про binfmt_misc, як йому відключити авто-виконання? Можна перезавантажити лайнукс, на що десь у непідступному замку Майкрософт захіхікає проста і добра пика С. Наделли.
Видаляння wine-systemd не є найкращім рішенням, бо з кожним оновленням dnf сумлінно встановить ного знову. Я вже думав прописати щось на кшталт
echo -1 | tee /proc/sys/fs/binfmt_misc/w*
десь у /etc/rc.local
, аж раптом вирішив прочитати binfmt.d(5).
Виявляється, рекомендованим способом є зробити у /etc
сімлінк на
/dev/null
з таким самим ім'ям файлу з /lib/binfmt.d/
, який ми не
хочемо, щоб systemd читав. Тобто,
# ln -s /dev/null /etc/binfmt.d/wine.conf
# systemctl restart systemd-binfmt