0

I a writing a custom wrapper that implements strcat, strcpy etc in a safer way by trying to remember heap size allocations to adresses. For example, if a malloc(100) returned a pointer p, strcat checks current size of string at p and converts safely to strncat if it remembers the p from malloc. Here is my implementation:

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <string.h>
#include "linkedlist.h"

List * ptrSizes;

char *(*libc_strcat)(char * , const char * );

char* strcat(char * dest, const char * src){
    printf("Called strcat\n");
    if (ptrSizes == NULL) {
        ptrSizes = createList();
    }
    if (libc_strcat == NULL) {
        libc_strcat = dlsym(RTLD_NEXT, "strcat");
    }
    // Assume node returns the saved mapping correctly      
    Node* node = findInList(ptrSizes, dest);
    if (node != NULL){
        size_t curr_sz = strlen(dest);
        size_t left = node -> max_sz - curr_sz - 1;
        if (left > 0) {
            printf("Copying %zd bytes with strncat\n", left);
            dest = strncat(dest, src, left);
        }
        else{
            printf("No copy to prevent overflow\n");
        }
    }
    else{
        // no memory of malloc. Can't help yet
        dest = libc_strcat(dest, src);
    }
    return dest;
}

Now my problem is that in any test file, strcat(dest, "Hello World"); does not call my wrapper strcat, but

char src[]="Hello World";
strcat(dest, src);

properly calls my wrapper. I can't remove the const keyword as that makes it non-conformant with the declaration in string.h.

What could I do so that both calls go to my wrapper?

Shashank Singh
  • 283
  • 1
  • 5
  • 16
  • why are you including string.h but then re-defining some of its functions? I'm surprised this even compiles. – itdoesntwork Apr 27 '16 at 21:55
  • C functions are not overloaded; function return values and parameters do not affect the symbol. Also note that you cannot possibly have a conforming `strcat` with your example; `strcat` by definition modifies the buffer pointed to by `dest`, but doing so in your case would modify past the end of the buffer. – Colonel Thirty Two Apr 27 '16 at 21:55
  • 1
    Also IIRC compilers are allowed to assuming standard C functions perform as they are specified in the C spec and optimize them out. If that's the case, the compiler might be optimizing `strcat(dest, "Hello World")` to a simple `strlen` and `memcpy`. – Colonel Thirty Two Apr 27 '16 at 21:56
  • Try compiling with -fno-builtin to disable usage of builtin strcat and friends – Ctx Apr 27 '16 at 22:01
  • @ColonelThirtyTwo Thanks. That makes sense and could be the case. I am actually calling the libc strcat internally with dlsym, I only check if I can convert it to a safer strncat by remembering all mallocs with their sizes. I have written a small linkedlist to store them and malloc and free wrappers respectively that work fine. I couldn't understand how am I not conforming to strcat though? – Shashank Singh Apr 27 '16 at 22:03
  • Nevermind about that; I was misreading your example. However, if you're concerned with buffer overflows AddressSanitizer can catch `strcat` misuses and a lot more; add `-fsanitize=address` to your compile flags. – Colonel Thirty Two Apr 27 '16 at 22:08
  • Be careful when defining `_GNU_SOURCE`. Look at [this question](http://stackoverflow.com/questions/5582211/what-does-define-gnu-source-imply/5583764#5583764) for more info. – ddz Apr 27 '16 at 22:08

0 Answers0