Valgrind is throwing two warning for two lines of codes, mentioned in the comments next to each.
Warning 1:
invalid write of size 8, Address ... is 8 bytes inside a block of size 9 alloc'd
data[size] = NULL;
Warning 2:
Conditional jump or move depends on uninitialized values(s)
for (char **ptr = data; *ptr; ptr++) { // warning -> Conditional jump or move depends on uninitialized values(s)
    free(*ptr);
}
Here's a complete code,
Callee
char **getList() {
    char **list = (char *[]) {"John", "Jane", NULL};
    int size = 0;
    for (char **ptr = list; *ptr; ptr++) {
        size++;
    }
    char **data = malloc(sizeof(char *) * size + 1);
    if (data == NULL) goto exception;
    for (int i = 0; *list; list++, i++) {
        data[i] = malloc(sizeof(char) * (strlen(*list) + 1));
        if (data[i] == NULL) goto exception;
        strcpy(data[i], *list);
    }
    data[size] = NULL; // this line gives warning
    // warning -> invalid write of size 8, Address ... is 8 bytes inside a block of size 9 alloc'd
    return data;
    exception:
    fprintf(stderr, "data allocation failed.\n");
    return NULL;
}
Caller different file/scope
char **data = getList();
for (char **ptr = data; *ptr; ptr++) { // warning -> Conditional jump or move depends on uninitialized values(s)
    free(*ptr);
}
free(data);
 
    