From c3618488f2730eae9634987b0969a497442aa0df Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Thu, 15 Dec 2022 20:18:12 +0000 Subject: [PATCH] Hexdump leaked memory to the log for debugging. --- TODO.txt | 3 ++ man/man7/telodendria-changelog.7 | 16 +++++-- src/Telodendria.c | 72 ++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/TODO.txt b/TODO.txt index 7aa951c..dc35c33 100644 --- a/TODO.txt +++ b/TODO.txt @@ -13,6 +13,9 @@ Milestone: v0.1.1 [x] DbDelete() [x] UtilRandomString() +[x] Hex dump leaked memory +[ ] Leaks in DB + [ ] Database version file [ ] User registration diff --git a/man/man7/telodendria-changelog.7 b/man/man7/telodendria-changelog.7 index 62505e9..48504a6 100644 --- a/man/man7/telodendria-changelog.7 +++ b/man/man7/telodendria-changelog.7 @@ -49,6 +49,16 @@ be used extensively for generating session tokens, device IDs, access tokens, and more. This generator is seeded by the current timestamp and the thread ID, so it should be fairly random. +.It +Leaked memory is now hexdump-ed out to the log if the log +level is set to debug. This greatly simplifies debugging, +because developers can now easily see exactly what the +contents of the leaked memory are. Note that in some +circumstances, this memory may contain sensitive data, +such as access tokens, usernames, or passwords. However, +.Nm +should not be leaking memory at all, so if you encounter +any leaks, please report them. .El .Pp Bug fixes: @@ -70,11 +80,11 @@ Fixed an "off-by-one" error in the HTTP server request parser that prevented GET parameters from being parsed. .It Fixed the database file name generator to prevent directory -traversal attacks by replacing characters with special meaning -with safer characters. +traversal attacks by replacing special characters with +safer ones. .El .Pp -Misc.: +Misc: .Bl -bullet .It Fixed a bug in diff --git a/src/Telodendria.c b/src/Telodendria.c index b036583..a8ade89 100644 --- a/src/Telodendria.c +++ b/src/Telodendria.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -79,9 +80,80 @@ TelodendriaMemoryIterator(MemoryInfo * i, void *args) /* We haven't freed the logger memory yet */ if (MemoryInfoGetPointer(i) != lc) { +#define LEN 16 + char hexBuf[(LEN * 2) + LEN + 1]; + char asciiBuf[LEN + 1]; + const unsigned char *pc = MemoryInfoGetPointer(i); + size_t pI = 0; + size_t hI = 0; + size_t aI = 0; + Log(lc, LOG_WARNING, "%s:%d: %lu bytes of memory at %p leaked.", MemoryInfoGetFile(i), MemoryInfoGetLine(i), MemoryInfoGetSize(i), MemoryInfoGetPointer(i)); + + for (pI = 0; pI < MemoryInfoGetSize(i); pI++) + { + if (pI > 0 && pI % LEN == 0) + { + hexBuf[hI - 1] = '\0'; + asciiBuf[aI] = '\0'; + + Log(lc, LOG_DEBUG, "%04x: %s | %s |", + pI - LEN, hexBuf, asciiBuf); + + sprintf(hexBuf, "%02x ", pc[pI]); + hI = 3; + + if (isprint(pc[pI])) + { + asciiBuf[0] = pc[pI]; + } + else + { + asciiBuf[0] = '.'; + } + asciiBuf[1] = '\0'; + aI = 1; + } + else + { + if (isprint(pc[pI])) + { + asciiBuf[aI] = pc[pI]; + } + else + { + asciiBuf[aI] = '.'; + } + aI++; + + sprintf(hexBuf + hI, "%02x ", pc[pI]); + hI += 3; + } + } + + while (hI < sizeof(hexBuf) - 2) + { + hexBuf[hI] = ' '; + hI++; + } + + while (aI < sizeof(asciiBuf) - 1) + { + asciiBuf[aI] = ' '; + aI++; + } + + hexBuf[hI] = '\0'; + asciiBuf[aI] = '\0'; + + Log(lc, LOG_DEBUG, "%04x: %s | %s |", + pI - (pI % LEN), hexBuf, asciiBuf); + + Log(lc, LOG_DEBUG, "%04x", pI); + +#undef LEN } }