Pull to refresh

Восстанавливаем работу «испорченного» php-cgi

Так получилось, что я все еще являюсь пользователем старого доброго виртуального хостинга у одного из хостеров. Код сайта написан для LAMP, но в модульном PHP оператора отсутствовала часть необходимых библиотек, поэтому пришлось собрать свой PHP и использовать его в качестве CGI. Один раз собрал все это дело, подключил и забыл до того дня пока не получил письмо от хостера о том, что на сервере будет производиться плановое обновление версий ПО, и это может затронуть работу пользовательских cgi-приложениий скомпилированных на сервере. Результаты обновлений увидел уже на следующий день т.к. запросы к сайту стали возвращать 500 (Internal Server Error).

Иду смотреть, что стало с моим бинарем
$ ./php -v
/libexec/ld-elf.so.1: Shared object "libpng.so.6" not found, required by "php"


еще раз проверяю библиотеки с которыми был скомпилирован php-cgi
$ ldd ./php
./php:
        libcrypt.so.5 => /lib/libcrypt.so.5 (0x285cc000)
        libmysqlclient.so.15 => /usr/local/lib/mysql/libmysqlclient.so.15 (0x285f2000)
        libm.so.5 => /lib/libm.so.5 (0x28751000)
        libz.so.5 => /lib/libz.so.5 (0x2876b000)
        libgd.so.4 => /usr/local/lib/libgd.so.4 (0x2877d000)
        libfreetype.so.9 => /usr/local/lib/libfreetype.so.9 (0x287c6000)
        libbz2.so.4 => /usr/lib/libbz2.so.4 (0x2883f000)
        libpng.so.6 => not found (0x0)
        libjpeg.so.11 => /usr/local/lib/libjpeg.so.11 (0x28850000)
        libgdbm.so.4 => /usr/local/lib/libgdbm.so.4 (0x28886000)
        libxml2.so.5 => /usr/local/lib/libxml2.so.5 (0x2888e000)
        libiconv.so.3 => /usr/local/lib/libiconv.so.3 (0x289b8000)
        libc.so.7 => /lib/libc.so.7 (0x28ab0000)
        libpng15.so.15 => /usr/local/lib/libpng15.so.15 (0x28bcc000)

Проверяю наличие «libpng» на сервере
$ ls -l /usr/local/lib/|grep 'png*.*so'
lrwxr-xr-x   1 root  wheel        11 Aug 22 13:23 libpng.so -> libpng15.so
lrwxr-xr-x   1 root  wheel        14 Aug 22 13:23 libpng15.so -> libpng15.so.15
-rwxr-xr-x   1 root  wheel    171916 Aug 22 13:23 libpng15.so.15

Либы есть, но нет файла «libpng.so.6» линк на который остался в моем бинарнике. Версии хостер обновил, а симлинки оставить забыл, видимо. Собирать php повторно из исходников было лень т.к. не помню точной конфигурации, поэтому решил воспользоваться старым «читерским» методом, поправив имя файла библиотеки в самом бинарнике. Как мы видели ранее, к библиотеке теперь можно обратиться через «libpng.so», поэтому в бинаре нужно выполнить замену подстроки libpng.so.6 на libpng.so

Открываем бинарный файл (лучше копию) в vi и переходим в hex-режим (Esc:%!xxd)

Находим строку с вхождением «libpng»
/libpng

0021df0: 322e 736f 2e34 006c 6962 706e 672e 736f 2.so.4.libpng.so
0021e00: 2e36 006c 6962 6a70 6567 2e73 6f2e 3131 .6.libjpeg.so.11

Видим, что символы точка и шесть (ascii: 2e36) в имени файла нам все портят, и нужно от них избавиться.

Заполняем нулями эти два байта

0021df0: 322e 736f 2e34 006c 6962 706e 672e 736f 2.so.4.libpng.so
0021e00: 0000 006c 6962 6a70 6567 2e73 6f2e 3131 ...libjpeg.so.11

Выходим (обязательно) из hex-режима (Esc:%!xxd -r) и сохраняемся (Esc:wq)

Проверяем
$ ./php -v
PHP 5.2.17 (cgi) (built: Mar 12 2012 18:02:07)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies

На это ушло максимум 2 минуты, а это быстрее чем вспоминать старый конфиг, и компилировать.

P.S. На сервере стоит freebsd, а вытащить строку конфига, как выяснилось позже, можно было так

$ strings phpbad|grep \/configure|sed s/\'//g
./configure  --prefix=/var/www --with-mysql=/usr/local --enable-ftp --enable-dbase --with-gdbm --with-ndbm --with-iconv=/usr/local --with-gd=/usr/local --enable-gd-native-ttf=/usr/local --with-jpeg-dir=/usr/local --with-png-dir=/usr/local --with-freetype-dir=/usr/local --with-ttf --with-zlib-dir=/usr --disable-posix --enable-mbstring --enable-force-cgi-redirect --enable-inline-optimization --without-pear --disable-debug
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.