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


Tal vez pueda interesarte


Compartí este artículo