¿Hay alguna manera de marcar un trozo de memoria asignada solo como lectura?


Si asigno algo de memoria usando malloc() hay una manera de marcarlo solo en lectura. Entonces memcpy() falla si alguien intenta escribirle?

Esto está conectado a un diseño de api defectuoso en el que los usuarios no usan un puntero const devuelto por un método GetValue() que es parte de una estructura de memoria grande. Dado que queremos evitar la copia de un gran trozo de memoria, devolvemos el puntero en vivo dentro de una memoria estructurada que es de un formato específico. Ahora el problema es que algunos usuarios encuentran hack para llegar allí cosas trabajando escribiendo en esta memoria directamente y evitando la llamada a setValue () que hace la asignación y entrega correctamente en formato binario de memoria que hemos desarrollado. Aunque hay hack en algún momento, pero en algún momento causa violación de acceso a la memoria debido a la interpretación incorrecta de las banderas de control que ha sido anulada por el usuario.

Educar al usuario es una tarea, pero digamos que por ahora queremos que el código falle.

Me pregunto si simplemente podemos protegernos contra esto caso.

Por analogía supongamos que alguien obtiene una columna blob de la instrucción sqlite y luego escribe de nuevo en ella. Aunque en el caso de sqlite no va a tener sentido pero esto algo pasando en nuestro caso.

Author: particle, 2013-02-18

3 answers

En la mayoría de las arquitecturas de hardware, solo puede cambiar los atributos de protección en todas las páginas de memoria ; no puede marcar un fragmento de una página de solo lectura.

Las API relevantes son:

Deberá asegurarse de que la página de memoria no contenga nada que no desee hacer de solo lectura. Para hacer esto, tendrá que sobreasignar con malloc(), o usar una asignación diferente API, tales como mmap(), posix_memalign() o VirtualAlloc().

 59
Author: NPE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-18 07:48:50

Depende de la plataforma. En Linux, puedes usar mprotect () (http://linux.die.net/man/2/mprotect).

En Windows puedes probar VirtualProtect () ( http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898 (v=vs.85). aspx). Aunque nunca lo he usado.

Editar: Esto no es un duplicado de la respuesta de NPE. NPE originalmente tenía una respuesta diferente; se editó más tarde y se agregaron mprotect() y VirtualProtect ().

 36
Author: Nikos C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-18 08:33:59

Un diseño de api defectuoso donde los usuarios no usan un puntero const devuelto por un método getValue() que es parte de una estructura de memoria grande. Dado que queremos evitar la copia de un gran trozo de memoria, devolvemos el puntero en vivo dentro de una memoria estructurada que es de un formato específico

Eso no es claramente un diseño de API defectuoso. Una API es un contrato: usted promete que su clase se comportará de una manera particular, los clientes de la clase prometen usar la API en el manera. Los trucos sucios como const_cast son impropios (y en algunos, pero no en todos los casos, tienen un comportamiento indefinido).

sería un diseño de API defectuoso si el uso de const_cast conduce a un problema de seguridad. En ese caso, debe copiar el fragmento de memoria o rediseñar la API. Esta es la norma en Java , que no tiene el equivalente de const (a pesar de que const es una palabra reservada en Java).

 4
Author: Raedwald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:45:56