Выпуск Git 2.4.11, 2.5.5 и 2.6.6 и 2.7.4 с устранением критических уязвимостей
Информация об уязвимостях была раскрыта несколько дней назад, при этом выявивший уязвимость разработчик был уверен, что уязвимости были устранены в начале февраля в выпуске 2.7.1. На деле, оказалось, что патчи (1, 2) были приняты только в ветку master, на основе которой формируется выпуск 2.8, но исправления забыли включить в релиз 2.7.1 и проблема осталась не исправленной, что поставило под угрозу Git-хостинги, такие как Github и Bitbucket, а также публичные Git-репозитории на базе Gerrit и Gitlab. Около месяца исправления оставались на виду, что давало возможность злоумышленникам оценить связанную с ними угрозу безопасности и разработать рабочий эксплоит.
Сервер может быть атакован в случае доступа злоумышленников к выполнению команды push (например, публичные git-хостинги). Атака также может быть совершена на клиента, выполняющего операцию "clone" при обращении к ранее атакованному или подконтрольному злоумышленникам серверу. В GitHub проблема была устранена ещё в феврале. В GitLab для блокирования возможных атак был нацелен выпуск 8.5.7, но он не устранил проблему, так как защита заключалась в запрещении использования версий Git младше 2.7.3 (на деле уязвимость оказалась исправлена только в Git 2.7.4).
Уязвимость вызвана ошибкой в реализации функции path_name(), позволяющей инициировать переполнение буфера при манипуляции с большим числом вложенных деревьев или слишком длинным именем файла. Размер имени файла сохраняется в знаковую целочисленную переменную, рассчитывается размер пути, выделяется память и имя файла копируется в хвост буфера при помощи незащищённой функции strcpy. В случае целочисленного переполнения переменной, содержащей размер строки, будет создан буфер заведомо меньшего размера и копирование будет осуществлено в область за пределами буфера.
char *path_name(const struct name_path *path, const char *name) { const struct name_path *p; char *n, *m; int nlen = strlen(name); int len = nlen + 1; for (p = path; p; p = p->up) { if (p->elem_len) len += p->elem_len + 1; } n = xmalloc(len); m = n + len - (nlen + 1); strcpy(m, name); for (p = path; p; p = p->up) { if (p->elem_len) { m -= p->elem_len + 1; memcpy(m, p->elem, p->elem_len); m[p->elem_len] = '/'; } } return n; }
Источник: http://www.opennet.ru/opennews/art.shtml?num=44068
|
0 | Tweet | Нравится |
|