"Users who often read vulnerability reports come across terms over and over again. Terms like buffer overflow, race condition, page fault, null pointer, stack exhaustion, heap exhaustion/corruption, use after free, or double free --all describe memory safety vulnerabilities.
Speaking at the BlueHat security conference in Israel last week, Microsoft security engineer Matt Miller said that over the last 12 years, around 70 percent of all Microsoft patches were fixes for memory safety bugs."
MiraclePtr< T> to address UseAfterFree bugs in Chrome ā¦
āThe BackupRefPtr algorithm is based on reference counting. It uses support of Chromeās own heap allocator, PartitionAlloc, which carves out a little extra space for a hidden reference count for each allocation.
Raw_ptr< T> increments or decrements the reference count when itās constructed, destroyed or modified.
When the application calls free/delete and the reference count is greater than 0, PartitionAlloc quarantines that memory region instead of immediately releasing it. The memory region is then only made available for reuse once the reference count reaches 0.ā
Surely the only point youāve made from this thread is to show Delphi isnāt memory safe and shouldnāt be on the list. Where Delphi doesnāt typically suffer from buffer overflow bugs (the only reason I can think of for it being on the list) it certainly doesnāt protect from many of the other issues like use after free etc
Some basic changes to the language like automatically initialising local variables would go a long way to helping make things much safer.
Agree, in so far as I donāt understand the reasons it ended up in the list. My de facto position before any of this came up was that OP is a nicer, more elegant, less spiky C++. So it was a surprise to me, as I said, to see it there.
That said, people put effort into these reports. Someone had reasons for making that evaluation, so we should probably figure out explicitly the pros and cons for our language in this context. AND create and promote guidelines for how to best utilise it for a certain level of āsafeā outcome.
Also ⦠hopefully, between this in the news,
and the efforts updating the C++Builder product line, Embarcadero will be energised to put new development attention into our favourite language.
The advertising has been done, essentially.
We have a chance to try to live up to it.
The link above about MiraclePtr suggests eg that maybe FastMM could be modified to do something similar.
@GrahameDGrieve already gave us a presentation that involved him doing his own memory manager. Maybe we need another talk on that subject.
The link above about MiraclePtr suggests eg that maybe FastMM could be modified to do something similar.
There is a great feature in C++Builder called CodeGuard which has been there for 25-odd years (but seems to be a bit flakey in recent times and now requires not using runtime libraries, I havenāt used it for a long time) that can catch a lot of memory safety issues. Using it does affect runtime performance but it can be enabled/disabled.
FastMM does some of those things, but others are very hard indeed for a memory manager to do. Or impossible.
I have written my own memory manager, but not anymore - I use fastMM. I do have a base object that does tracking / manual reference counting / debugging leak support, and I have talked a little about this. Iām happy to talk again about it, but itāll have to virtual - Iām on the road for the next 9 months
FastMM does some of those things, but others are very hard indeed for a memory manager to do. Or impossible.
I believe that some of them work as follows (Iād have to check my old article on CodeGuard to see if I knew how they worked back then - my memory manager deallocated that knowledge years ago ):
Access in freed memory: when a block is freed the mm overwrites the block with a pattern and delays actually releasing the memory for a while. Later, when it is time to release the memory it checks that the pattern is still intact and actually releases the memory. If the pattern was modified then an invalid write occurred. This doesnāt catch read access though. This technique detects write access to freed memory if it would have otherwise been reallocated for another purpose
Method called on freed object: Hook all class member functions. When the hook function is called check the implicit Self parameter against valid memory blocks and call the original function
Access overrun (also available in FastMM) and underrun: Add some guard memory to the start and end of each allocated block and fill with a pattern. When the object is freed check that the patterns are still intact. Again, wonāt catch an invalid read
Access uninitialized/invalid stack: Function hooks, check stack pointer and frame have just been initialized, maybe push a pattern on the stack, call the original function, maybe check pattern on return
To help catch access in freed memory immediately, at least where the memory is not reallocated, and to catch reads, you could use something to trigger AVās like the following instead of calling .Free:
procedure FreeAndInvalidate(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := $C0FFEE;
Temp.Free;
end;
var o := TThing.Create;
...
FreeAndInvalidate(o);
...
// Access member field or call a method that does = AV: read of address 00C0FFEE
if o.Something = 42 then ...
Calling FreeAndNil() also works but that would get mixed in with āaccess before allocatedā or other uninitialised ref code.
Delphi is usually pretty good at warning about uninitialised variables.
I will just add an appropriate var := value; statement, even when (rarely) I think it has it wrong.
Sometimes annoying when a newer version of the compiler warns that the initialisation value is not used⦠What to do then? Probably just leave it in, with a comment.
This is how I would deal with the issue
a update to Delphi
1/ TObject.free should always set the pointer to Nil so when writing code you know if the memory has been freed by looking at the pointer!!! everyone is thinking that way - can the complier or assembly code find the objectās pointer from inside the free statement to set the pointer to Nil in TObject.Free?
I have been working on an object of my own and I have a very irritating complier issue
when I declare a value with a type in my objectās procedure
1/ The type is always from another place than in the file
2/ It sometimes cannot identify the type!!!
It reminds me of a bad wiring joint that works when it wants to work!!!.
Very common types to Delphi
var
W: Word;
I64: Int64;
it is rarely I: Integer;
These a very common types Iām using but they are sometimes rejected by the complier
so i make Word64 = NativeUInt; in my file and no problems
Var
w64: Word64
why?
I have not had the problem with
Strings;
ShortStrings;
I need to admit I put my computer in sleep mode many times
And the editor sometimes does not fully work recovering from a sleep for some reason
So its about the proās and conās if TObject.Free NILed the pointer of TObject as the object was freed as Delphi user.
1/ I can test the pointer to see if its nil before so I do not create another TObject and loose the old pointer value. And that lowers the risk of memory leeks!!!
2/ another point is the creation of TObject and the pointer value already used (not Nil). That the object does not get created but instead old the pointer value is maintained until it is set to Nil. And that blocks the risk of memory leeks!!!
Example TObject,Create(Var NewObjectPtr: TObject) ; virtual;
Just an idea, you may have another or use both ideaās
The project Iām working on right now is only to have one object from the file to ever be executed at any one time. It has a single pointer in the file of this main object that other stuff uses in the file. When I create my Object I cannot stop the creation so I have to run a TList to remember created objects and then produce a delete of one of the objects.
Iām saying its messy code?
One Example TObject,CheckCreate(Var NewObjectPtr: TObject; NoAllowedObjects: integer default 0) ; virtual; Override; // 0 means unlimited objects
something like that as What Iām saying is a pointer is allocated to an object for a single task and you use memory for the object or you do not use memory controlled buy one pointer. You can still put the pointer value in TList and then Nil the pointer in code for reuse as you have made it harder to forget the pointer is in use before reusing it.
The other option is a TList containing all created objects that gets cleared when the application closes. the con how much mothering does the programmer need?