Why doesnt Dispose() clean the memory address or am I being lazy?

When looking at the memory address of a reference variable before a value is assigned after its been NEW’ed its empty/clean, when I check the same location after its been disposed, the data still shows in the memory location.

Why doesnt Dispose() clean this memory location?

I could probably write my own function to clean it and then dispose, but from a security perspective, wouldnt it be better if dispose() cleaned the memory itself?

After all this is one of the justifications for using .net, in that it cleans up behind you, or is this where everyone comes out and says, dont you clean before disposing, which is an alternative to doing a function?

Because it would slow things down. And most things do not need to be cleared before release. But if yours does, it should not be hard to do.

1 Like

But is that really a factor today with 5Ghz machines, unlike the 8086/286/Pentium days?

If it is done often enough, like in a loop, then yes it can matter.

Particularly when, once disposed, any access to the pointer can (maybe) cause a GPF. So it should never be touched after.

But if it is a security issue, which is more of a concern nowdays, then maybe it should be cleared and overwritten before Dispose.

Hmmmm ads targeted to hackers.

1 Like

So whilst I could say, I’d question if Dispose is in the right place inside a loop, I can see how it could slow the loop up. Problem is, do I assume new() and dispose() is taking place from the same starting pointing in memory, in effect over writing itself which would garbage up the smaller string lengths, but the last part of the longest string would still be visible in memory. If new() starts from the same starting point in memory, a function which notes the longest string could then clean the memory for the longest string once after the loop which would encompass all the other smaller strings. Job done, nice and easy.

However, if new() not starting from the same starting point in memory, then I’m going to have to clean each and every memory space that new() uses, so then it becomes a question of strategy, do I log the memory addresses used, in a queue, and then after the loop sort the queue, and work out the best way to wipe the memory, whilst trying to avoid repeating any wipes/cleans on a memory address.

I think I’ll have to do a class to start logging the memory usage with new() and dispose() and see what it does in different situations and then come up with different ways to efficiently wipe the memory.

I think it would be handy to also log what is left in the memory addresses after dispose() to also see what usable data can be obtained from memory and see just how risky not cleaning memory is. This might also shed some light on how ASLR is working in windows, when its switched on.

Time between new() and then the inevitable wipe/clean will also be a factor as I’d imagine making it as small a window of time between new() and wipe/clean will also be ideal to reduce windows of opportunity for prying “eyes”.

[min 20 character board filler] What do you mean?

MyRef = MyAdvertisement
DISPOSE(MyRef)

I still understand what you mean? Are you getting adverts in your browser showing security tools or something. I think you’ll have to walk me through this one… :confused:

I agree if a developer has a desire to protect disposed data left in memory … then they can easily code their own protection to clear it. The RTL should Not be slowed … as noted below there is much more to consider to be “secure”.

New() and Dispose() data are not the only concern. What about all the variables declared in a Procedure? When the Procedure closes that memory will be returned to the OS “as is”. Most will be on the Stack and larger variables on the Heap… then you have File Record Buffers that may have Fields with sensitive data that should be cleared when the file is closed? Data that is THREAD that should be cleaned when the Thread terminates? Static / Global data when the process is closed.

There’s a bunch of stuff about the string stack and other stack stuff in Clarion\docs\AdvancedTopicsReferenceGuide.pdf

I had started a new post but it got flagged and hidden for some obscure reason, but I think ASLR enabled systems pave the way for virtualised code outside of an OS to utilise these ASLR procedures on systems with double or triple digit GB of ram, where the procedures dont ever get overwritten during a session, in much the same way TSR’s used to work in the DOS days, only instead of there being a dos interrupt the virtualised code utilises it. It has many benefits, like its outside of the OS and thus potentially not detected and not constrained by the boundaries an OS places on code that runs on it.

Pretty much all files and programs fit inside a template of sorts, otherwise the things could not run…

We know there is an order to the way a PE file is constructed where some elements are mandatory and some optional, so how hard is it to have some virtualised code reading everything from an ALSR procedure on a system with lots of ram?

PE Format - Win32 apps | Microsoft Docs

TLDR, tiny amounts of ram on a slow cheap value pc could be an unrecognised industry wide security feature!!!

All those page swaps being made by the slow cheap value pc could be negating the need for programmers to clean up behind their code, when using things like New() and Dispose() and virtualised sniffers could have a hard time keeping up with reading whats currently in memory.

[quote=“RichClaCode, post:6, topic:5260”]…
However, if new() not starting from the same starting point in memory, then I’m going to have to clean each and every memory space that new() uses, so then it becomes a question of strategy, do I log the memory addresses used, in a queue, and then after the loop sort the queue, and work out the best way to wipe the memory, whilst trying to avoid repeating any wipes/cleans on a memory address. …
[/quote]
There have been languages that did this kind of thing, put they were so slow and “klunky” that they are no longer used. The time saved was less than the extra time used.

Keep it simple and small. Clear the things necessary right after the New(), or if for security right before the Dispose().

The memory areas can be anywhere in physical memory, even if the program thinks they are right together. See the memory handling inside the CPU.

P.S., More than half of the memory values will usually be written immediatly after the New(), so that clearing is not needed for them. If something is not set right after New(), then it should be cleared.

Clarion automatically clears memory as part of doing a New(). So it basically does a malloc then memset. This does add a tiny overhead but means you don’t need to worry about clearing New() memory before using it.

Not sure that applies to classes. Not sure about nowadays, but early on, they told us to initialize properties in the constructor, as you could not assume what the values would be.

interesting Jeff - I would have thought if you had properties of a class then the default values would apply.

eg.

x string(‘abcdef’)
y string(100) ! initialized to spaces
z string(100),auto ! not initialized so potentially whatever is sitting in memory

and then if a class had

xx &string

xx &= new string(100) ! this is initialized to spaces

I’d be pretty surprised if that was not the case - but I have never tested it

cheers

Geoff R

To me, this use of heap and stack memory seems like a security nightmare and is clear it was designed for performance first and not security especially considering how slow these computers used to run and the invention of .net which many have bought in to.

I’ve never understood why the Auto attribute exists, other than to force the use of the supposedly “faster” stack memory instead of slower “heap” memory, because at some point some data will be placed in it, and whilst its understandable that variables are initialised (read cleaned), if this tiny overhead of clearing the memory takes place with new(), then why not with dispose()? Not even as an optional parameter in the language function? Stack-based memory allocation - Wikipedia

And as the stack seems to be allocating a big block of memory when a procedure is called, is the OS clearing the memory before its allocated to the stack? From what I see in the debugger and this thread I’d say no the OS is not cleaning memory before its assigned to the procedure and the stack.

And when we look at why .net came into existence, which was to tidy up the memory usage, ie making sure Dispose() was called automatically because so many programmers were not disposing of their variables and to enforce higher standards like a new security model called CAS, even CAS has died a death because its too complicated for programmers!
The end of Code Access Security in Microsoft .NET | Tim Anderson’s IT Writing

Sure, memory leaks can crash programs, but security leaks can put companies out of business and if the business disappears so does the program. Darwinism in action with computer software!

However there might be hope, I dont have any DDR5 ram to test this with, but looking at the command encodings DDR5 SDRAM - Wikipedia I see there is a new write pattern.

The “Write Pattern” command is new for DDR5; this is identical to a write command, but the range is filled in with copies of a one-byte mode register (which defaults to all-zero) instead of individual data.

So has anyone with DDR5 in their computer, seen evidence to suggest the OS is now clearing memory beit uninitialized Auto stack variables or initialised heap variables in Clarion?

I cant find any security settings in windows to force cleaning of memory before its given over to an app for use, but maybe its a bios setting?

Anyone know?

Filling memory allocated by NEW to blanks or zeroes is documented as part of NEW’s behavior.

Local variables are allocating

  • on the stack if they have size not greater than value of the define(stack_threshold) pragma (default value is 32, not recommended to change it to lower values)
  • in the heap, otherwise.

Local variables allocated in the heap are freeing automatically on closing the scope where it has been declared, i.e. on return from procedure or on exit from ROUTINE.

If a local variable has no the AUTO attribute, the compiler generates code to set it to blank or zero value meaningful for that variable’s type. For complex data types it means invoking the corresponding variant of the BLANK statement. If a local variable has the AUTO attribute, it is not initializing. Variables of ANY and VARIANT types and implicit variables are initializing.

Windows allocates the space for every thread when it is attached to the process. The stack memory block is originally filled with zeroes. Every procedure is responsible for initializing stack allocated data on the call, if this is required. In Clarion this can be done by providing variables’ initial values or missing the AUTO attribute.

Garbage-collection-supported allocation must be a part of pointers semantic in the language. Introducing of the automatic garbage collection to existing languages creates numerous problems. For example, the new allocation function gcnew() has been introduced in Visual C++ with applying significant restrictions to usage of normal new() to solve these problems (not all, though).

Every process is running in its own virtual memory space. If process terminated, content of its memory space is not available anymore for all other processes - not counting mapped files and other persistent data objects which are stored really in the external storage. Filling or not filling memory blocks on allocation and/or freeing can’t be a reason of security leak itself.

1 Like

But there are ways to read the memory of another process.

In Clarion’s case, the runtime, ie stack handling rules can be worked out and any window with a control can easily have the values read from the variable attached to the control using things like Spy++.

I’ve even written a clarion app which does something similar to Spy++ Introducing Spy++ - Visual Studio (Windows) | Microsoft Learn
but in Windows 10, its now not possible to get at some of the OS values seen in the Settings (Gear Icon) window even with Spy++, just as its not possible to extract the web address from the Firefox webbrowser address bar. But its still possible to extract settings/values from the Control Panel in Win10 and older versions of Windows.

Mapped files are just pipes in windows.

This link explains how just 3 windows api’s can be used to access another processes memory.
How to Read and Write Other Process Memory (nullprogram.com)

These 3 windows api’s let you access another process running in its own virtual memory space so there is no security here.
OpenProcess function (processthreadsapi.h) - Win32 apps | Microsoft Learn
ReadProcessMemory function (memoryapi.h) - Win32 apps | Microsoft Learn
WriteProcessMemory function (memoryapi.h) - Win32 apps | Microsoft Learn

Other examples GitHub - T-vK/Memory-Hacking-Class: Easy-to-use class to read and modify other processes memory.

So I dont think there is that much security once you can use these api’s on a windows machine, but I was thinking maybe it would be possible to write some code/class which could provide garbage or Chaff to use an Air Force term, by creating lots of variables with random stuff in, to make it harder to find the real data amongst the garbage. Its not like we have 1990’s machines any more, so having a bit of bloat which is hiding real data in amongst garbage on todays machine wont affect the performance that much imo, and not all real data is attached to a windows control.

Ransomware shows that getting code onto a machine is possible, but the stealth hackers just want to steal data and its not always published online, corporate espionage is still a thing even today.

Why memory can’t be read while it is not cleared/filled with a pattern?

Value of controls’ USE variables can’t be read by controls’ handles in general case. For example,
if the CHECK control has the VALUE attribute, e.g.

CHECK(‘Text to display’),USE(S),VALUE(‘2,718281828’,‘3.1415926’),…

  • WM_GETTEXT will return ‘Text to display’
  • BM_GETCHECK will return one of following values: BST_CHECKED, BST_UNCHECKED or BST_INDETERMINATE

but actual value of the USE variable is either e or pi.

Possibility to get information about control or window by its handle is a property of Windows, not of Clarion. It’s possible to set hooks of WH_CALLWNDPROC or WH_GETMESSAGE types to monitor posted and sent messages for every window/control and every thread in the system using the SetWindowsHookEx API function.

MapViewOfFile maps the view of file mapping into process address space => (part of) file behaves just like a memory block with corresponding access rights.

Again, this is how Windows works - this is the part of Windows API. It can’t be prevented.Debuggers can do even more. And clearing memory blocks can’t help. You need to use some kind of sandbox with your own device drivers to have more or less safe environment.

If you already have some criminal software in the computer memory, it’s late.