2013-11-29 12 views
2

Когда вы пишете безопасный код в прямом C, я устал придумывать цифры , чтобы представлять ограничения - в частности, максимальное количество памяти для выделения одной строки текста. Я знаю, что всегда могу сказать вещи, какИспользование sysctl (3) для написания безопасного, портативного кода: хорошая идея?

#define MAX_LINE_LENGTH 1024 

, а затем передать этот макрос к таким функциям, как snprintf().

Я работаю и кодируюсь в NetBSD, который имеет переменную sysctl (3), называемую «user.line_max», предназначенную для этой цели. Поэтому мне не нужно выходить с произвольным номером, например MAX_LINE_LENGTH. Я просто прочитал переменную sysctl «user.line_max» , которая, кстати, настраивается пользователем.

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

И для записи «переносимость» в данном случае исключает Microsoft Windows.

ответ

1

Ну линукс SYSCTL (2) человек страница это сказать в разделе Примечания:

Glibc не предоставляет обертку для этого системного вызова; вызовите его, используя syscall (2). Вернее ... не называйте это: использование этого системного вызова уже давно обескуражено, и оно настолько нелюбоподобно, что оно, скорее всего, исчезнет в будущей версии ядра. Удалите его из своих программ сейчас; вместо этого используйте интерфейс/proc/sys.

Так что это одно соображение.

+0

Ew, yuck. Хорошо знать. – christiank

1

Неплохая идея. Даже если бы не то, что сказал вам Duck, полагаясь на общесистемную настройку, которая является переменной времени выполнения, является плохим дизайном и подвержена ошибкам. Если вы столкнулись с проблемой изменения ограничений размера буфера (что обычно требует динамического выделения и проверки на отказ), вы должны перейти на последний шаг и настроить его на более локальную область.

С вашим примером ограничений размера буфера мнения отличаются друг от друга относительно наилучшей практики. Некоторые люди думают, что вы всегда должны использовать динамически растущие буферы без жесткого ограничения. Другие предпочитают фиксированные пределы, достаточно большие, чтобы разумные данные не превышали их. Или, как вы заметили, настраиваемые лимиты являются опцией. Выбирая то, что подходит для вашего приложения, я буду рассматривать последствия для пользователей. Уверенные пользователи не любят произвольные ограничения, но им также не нравится, когда случайно (или чужой злобой) чтение данных без новых строк в нем заставляет ваше приложение потреблять неограниченное количество памяти, начать замену и/или в конечном итоге аварии или болота всей системы.

+0

Фактически, переменная sysctl «user.line_max» не может быть изменена во время выполнения, по крайней мере, на NetBSD - это постоянная жестко закодированная в ядре ОС.Вы можете изменить его только при компиляции нового ядра. Сохранение конфигураций более локально - тоже хорошая идея, теперь, когда я думаю об этом. – christiank

0

1) Проверьте Unix Specification Single, ключевое слово: "пределы"

2) s/безопасность/безопасность/

+0

Итак, комментарий к limit.h указывает, что «приложения не должны принимать какое-либо особое значение для ограничения» для достижения максимальной переносимости. Означает ли это, что это «неправильно» (что бы это ни значило) для того, чтобы код включал определенные пользователем ограничения, такие как мой пример «MAX_LINE_LENGTH», выше? Я все время вижу подобные вещи в дикой природе. – christiank

1

Ближайшим портативная конструкция для этого является "getconf LINE_MAX" или эквивалент C.