Обходной путь для предупреждения Spectre MSVC C5040 - PullRequest
0 голосов
/ 17 мая 2018

MSVC только что выпустил обновление, в которое добавлено новое предупреждение о некотором коде, который компилятор введет, чтобы смягчить (по-видимому, немного) Spectre:

https://blogs.msdn.microsoft.com/vcblog/2018/01/15/spectre-mitigations-in-msvc/

Вот немногоMCVE получен из их примера «проблемного» кода:

#include <stdio.h>

int main(int argc, char *argv) {
    unsigned char array1[1] = {0};
    int array1_length = 1;
    unsigned char array2[1] = {99};
    int untrusted_index = 0; /* in this MCVE, I trust it, compiler doesn't */
    for (; untrusted_index < array1_length; ++untrusted_index) {
        unsigned char value = array1[untrusted_index];
        unsigned char value2 = array2[value * 64];
        printf("Picked value %d\n", value2);
    }
    return 0;
}

». В приведенном выше примере код выполняет проверку границ массива, чтобы убедиться, что значение untrusted_index меньше длины массива 1. Этонеобходимо, чтобы программа не читала за пределами массива. Несмотря на то, что это выглядит так, как будто записано, оно не учитывает микроархитектурное поведение ЦП, связанное со спекулятивным выполнением. "

Таким образом, теперь вы получаете предупреждение:

Предупреждение C5045: Компилятор вставит смягчение Spectre для загрузки памяти, если указан переключатель / Qspectre

То естьэто способ сказать вам, что этот код может оказаться медленнее, чем вам хотелось бы (если он скомпилирован / Qspectre), потому что он собирается вставитьнекоторые дополнительные средства защиты.

Поскольку кажется, что вы не можете принимать что-либо как должное, я с подозрением отношусь к изменениям, которые "просто убирают предупреждение" .Например, изменение untrusted_index < array1_length на untrusted_index != array1_length, кажется, делает это, для конкретного экземпляра кода MCVE, который я здесь привожу .Но это жизнеспособный патч или его предупреждение просто неполное - и в следующем обновлении он тоже будет жаловаться на это?

Я знаю, что могу отключить предупреждение с помощью / wd5040 илииначе.Но я заинтересован в том, чтобы убедиться, что если код скомпилирован с / Qspectre, что нет замедлений, и что нет предупреждений, если он не скомпилирован с / Qspectre.Я не хочу касаться файлов, изменяющих < на != в условиях цикла - или что-то еще - если это просто отток.

Так что больший вопрос будет, если естьзаконные схемы обхода, которые являются такими основными, почему нет некоторых упоминаний о них?Например, описанный мной случай - это итерация, в которой я контролирую индекс, и мне не нужно беспокоиться об этом из «ненадежного источника».И все же я получил предупреждение, и переключение с < на != заставило его уйти.Зачем?Должен ли он иметь?

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Из самой статьи:

Важно отметить, что существуют ограничения для анализа, который MSVC и компиляторы в целом могут выполнять при попытке идентифицировать экземпляры варианта 1. Таким образом, существуетнет никакой гарантии, что все возможные экземпляры варианта 1 будут описаны в /Qspectre.

Вы, вероятно, столкнулись с одним из случаев, когда текущая реализация / Qspectre не будет уменьшать уязвимость путем разработки,Это разумно, потому что чрезмерное использование LFENCE может значительно снизить производительность.Смягчение каждого отдельного экземпляра варианта 1, присутствующего в коде, слишком дорого, чтобы полностью выполнить его в программном обеспечении (используя LFENCE).

В комментариях кто-то спросил:

МожетВы характеризуете для разработчиков ограничения MSVC и что еще нужно сделать разработчикам, чтобы защитить себя от «варианта 1»?

Автор статьи ответил:

Мы не будем вдаваться в подробности реализации MSVC.Многие люди и компании полагаются на наши инструменты, поэтому мы будем осторожны с тем, что мы обсуждаем публично.

Так что, похоже, Microsoft не хочет раскрывать точнокакие экземпляры варианта 1 не будут смягчены /Qspectre.

0 голосов
/ 18 мая 2018

Если вы не хотите получать предупреждение, просто используйте предупреждение #pragma (отключите: 5040) или отключите его на странице свойств проекта.

И обратите внимание, что предлагаемое вами изменение на "untrusted_index! = Array1_length"этого недостаточно, поскольку он оставляет весь диапазон больше, чем размер, открытый для злоупотреблений.

Помните, что эта диагностика просто говорит вам, что компилятор будет делать что-то другое, чем раньше, с включенным смягчением спектра, на самом деле это не говорит вамчто вам обязательно нужно сделать что-нибудь с кодом.

...