En este artículo voy a explicar cómo compilar una versión específica de un paquete, aplicando los últimos parches disponibles.
Como ha sido de público conocimiento, recientemente surgió una vulnerabilidad grave para el intérprete de comandos Bash que afectó a una gran cantidad de servidores GNU/Linux. Para resolver esta vulnerabilidad basta simplemente con actualizar el sistema, ya que, como es de costumbre, todas las distribuciones liberaron una actualización para el paquete Bash inmediatamente. Pero, ¿qué pasa si necesitamos una versión en particular compilada desde los fuentes? En este escenario es necesario compilar la versión en cuestión aplicando todos los parches que se han liberado desde la misma. Para ello se debe utilizar la herramienta patch
.
La herramienta patch se utiliza para realizar modificaciones en archivos en modo batch, a partir de archivos diff fuente. Por defecto, patch lee desde entrada estándar.
$ man patch
En mi caso necesitaba compilar la versión 3.2 de Bash. Entonces el primer paso consiste en descargar su código fuente desde el sitio oficial (www.gnu.org/software/bash/):

Acceder al enlace "GNU mirrors" y seleccionar uno cercano a nuestra ubicación:

Luego navegar hasta la carpeta bash/
:

Descargar el paquete bash-*.tar.gz
correspondiente a la versión específica, por ejemplo bash-3.2.48.tar.gz
si se desea compilar la versión 3.2
:

Luego, para cada versión existe una carpeta *-patches/
que contiene todos los parches específicos de cada rama. Para la versión 3.2
, navegar hasta la carpeta bash-3.2-patches/
:

Descargar todos los parches liberados a partir de la versión del paquete:

Por ejemplo, si se descargó el paquete bash-3.2.48.tar.gz
se deben descargar los parches a partir del 49 en adelante.
Si se trata de un servidor remoto, tal vez es preferible copiar los enlaces para descargarlos utilizando wget
. Entonces, cambiar a un directorio conveniente para guardar código fuente:
$ cd /usr/local/src/
Descargar el código fuente de Bash para la versión requerida (en este caso la 3.2
), junto con todos los parches que se han liberado a partir de la misma:
$ wget http://mirror.sdunix.com/gnu/bash/bash-3.2.48.tar.gz $ wget http://mirror.sdunix.com/gnu/bash/bash-3.2-patches/bash32-049 $ wget http://mirror.sdunix.com/gnu/bash/bash-3.2-patches/bash32-050 $ wget http://mirror.sdunix.com/gnu/bash/bash-3.2-patches/bash32-051 $ wget http://mirror.sdunix.com/gnu/bash/bash-3.2-patches/bash32-052 $ wget http://mirror.sdunix.com/gnu/bash/bash-3.2-patches/bash32-053 $ wget http://mirror.sdunix.com/gnu/bash/bash-3.2-patches/bash32-054
Como mencioné anteriormente, al haber descargado la versión "3.2.48" es recomendable aplicar todos los parches >48 (es decir 49, 50, 51...).
Luego de descargar todos los parches, tenemos todo lo necesario para extraer, parchar y compilar:
[root@linuxito.com src]# ll total 2508 -rw-r--r-- 1 root root 1663 Sep 29 12:11 bash32-049 -rw-r--r-- 1 root root 1697 Sep 29 12:11 bash32-050 -rw-r--r-- 1 root root 1371 Sep 29 12:11 bash32-051 -rw-r--r-- 1 root root 3250 Sep 29 12:11 bash32-052 -rw-r--r-- 1 root root 1115 Sep 29 12:11 bash32-053 -rw-r--r-- 1 root root 6617 Sep 29 12:11 bash32-054 -rw-r--r-- 1 root root 2539329 Sep 29 12:11 bash-3.2.48.tar.gz
Extraer el contenido del paquete:
$ tar xf bash-3.2.48.tar.gz
Revisar cada parche para determinar qué cambios realizan y cómo aplicarlos:
$ less bash32-049 $ less bash32-050 $ less bash32-051 $ less bash32-052 $ less bash32-053 $ less bash32-054
Por ejemplo, el parche bash32-052
indica que debe ser aplicado con la opción -p0
:
apply with `patch -p0'
Cambiar al directorio extraído:
$ cd bash-3.2.48/Las instrucciones y opciones de instalación se encuentran en los archivos README
e INSTALL
:
$ less README $ less INSTALL
Aplicar todos los parches, en orden, utilizando la herramienta patch
y redireccionando la entrada estándar. Si no se encuentra instalada en el sistema, instalarla ejecutando yum install patch
en Red Hat/Fedora/CentOS y apt-get install patch
en Debian/Ubuntu y derivados.
[root@linuxito.com bash-3.2.48]# patch -p0 < ../bash32-049 patching file lib/readline/mbutil.c patching file patchlevel.h
[root@linuxito.com bash-3.2.48]# patch -p0 < ../bash32-050 patching file lib/readline/mbutil.c patching file patchlevel.h
[root@linuxito.com bash-3.2.48]# patch -p0 < ../bash32-051 patching file builtins/read.def patching file patchlevel.h
[root@linuxito.com bash-3.2.48]# patch -p0 < ../bash32-052 patching file builtins/common.h patching file builtins/evalstring.c patching file variables.c patching file patchlevel.h
[root@linuxito.com bash-3.2.48]# patch -p0 < ../bash32-053 patching file parse.y patching file patchlevel.h
[root@linuxito.com bash-3.2.48]# patch -p0 < ../bash32-054 patching file variables.c patching file patchlevel.h
En la salida de patch se listan los archivos que se han actualizado.
Luego de aplicar todos estos parches, se ha pasado de la versión 3.2.48
a 3.2.54
.
Ahora es posible compilar el paquete como de costumbre:
# ./configure
# make
# make install
Para más información: man patch