henry_flower: A melancholy wolf (Default)
henry_flower ([personal profile] henry_flower) wrote2017-03-24 12:20 am
Entry tags:

Сутінки вільного лайнуксного десктопу. Епізод #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