I would like to that in my spare time - not many hours - and leverage my subsequent relaxation browsing time...
What I am thinking is based on rough understanding, so please pass along any hints.
My idea is to provide a memcpy() that can safely be used in any application with minimal changes to the software behaviour, and yet provide logging of bad usage for proactive corrections.
It is ok if the system is slower.. but it should still work.
I don't really know how to do the logging as it should:
* not interfere with threads, signals etc
* be always available
The memcpy() is pretty simple..
A replacement memcpy() based on combination of memove() to test the parameters and the old memcpy() to provide the implementation for stability of my software.
When a memcpy() is made with bad args, that would normally invoke the special logic an error is logged by PID? and the old memcpy() still invoked to deliver the vanilla experience.
The replacement sounds like building a patched Glibc.
Any suggestions or hints for how to do the logging would be appreciated.
Posted Nov 12, 2010 5:00 UTC (Fri) by dafid_b (guest, #67424)
[Link]
i hacked up something, around shared memory, which seems most likely to me (based on little experience) to be safe..
If this approach is reasonable.. then just need to link it into memcpy as outlined above to have a trace of last few hundred errors on the system in shared memory waiting to dumped...
struct data // trace data for a memcpy() error
{
pid_t pid ;
const void *ret ;
const void *dest ;
const void *src ;
size_t len ;
} ;
struct log
{
long int index ; // sequence or index of last entry used
struct data entry[ SHARED_MEM_SIZE/sizeof(struct data) - 1 ] ; // vector of logging instances
} ;
struct log *pLog ;
#define N_ENTRIES (sizeof(pLog->entry)/sizeof(pLog->entry[0]))
void
displayLog(int i)
{
int j = i % N_ENTRIES ; // restrict index.
Posted Nov 12, 2010 6:44 UTC (Fri) by cmccabe (guest, #60281)
[Link]
> fd = open(av, O_RDWR, 0x777)
This is not correct. You want
> fd = open(av, O_RDWR, 0777)
Yes, it's an octal constant. Or use the symbolic constants.
Also, this is more of a personal preference thing, but bumpyCaps and hungarian notation are frowned on by most.
In a larger sense, I think you don't want to rebuild glibc. You probably just want to use "the LD_PRELOAD trick"
If I were you, I would print my nastygrams to syslog, using the syslog(3) function. Most sysadmins don't check random areas of shared memory that often. If you do choose to use shm, try shm_open.
cheers,
C.
Glibc change exposing bugs
Posted Nov 12, 2010 9:09 UTC (Fri) by dafid_b (guest, #67424)
[Link]
Thanks for the code review, much appreciated.
Is syslog() safe to call at this point?
It generates formatted output, which seems like it could itself call memcpy() or do other stuff in te library that the app did not allow for in its plan when it called memcpy.
Also is the system call that sends the message to the log safe, or can it have side effect such as signals and new error codes in errno?
I would be very happy if the answer to the above is: syslog() safe to call like this with no side-effects.
Glibc change exposing bugs
Posted Nov 13, 2010 3:02 UTC (Sat) by cmccabe (guest, #60281)
[Link]
> Is syslog() safe to call at this point?
> It generates formatted output, which seems like it could itself call
> memcpy() or do other stuff in te library that the app did not allow for in
> its plan when it called memcpy
You raise a good issue. glibc's version of syslog is known to call malloc sometimes, which means that you shouldn't use it from within a signal handler. Surprisingly, memcpy isn't on the official list of "async-signal safe" functions, so you could argue that such an implementation would be POSIX conforming :)
But seriously. I think the best thing to do is probably implement your own version of syslog with no memory allocations or calls to memcpy. It's pretty easy to do in a few hundred lines. I had to do it before when writing a good signal handler.
C.
Glibc change exposing bugs
Posted Nov 12, 2010 18:21 UTC (Fri) by chad.netzer (✭ supporter ✭, #4257)
[Link]
Not to deprive you of the experience of doing it yourself, which can be instructive. However, you should need to reinvent the wheel if all you want is the use of the tool. At the very least, you can see how valgrind does it. As for automatically invoking it, well that's an exercise for the reader. :)