если я выделю немного памяти, используя malloc()
Есть ли способ пометить его только для чтения. Таким образом, memcpy () не работает, если кто-то пытается написать в него?
Это связано с неправильным дизайном API, где пользователи не используют константный указатель, возвращаемый методом GetValue()
которая является частью большой структуры памяти. Поскольку мы хотим избежать копирования большого фрагмента памяти, мы возвращаем живой указатель в структурированной памяти определенного формата. Теперь проблема в том, что некоторые пользователи находят хак, чтобы заставить их работать, записывая в эту память напрямую и избегая вызова SetValue (), который выполняет выделение и правильную передачу в двоичном формате памяти, который мы разработали. Хотя иногда взломать работу, но иногда это вызывает нарушение доступа к памяти из-за неправильной интерпретации контрольных флагов, которые были переопределены пользователем
Обучение пользователей — это одна из задач, но, скажем, пока мы хотим, чтобы код не работал.
Мне просто интересно, сможем ли мы просто защитить от этого случая.
Для аналогии предположим, что кто-то получил столбец BLOB-объекта из оператора sqlite, а затем записал обратно. Хотя в случае с sqlite это не имеет смысла, но в нашем случае это несколько не так.
На большинстве аппаратных архитектур вы можете изменять только атрибуты защиты на всей страницы памяти; Вы не можете пометить фрагмент страницы только для чтения.
Соответствующие API:
mprotect()
в Unix;VirtualProtect()
на винде.Вам нужно убедиться, что страница памяти не содержит ничего, что вы не хотите делать только для чтения. Для этого вам придется либо перераспределить с malloc()
или используйте другой API распределения, такой как mmap()
, posix_memalign()
или же VirtualAlloc()
,
Зависит от платформы. В Linux вы можете использовать mprotect () (http://linux.die.net/man/2/mprotect).
В Windows вы можете попробовать VirtualProtect () (http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898(v=vs.85).aspx). Я никогда не использовал это все же.
Редактировать:
Это не дубликат ответа NPE. У NPE изначально был другой ответ; это было отредактировано позже, и были добавлены mprotect () и VirtualProtect ().
неправильный дизайн API, где пользователи не используют константный указатель, возвращаемый методом GetValue (), который является частью большой структуры памяти. Поскольку мы хотим избежать копирования большого фрагмента памяти, мы возвращаем живой указатель в структурированной памяти определенного формата.
Это не явно неправильный дизайн API. API — это контракт: вы обещаете, что ваш класс будет вести себя определенным образом, клиенты этого класса обещают использовать API надлежащим образом. Грязные трюки, как const_cast
являются неправильными (и в некоторых, но не во всех неопределенное поведение).
Это было бы Неправильный дизайн API при использовании const_cast
привести к проблеме безопасности. В этом случае вы должен скопируйте кусок памяти или перепроектируйте API. Это норма в Java, который не имеет эквивалента const
(несмотря на const
быть зарезервированным словом в Java).