For the sake of demonstration, I have created this simple console application:
#include <iostream>
class Person {
public:
int mAge;
};
int main(int argc, const char * argv[])
{
Person *iPerson = new Person();
iPerson->mAge = 15;
std::cout << "Age: " << iPerson->mAge;
return 0;
}
Now I'm aware that Valgrind and CPP Check will identify leaks here, but testing Apple's Instruments, When I profile this code I can't see any leaks. This is despite iPerson never being deleted.
I've worked it out:
I had to set the snapshot interval to 1 second.
I had to disable (set to None) Optimization for the release version (for which profiling is done).
Then based on justin's reply and this question, I had to modify my code like so:
#include <iostream>
#include <unistd.h>
class Person {
public:
int mAge;
};
void CreateLeaks()
{
// All three lines will generate a leak.
Person *iPerson = new Person();
iPerson = new Person();
iPerson = new Person();
}
int main(int argc, const char * argv[])
{
CreateLeaks();
sleep( 2 );
return 0;
}
There are still some odd things going on. For example, if you start adding sleep(2) within CreateLeaks, Instruments doesn't catch all leaks (depending on where you put the sleep commands. Odd.
Leaks Instrument performs snapshots at a predefined frequency. By default, that value is "every 10 seconds". You program completes before 10 seconds. Thus, the leak is never collected. So you must suspend execution after iPerson has gone out of scope in order for that leak to be detected. Also, if you just add a sleep while that pointer is still referenced on the stack or in a register, then it won't be a leak.
You could have a look at Tips for Improving Leak Detection from the Mac Developer Library.
Cppcheck static analysis tool for C/C++ code might also help. For the example you provided, it finds:
#>cppcheck so_code.cpp
Checking so_code.cpp...
[so_code.cpp:15]: (error) Memory leak: iPerson
Related
I have currently a memory issue using the Botan library (version 2.15) for cryptography functions within a C++ project. My development environment is Solus Linux 4.1 (kernel-current), but I could observe this issue on Debian Buster too.
I observed that some memory allocated internally by Botan for calculations is not deallocated when going out of scope. When I called Botan::HashFunction, Botan::StreamCipher and Botan::scrypt multiple times, always going out of scope in between, the memory footprint increases steadily.
For example, consider this code:
#include <iostream>
#include <vector>
#include "botan/scrypt.h"
void pause() {
char ch;
std::cout << "Insert any key to proceed... ";
std::cin >> ch;
}
std::vector<uint8_t> get_scrypt_passhash(std::string const& password, std::string const& name) {
std::vector<uint8_t> key (32);
Botan::scrypt(key.data(), key.size(), password.c_str(), password.length(), salt.c_str(), salt.length(), 65536, 32, 1);
std::cout << "From function: before closing.\n";
pause();
return key;
}
int main(int argc, char *argv[]) {
std::cout << "Beginning test.\n";
pause();
auto pwhashed = get_scrypt_passhash(argv[1], argv[2]);
std::cout << "Test ended.\n";
pause();
}
I used the pause() function to observe the memory consumption (I called top/pmap and observed KSysGuard during the pause), when it is called from within get_scrypt_passhash before terminating, the used memory (both by top/pmap and KSysGuard) is about 2 MB more than at beginning, and after terminating the same.
I tried to dive into the Botan source code, but I cannot find memory leaks or the like. Valgrind also outputted that all allocated bytes have been freed, so no memory leaks were possible.
Just for information, I tried the same functionality with Crypto++ without observing this behavior.
Has anyone experienced the same issue? Is there a way to fix it?
My problem
I have a singleton whose memory is being corrupted by an unknown corruptor. Something is overwriting the memory for the singleton, and hundreds of bytes around it, with value 0. After the object is constructed via new, it is read-only for the lifetime of the application.
My goal
I'd like to capture the corruptor at the time of the corruption. I'd like to mprotect as read-only the memory of the object after construction. That way later when the corruption happens the system will segmentation fault at the time of corruption.
My question
It looks like mprotect is granular to the page level. How would I "over allocate" for the singleton instance a full page for the object (it is far smaller than 4k, the standard page size) and then mprotect that page?
You can use anonymous mmap to allocate a full page for the singleton, then construct the object into it with placement new.
Thank you #Brian. Here's my minimal example of using mmap as he suggests, followed by placement new to use that memory and then mprotect to make it read-only:
#include <iostream>
#include <sys/mman.h>
#include <unistd.h>
using namespace std;
struct MySingleton
{
int some_value;
static MySingleton* init(int a_value)
{
// Get the system's page size.
const auto pagesize = getpagesize();
// mmap one page worth of memory, initially writable.
void* map = mmap(0, pagesize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
// Use placement new using that memory.
MySingleton::_instance = new(map) MySingleton(a_value);
// Now make that memory read-only.
mprotect(map, pagesize, PROT_READ);
return MySingleton::_instance;
}
static MySingleton* instance()
{
return _instance;
}
private:
MySingleton(int a_value)
: some_value{a_value}
{
}
static MySingleton *_instance;
};
MySingleton *MySingleton::_instance = nullptr;
int
main(int argc, char* argv[])
{
MySingleton *instance = MySingleton::init(10);
// Read is OK.
cout << instance->some_value << endl;
// This should crash;
instance->some_value = 5;
cout << instance->some_value << endl;
return 0;
}
When I compile and run this, I get the crash that I desire:
g++ -g -Wall -Werror -std=c++17 test.cc -o test
./test
10
runit: line 4: 18029 Bus error: 10 ./test
The debugger points right to the write:
$ lldb test
(lldb) target create "test"
Current executable set to 'test' (x86_64).
(lldb) run
Process 18056 launched: '<snip>' (x86_64)
10
Process 18056 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x10011d000)
frame #0: 0x0000000100000c50 test`main(argc=1, argv=0x00007ffeefbff9a8) at test.cc:50:26
47 cout << instance->some_value << endl;
48
49 // This should crash;
-> 50 instance->some_value = 5;
51 cout << instance->some_value << endl;
52
53 return 0;
Target 0: (test) stopped.
Practically every debugger got a tool to watch memory for change (in gdb command literally called watch)
Instead of trying to work around issue, you have to find source, corruption due to out-of-bound write may touch something else, even mory vital and hard to detect.
To answer your question, C++ got a placement new expression, an overload for new operator which allows to allocate object at particular address of pre-allocated memory
I'm having trouble running a code I've been assigned to modify.
The code works normally, but I've been asked to test one of the functions from the code, so I made a set of data that I'd give the function to test that the outputs will be the desired ones.
However, whenever I run my code, a message box appears that says that the program has stopped working.
Here's the beginning of the code:
int main(int argc, char *argv[])
{
int nrMonsters;
cout << "Hello World!" << endl;
Monsters *monster[20]={0};
cout<<"Beginning of Test\n...\n";
//the first data set prepared for testing
Monsters *date1[4]= {0};
//date1 - CC BB AA DD
date1[0]->name="CC";
date1[1]->name="BB";
date1[2]->name="AA";
date1[3]->name="DD";
for (int a=0;a<4;a++)
{
date1[a]->type=BALAUR;
date1[a]->health=10;
}
cout<<"Set date1 initialised.";
cout<<"\n\nSorting set date1...\t";
sortMonster(4,date1);
Here's what the structure is:
enum MonsterTypes
{
UNDEFINED=-1,
VARCOLAC,
CAPCAUN,
PAIANJEN,
SPIRIDUS,
STRIGOI,
BALAUR
};
struct Monsters
{
MonsterTypes type;
std::string name;
int health;
};
Here's the requirements of the function (it's meant to sort them alphabetically):
void sortMonster(int number_of_monsters, Monsters **monster)
{
/ /sorting
}
When I hover the mouse above the second argument, it shows
"Monster **monster"
But when I hover it at the top of the code where it's initialised, it reads
"Monster *mosnter[]"
Does anyone know how to fix this?
Thank you.
You have to allocate memory.
Monsters *date1 = new Monsters[4];
Or use C style malloc
Dont forget to free allocated memory via
delete []date1;
or
free(date1); // if allocated with malloc/calloc
We are under a PCI PA-DSS certification and one of its requirements is to avoid writing clean PAN (card number) to disk. The application is not writing such information to disk, but if the operating system (Windows, in this case) needs to swap, the memory contents is written to page file. Therefore the application must clean up the memory to prevent from RAM capturer services to read sensitive data.
There are three situations to handle:
heap allocation (malloc): before freeing the memory, the area can be cleaned up with memset
static or global data: after being used, the area can be cleaned up using memset
local data (function member): the data is put on stack and is not accessible after the function is finished
For example:
void test()
{
char card_number[17];
strcpy(card_number, "4000000000000000");
}
After test executes, the memory still contains the card_number information.
One instruction could zero the variable card_number at the end of test, but this should be for all functions in the program.
memset(card_number, 0, sizeof(card_number));
Is there a way to clean up the stack at some point, like right before the program finishes?
Cleaning the stack right when the program finishes might be too late, it could have already been swapped out during any point at its runtime. You should keep your sentitive data only in memory locked with VirtualLock so it does not get swapped out. This has to happen before said sensitive data is read.
There is a small limit on how much memory you can lock like this so you can propably not lock the whole stack and should avoid storing sensitive data on the stack at all.
I assume you want to get rid of this situation below:
#include <iostream>
using namespace std;
void test()
{
char card_number[17];
strcpy(card_number, "1234567890123456");
cout << "test() -> " << card_number << endl;
}
void test_trash()
{
// don't initialize, so get the trash from previous call to test()
char card_number[17];
cout << "trash from previous function -> " << card_number << endl;
}
int main(int argc, const char * argv[])
{
test();
test_trash();
return 0;
}
Output:
test() -> 1234567890123456
trash from previous function -> 1234567890123456
You CAN do something like this:
#include <iostream>
using namespace std;
class CardNumber
{
char card_number[17];
public:
CardNumber(const char * value)
{
strncpy(card_number, value, sizeof(card_number));
}
virtual ~CardNumber()
{
// as suggested by #piedar, memset_s(), so the compiler
// doesn't optimize it away.
memset_s(card_number, sizeof(card_number), 0, sizeof(card_number));
}
const char * operator()()
{
return card_number;
}
};
void test()
{
CardNumber cardNumber("1234567890123456");
cout << "test() -> " << cardNumber() << endl;
}
void test_trash()
{
// don't initialize, so get the trash from previous call to test()
char card_number[17];
cout << "trash from previous function -> " << card_number << endl;
}
int main(int argc, const char * argv[])
{
test();
test_trash();
return 0;
}
Output:
test() -> 1234567890123456
trash from previous function ->
You can do something similar to clean up memory on the heap or static variables.
Obviously, we assume the card number will come from a dynamic source instead of the hard-coded thing...
AND YES: to explicit answer the title of your question: The stack will not be cleaned automatically... you have to clean it by yourself.
I believe it is necessary, but this is only half of the problem.
There are two issues here:
In principle, nothing prevents the OS from swapping your data while you are still using it. As pointed out in the other answer, you want VirtualLock on windows and mlock on linux.
You need to prevent the optimizer from optimizing out the memset. This also applies to global and dynamically allocated memory. I strongly suggest to take a look at cryptopp SecureWipeBuffer.
In general, you should avoid to do it manually, as it is an error-prone procedure. Instead, consider using a custom allocator or a custom class template for secure data that can be freed in the destructor.
The stack is cleaned up by moving the stack pointer, not by actually popping values from it. The only mechanics are to pop the return into the appropriate registers. You must do it all manually. Also -- volatile can help you avoid optimizations on a per variable basis. You can manually pop the stack clean, but -- you need assembler to do that -- and it is not so simple to start manipulating the stack -- it is not actually your resource -- the compiler owns it as far as you are concerned.
I am trying to do some practice for memory allocation.
I have the below code which is working but have two questions.
Where do I have to use delete [ ] to free the memory after allocating?
Why is the output for this code at function when using show() function is CDcar?.
#include <cstdlib>
#include <new>
#include <iostream>
#include <cstring>
using namespace std;
class automobile {
private:
char (*function)[30];
char *type;
double speed;
public:
automobile ( );
automobile (double , char *);
void speed_up (double);
void speed_down(double);
const char * get_function ( ) const;
void show ( );
};
automobile::automobile ( ) {
speed = 0;
function = new char [1][30];
strcpy(function[1], "CD player with MP3");
type = new char [4];
strcpy(type, "car");
}
automobile::automobile(double spd, char * fn ) {
int sz;
}
void automobile::show ( ) {
cout << "This is a " << type << " and it has the following functions: " << function[1] << ", and its speed is " << speed << " km/h\n";
}
int main ( ) {
automobile car;
car.show ( );
return 0;
}
this is the output:
This is a car and it has the following functions: CDcar, and its speed is 0 km/h
I thought the output shoud be this:
This is a car and it has the following functions: CD player with MP3, and its speed is 0 km/h
Please advise
Where do I have to use delete [ ] to free the memory after allocating?
Ideally nowhere. new and delete are features of C++ that are not suitable for most code. They are error-prone and too low-level. They're only useful for basic building blocks.
The code shown could benefit from basic building blocks like std::string, std::vector.
The code shown also invokes undefined behaviour at least in one place:
function = new char [1][30];
strcpy(function[1], "CD player with MP3");
Arrays are 0-based, so function[1] is an out-of-bounds access.
You should call delete[] in the destructor of your class.
//Called when your class is destroyed.
automobile::~automobile()
{
delete[] function;
}
You should place the delete[] for function and type within the destructor ~automobile (you don't have one currently, so you'll have to create it).
Regarding the output: Your character is array is not well defined. Consider using std::vector<string> for such things (much easier).
Your output is incorrect b/c of the following:
speed = 0;
function = new char [1][30];
strcpy(function[1], "CD player with MP3");
This should be
speed = 0;
function = new char [1][30];
strcpy(function[0], "CD player with MP3");
and when you output you should be cout'ing function[0] instead of function[1].
Having said this, you should almost always try to eliminate manual calls to new and delete. It helps with maintainability and it helps keep code exception safe. In this case you can get this for free by using vectors and strings provided by the standard C++ library. In a more general sense, you want to follow the RAII Idiom. This will help C++ and memory management from shaving a couple of years off your life during your studies/career.
Inside ~automobile destructor.