7

The const type qualifier causes the compiler to issue an error message in case an attempt to modify an object declared as const,but that is not enough protection.For example the following program modifies both elements of the array declared as const:

#include <stdio.h>

int main(void)
{
    const char buf[2] = { 'a','b' };
    const char *const ptr = buf;
    unsigned long addr = (unsigned long)ptr;

    *(char *)addr = 'c';
    addr = addr + 1;
    *(char *)addr = 'd';

    printf("%c\n", buf[0]);
    printf("%c\n", buf[1]);
    return 0;
}

So,it turns out to be that the compiler is not enough guard to protect the objects from being modified.How can we prevent this sort of thing?

  • 2
    Use an architecture with a real *read-only* memory, and store your constants there. Or switch a programming language. BTW, when you are trying to *protect* something, first specify the threats. Who are you trying to protect it from? From yourself? – Eugene Sh. Apr 12 '16 at 13:30
  • 1
    In this case the best protection would be the learning of the language, following good coding practices and standards. Or, again, use a safer language. `C` is assuming that the programmer is smarter than the compiler :) – Eugene Sh. Apr 12 '16 at 13:36
  • OK, then blow it into ROM like @EugeneSh. suggests. If specialist hardware is required to modify it, you cannot then do so my mistake. – Martin James Apr 12 '16 at 13:37
  • Something as simple as a DIP-clip that disables writing would do it. Your dodgy software would be unable to fit a physical link. – Martin James Apr 12 '16 at 13:38
  • @Suki: As you've shown, you have to put in some effort to work around the `const` qualifier; are you afraid you'll write such code by accident? – John Bode Apr 12 '16 at 13:42
  • 1
    See also [Can we change the value of a constant through pointers?](http://stackoverflow.com/a/3801601/33499) and [Does the evil cast get trumped by the evil compiler?](http://stackoverflow.com/q/712334/33499). – wimh Apr 12 '16 at 13:42
  • 2
    If you explicitly cast things just to get rid of const you can also bypass any other memory protection other than physical. Don't cast away const and you'll be fine 99% of the time. The language gives you all the power you might want, including the power to override most protections. – Art Apr 12 '16 at 13:44
  • The cast is bad practice because it relies on implementastion defined behaviour to unnecessary high degree and does not work on many systems (e.g. 64 bit with I32P64). Use `(u)intptr_t` to store a pointer to an integer. It is hopefully unnecessary that your conversion invokes undefined behaviour, too - even iff there is no data lost by the conversion. As @EugeneSh. wrote, either you have to accept the bounds C imposes or switch to a language more forgiving. If you stay with C, enable all useful compiler warnings (just read the documentation, understand what they mean and enable all useful). – too honest for this site Apr 12 '16 at 13:44
  • Possible duplicate of [When to use const void\*?](http://stackoverflow.com/questions/34842224/when-to-use-const-void) – bolov Apr 12 '16 at 13:49
  • This has been asked many times before. [Here](http://stackoverflow.com/questions/35646493/can-gcc-warn-me-about-modifying-the-fields-of-a-const-struct-in-c99) for example. – Lundin Apr 12 '16 at 13:59
  • Any "higher" level of protection is going to be system-specific and outside the bounds of the standard C language. So if you really need this, you'll have to say what system you want to target. For instance, on POSIX systems, you could place the object on its own page and use `mprotect` to make that page read-only; attempts to write to it would cause a segmentation fault. – Nate Eldredge Apr 12 '16 at 14:05

3 Answers3

3

I don't think more protection can nor should be provided.

The C programming language lets you do almost everything you want freely, especially accessing objects from pointers. However, freedom is never free, so C programmers must always be careful (and avoid casting if it isn't necessary).

nalzok
  • 14,965
  • 21
  • 72
  • 139
0

A standard tool for finding memory overruns is watchpoints, or data breakpoints as they are called in MS Visual Studio.

If you need to protect your object just for debugging, use your debugger to set a watchpoint inside your object. The bug will be discovered at runtime (not compile time) - when your program tries to write to the specified address, the debugger will stop it.

You might be able to set your watchpoints in your code, but their number is limited (the maximum is 4 on x86 platform), so this cannot be a general-purpose feature of your program.

Community
  • 1
  • 1
anatolyg
  • 26,506
  • 9
  • 60
  • 134
0

I think the philosophy behind protection is the comfort of one who is using your code as ready library in his own code. Otherwise if it was possible to make the object completely non-modifiable in C language, there would be some crackers who could modify whatever they want :) :)

Afshin
  • 392
  • 2
  • 11