Ядро Linux в комментариях

Proc_dointvec_minmax


Функция proc_dointvec_minmax почти аналогична do_proc_dointvec, за исключением того, что она дополнительно рассматривает члены extra1 и extra2 входа таблицы как массивы ограничений на те значения, которые могут быть записаны во вход таблицы. Значения в extra1 представляют собой минимумы, а значения в extra2 — максимумы. Еще одним отличием является то, что функция proc_dointvec_minmax не имеет параметра conv.

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

Вот самое значительное различие: при записи значения, выходящие за пределы диапазона, определенного величинами min и max (которые берутся в цикле из массивов extra1 и extra2), молча пропускаются. Очевидно, назначение этого кода состоит в обработке min и max наряду с val. После того, как значение будет считано со входа, оно должно быть проверено по отношению к следующему значению min и следующему значению max, а затем либо принято, либо пропущено. Однако это происходит не совсем так. Предположим, что текущее значение из буфера, которое было интерпретировано и записано в переменную val, меньше минимума; предположим также ради уточнения, что это третья итерация цикла, поэтому и min, и max указывают на третьи элементы соответствующих им массивов. Тогда значение val будет проверено по min и будет обнаружено, что оно выходит за пределы диапазона (слишком мало), поэтому цикл будет продолжен. Однако в качестве побочного эффекта этой проверки значение min будет обновлено, а значение max — нет. Теперь min указывает на четвертый элемент соответствующего ему массива, a max все еще указывает на третий элемент своего массива. Эти две величины не согласованы друг с другом и таковыми и останутся, поэтому следующее значение (и в действительности, все последующие значения), считанные из буфера, могут проверяться по неправильному пределу. Ниже описано простейшее исправление:

if (min && val < *min++) { ++max; /* Синхронизация значений max и min. */ continue; } if (max && val > *max++) continue;

Однако, как вы узнаете далее из этой главы, оказывается, что эта ошибка никогда не проявит себя в текущем исходном коде Linux. (Другое дело — будущие выпуски, но это еще не написанный роман.)



Содержание раздела