On Thu, 26 Jan 2006, Frank Heckenbach wrote:
Adriaan van Os wrote:
Is Pascal and namely GNU Pascal safer re: buffer overruns? How much does runtime range checking help
Thank you for this link, Adriaan,
(Of course, the answer of Mr. Waldek Hebisch is depending on entire run/time system being (re)compiled with range checking on IMHO. Otherwise a runtime overrun could happen inside a system function when unchecked?)
Additionally I am interested whether there is a plan to introduce NX bit support (or emulation), and about StackGuard or similar "canary" protection.
Does NX bit use depend on compiler support at all, or is it completelly OS-supported/dependent? I reckon there ought to be something in RTS mmap()-ing stack area with PROT_EXEC disabled or am I wrong?
Yes. In particular, some holes are intentional, either for compatibility with other dialects (pointer-arithmetic etc.), or for performance reasons (possibility to turn off checks).
There are other holes, such as dangling pointers and using unintialized variables, which GPC cannot detect at all yet. It might do in the future, but implementing them will be very hard, so don't hold your breath.
Thank you for your reply, Frank,
In fact, this came to my mind in few considerations too: I was thinking of new breed of pointers that would allow for memory map defragmentation. As said somewhere in theoretical books, after millions of seemingly random allocations/deallocations - memory looks completely fragmented, and wtih equally distributed holes and used spaces. This as you must have noted means that actual system memory used is at least twice the malloc() allocated memory, since the holes cannot be defragmented or compacted.
This is why I would like to propose "registered pointers" (maybe it came subconsciously from Java?) and memory allocation library that would have a better heap use and corruption detection.
Registered pointers are close in semantics to pointers with ranges already intorduced on the list, but they should also allow defragmentation of the memory on-the-fly, compacting of free space and deallocating and returning ampped pages back to system (unlike current memory allocators that behave like my country's budget: they only grow and become less efficiently used with time ...).
Is that too difficult to implement?
(I am sorry if this has been discussed already.)
To explain the idea more visibly, as we are all probably tired at 4 PM:
Every pointer would be registered in a pointer table or list *depending on implementation*
Pointers would be indirect, used through a mechanism that would allow transparent moving of memory fragment pointed to.
A garbage collection mechanism would browse through all pointers and defragment memory, much like a file system, moving used memory towards beginning, free memory towards end of memory mapping, so it could be later munmap()-ed and returned to OS when certain LOW_WATERMARK or threshold is reached
Unused fragments of memory that are not explicitly free()-ed could be deallocated automatically and an optional warning could be generated
Safe garbage collection memory allocator could and probably should be mapped in separate address range from "normal" heap memory mapping that permits direct use and hacking of pointers
Better heap use would allow for introducing "heap canary" technique that would eliminate another source of exploits
All could be done transparent, without changing existing code
Better heap integirty checking would be introduced to existing programs, detecting memory leaks as warnings
That's the general idea, but I haven't tried implementation yet.
Compatible programs could simply be linked with new library and have the advantage of better memory use, better heap integrity and possibly longer uptime without need to reboot system because of memory leaks because of fragmentation.
I went far from original question, but this idea is tempting me for a long time, and GPC development team seems open enough :-) that I thought of requesting implementation or putting it on the wish list.
and to what extent can we depend on it?
Adriaan wrote:
The only thing you can depend on in programming is clear thinking. Don't trust anything that promises you automatic wonders.
I don't. But this would be simply a means of debugging, not an electric fense for intruders. As well as new heap mechanism described above.
Frank wrote:
Yes. Though it might help thinking clearly when you don't have to worry about every little detail (such as basically every C-string operation, which can be dangerous if not careful; note, I said C-string, so using C-strings in Pascal is just as dangerous as in C, of course).
Understood.
Is it acceptable to write setuid root programs in GPC and what are the cautions?
From http://en.wikipedia.org/wiki/Setuid
"While the setuid feature is very useful in many cases, it can however pose a security risk if the setuid attribute is assigned to executable programs that are not carefully designed. Users can exploit vulnerabilities in flawed programs to gain permanent elevated privileges, or unintentionally execute a trojan horse program."
I think "carefully designed" is the keyword (and ask yourself if that applies to the C and C++ programming languages (...)).
Indeed. But apart from the programming language, the same applies to your program as well. Even a perfectly secure programming language and environment don't help if your program, e.g., executes another program carelessly. No amount of string and buffer checking helps if the program allows the name of the program to be executed to be supplied by an attacker, say /bin/sh ...
As for the original question about buffer overruns (only), Pascal in general and GPC in particular should be quite a bit safer than C, *if* you turn on all checks and use only high-level features (this excludes, e.g., the address operator, type-casts, abuse of variant records, low-level routines such as GetMem, Move and FillChar, calls to unsafe external routines (assembler, C, or whatever), and probably much more).
This is what I wanted to know. Since system programs have security a greater priority than runtime efficiency, I would not turn the range checks off.
The "only" problem is implementing all those low-level interfaces to be used from GNU Pascal in elegant manner.
Please consider the new heap allocation system proposal above and comment on it. I ma sorry if it is already made by someone, I give my word I did not steal intentionally.
Sorry for length of this email, I am not very good with being laconic in English. :-)
Mirsad