Есть ли способ отметить фрагмент выделенной памяти только для чтения?

если я выделяю некоторую память с помощью malloc(), есть способ отметить ее только для чтения. Так memcpy() терпит неудачу, если кто-то попытается написать ему?

Это связано с неисправной архитектурой api, где пользователи пропускают указатель const, возвращаемый методом GetValue(), который является частью большой структуры памяти. Поскольку мы хотим избежать копирования большого фрагмента памяти, мы возвращаем живой указатель внутри структурированной памяти, которая имеет определенный формат. Теперь проблема в том, что некоторые пользователи находят хак, чтобы получить там вещи, работающие при записи в эту память напрямую, и избегать вызова SetValue(), который выполняет распределение и правильную передачу двоичного формата памяти, который мы разработали. Несмотря на то, что когда-то работал, но иногда он вызывает нарушение доступа к памяти из-за неправильной интерпретации контрольных флагов, которые были отменены пользователем.

Воспитание пользователя - одна из задач, но позвольте сказать, что сейчас мы хотим, чтобы там был сбой кода.

Мне просто интересно, можем ли мы просто защитить от этого случая.

Для аналогии предположим, что кто-то получает столбец blob из оператора sqlite, а затем записывается обратно. Хотя в случае sqlite это не будет иметь смысла, но это несколько хлопот в нашем случае.

Ответ 1

На большинстве аппаратных архитектур вы можете изменять атрибуты защиты только на целых страницах памяти; вы не можете отметить фрагмент страницы только для чтения.

Соответствующие API-интерфейсы:

Вам нужно убедиться, что страница памяти не содержит ничего, что вы не хотите делать только для чтения. Для этого вам придется либо комбинировать с malloc(), либо использовать другой API распределения, например mmap(), posix_memalign() или VirtualAlloc().

Ответ 2

Зависит от платформы. В 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().

Ответ 3

ошибочная конструкция api, где пользователи пропускают указатель const, возвращаемый методом GetValue(), который является частью большой структуры памяти. Поскольку мы хотим избежать копирования большого фрагмента памяти, мы возвращаем указатель живого изображения внутри структурированной памяти, которая имеет определенный формат

Это явно не ошибка дизайна API. API - это контракт: вы обещаете, что ваш класс будет вести себя определенным образом, клиенты этого класса обещают использовать API надлежащим образом. Грязные трюки типа const_cast являются неправильными (и в некоторых, но не во всех случаях, имеют undefined поведение).

Было бы ошибкой дизайн API, если использование const_cast приведет к проблеме безопасности. В этом случае вы должны скопировать кусок памяти или перепроектировать API. Это норма в Java, которая не имеет эквивалента const (несмотря на const являющееся зарезервированным словом в Java).

Ответ 4

Обсудить указатель. т.е. вернуть клиенту указатель плюс смещение, теперь они не могут использовать указатель напрямую. всякий раз, когда указатель передается в ваш код через официальный API, вычитайте смещение и используйте указатель как обычно.