miércoles, abril 09, 2008

La aritmética de punteros, su desbordamiento y la seguridad

Me he enterado vía el valle del viento helado de una nueva polémica acerca de gcc y su implementación. El hecho es que gcc cambió su comportamiento en cuanto a comparaciones entre punteros incrementados y ha provocado muchos meses después una alerta de seguridad desproporcionada y según los desarrolladores de gcc, falsa (Se puede oír desde aquí el ruido y la furia)

El caso es que, entrando en profundidad, es una optimización casi "trivial" que hace que p + C1 < p + C2 pase a ser C1 < C2 sin tener en cuenta el posible desbordamiento (overflow) de ambas operaciones. Hay que decir además que el estándar (de C y de C++) declara no definido el valor del resultado de la suma entre un puntero y un entero cuando se sobrepasa el tamaño del objeto al que apunta.

Es muy importante este último punto, porque deja traslucir un error de concepto: la comprobación de overflow propuesta en la alerta(*) es muy burda porque sólo se comprueba el desbordamiento de la operación aritmética, no que nos estamos saliendo del rango permitido. Sin embargo lo que deben saber el programador y el programa a la vez, cuando están manejando aritmética de punteros es cual es el desplazamiento (offset) máximo, de cuanta memoria se dispone. Si eso no lo sabe, es inútil cualquier otra comprobación...

Hay que hacer notar además que la optimización de la que se habla aquí la aplican casi todos los compiladores y lo que provoca la alerta es en realidad el cambio de comportamiento, no que sea incorrecto.

También recuerda esto que es muy mala política basar el código en detalles de implementación específicos de la plataforma. En este caso y en muchos otros, los desarrolladores de gcc tiran de cita del estándar para argumentar sus decisiones. Los usuarios se quejan, llamándoles abogados del lenguaje (language lawyer) pero en momentos como esos hay que recordar que probablemente están defendiendo sus decisiones de implementación y lo importante de esas decisiones para el éxito de una tecnología.

(*)char *buf;
int len;
len = 1 << 30;
if (buf+len < buf){ Overflow }


La aritmética de punteros, su desbordamiento y la seguridad en barrapunto