Pull to refresh

История однострочных багов

Reading time2 min
Views43K
Компания Apple недавно допустила крупную ошибку, забыв удалить лишнюю строчку с оператором безусловного перехода goto посередине функции SSLVerifySignedServerKeyExchange для проверки серверной подписи при установке SSL-соединения. В результате, функция успешно завершала работу, независимо от результата проверки подписи.

Однако, это не первый случай в истории, когда критическая ошибка объясняется единственной строчкой кода. Вот ещё несколько таких примеров.

X Server


В 2006 году было обнаружено, что X Server проверяет рутовые права у пользователя, но при этом разработчики в реальности забыли вызвать соответствующую функцию.

--- hw/xfree86/common/xf86Init.c
+++ hw/xfree86/common/xf86Init.c
@@ -1677,7 +1677,7 @@
   }
   if (!strcmp(argv[i], "-configure"))
   {
-    if (getuid() != 0 && geteuid == 0) {
+    if (getuid() != 0 && geteuid() == 0) {
        ErrorF("The '-configure' option can only be used by root.\n");
        exit(1);
     }


Debian OpenSSL


В 2008 году Debian признала, что генератор псевдослучайных чисел в её «фирменной» реализации OpenSSL от 2006 года на самом деле генерирует предсказуемые числа.

--- openssl-a/md_rand.c
+++ openssl-b/md_rand.c
@@ -271,10 +271,7 @@
                else
                        MD_Update(&m,&(state[st_idx]),j);

-/*             
- * Don't add uninitialised data.
                MD_Update(&m,buf,j);
-*/
                MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
                MD_Final(&m,local_md);
                md_c[1]++; 

Причина в том, что важную строчку включили в комментарий. Совершенно непонятно, как такой заметный баг попал в финальный релиз, как будто никто вообще не проверял код. Кстати, многие тогда заподозрили Debian в том, что она «поломала» ГПСЧ не случайно.

Стандартный OpenSSL


Ещё один баг в OpenSSL, и опять из 2008 года. OpenSSL 0.9.8i и более ранние версии «некорректно проверяли значение, которое возвращает функция EVP_VerifyFinal, что позволяло злоумышленникам обходить валидацию сертификата с помощью поддельных подписей SSL/TLS для ключей DSA и ECDSA».

 --- lib/libssl/src/ssl/s3_srvr.c
+++ lib/libssl/src/ssl/s3_srvr.c
@@ -2009,7 +2009,7 @@ static int ssl3_get_client_certificate(S
 	else
 		{
 		i=ssl_verify_cert_chain(s,sk);
-		if (!i)
+		if (i <= 0)
 			{
 			al=ssl_verify_alarm_type(s->verify_result);
 			SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED); 

Android


Посмотрите на патч для memset.c от 11 мая 2010 года.

--- libc-a/memset.c
+++ libc-b/memset.c
@@ -1,6 +1,6 @@
 void *memset(void *_p, unsigned v, unsigned count)
 {
     unsigned char *p = _p;
-    while(count-- > 0) *p++ = 0;
+    while(count-- > 0) *p++ = v;
     return _p;
 }

Вместо корректного параметра в память записывается нуль. То есть один из передаваемых в функцию параметров вообще не используется.

Tarsnap


Автор программы Tarsnap, онлайн-сервиса защищённого хранения резервных копий на Amazon S3, в 2011 году сообщил о баге в процедуре генерации случайного значения (nonce) при шифровании данных.

--- tarsnap-autoconf-1.0.27/lib/crypto/crypto_file.c
+++ tarsnap-autoconf-1.0.28/lib/crypto/crypto_file.c
@@ -108,7 +108,7 @@

        /* Encrypt the data. */
        if ((stream =
-           crypto_aesctr_init(&encr_aes->key, encr_aes->nonce)) == NULL)
+           crypto_aesctr_init(&encr_aes->key, encr_aes->nonce++)) == NULL)
                goto err0;
        crypto_aesctr_stream(stream, buf, filebuf + CRYPTO_FILE_HLEN, len);
        crypto_aesctr_free(stream);

Новое случайное значение должно было генерироваться для каждых 16 байт шифруемых данных, но в реальности оно вообще не менялось.

Так что не только Apple допускает ошибки.
Tags:
Hubs:
Total votes 142: ↑118 and ↓24+94
Comments90

Articles