kubernetes-client / c

Official C client library for Kubernetes
Apache License 2.0
144 stars 46 forks source link

free Error() #59

Closed minerba closed 3 years ago

minerba commented 3 years ago

@ityuhui

Hello,

I'm trying to Use pod_list_free(), But I have Error Message " free() : Invalid size "

so I trace function stack like below

#0  0x00007ffff69b57ff in raise () from /lib64/libc.so.6
#1  0x00007ffff699fc35 in abort () from /lib64/libc.so.6
#2  0x00007ffff69f8987 in __libc_message () from /lib64/libc.so.6
#3  0x00007ffff69ffd8c in malloc_printerr () from /lib64/libc.so.6
#4  0x00007ffff6a0169c in _int_free () from /lib64/libc.so.6
#5  0x00007ffff797bc42 in v1_pod_security_context_free (v1_pod_security_context=0x7da480)
    at kubernetes/model/v1_pod_security_context.c:51
#6  0x00007ffff797c842 in v1_pod_spec_free (v1_pod_spec=0x7dae40)
    at kubernetes/model/v1_pod_spec.c:214
#7  0x00007ffff797a0f3 in v1_pod_free (v1_pod=0x7db3f0)
    at kubernetes/model/v1_pod.c:52
#8  0x00007ffff797b779 in v1_pod_list_free (v1_pod_list=0x80f140)
    at kubernetes/model/v1_pod_list.c:38
#9  0x0000000000400893 in main (argc=1, argv=0x7fffffff55c8) at main.c:39

I don't know what the intent of this free()

free void v1_pod_security_context_free(v1_pod_security_context_t *v1_pod_security_context)

=> if (v1_pod_security_context->supplemental_groups) { list_ForEach(listEntry, v1_pod_security_context->supplemental_groups) { free(listEntry->data); }

allocate kubernetes/model/v1_pod_security_context.c

v1_pod_security_context_parseFromJSON(cJSON *v1_pod_security_contextJSON) => list_addElement(supplemental_groupsList , &supplemental_groups_local->valuedouble);

So fixed not to call free function. It worked fine.

Is this right?

brendandburns commented 3 years ago

Can you provide the code in your main.c?

Thanks!

minerba commented 3 years ago
#include <malloc.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#include "v1_pod_list.h"
#include "apiClient.h"

int main(){
    apiClient_t *apiClient = NULL;
    sslConfig_t *sslConfig = NULL;
    list_t    *apiKeys = NULL;
    char      *basePath = NULL;
    int        Ret    = 0;

    Ret = load_incluster_config(&basePath, &sslConfig, &apiKeys);
    if(Ret != 0)
    {
            free_client_config(basePath, &sslConfig, &apiKeys);
            return 0;
    }

    apiClient = apiClient_create_with_base_path(basePath, sslConfig, apiKeys);
    if(!apiClient)
    {
        free_client_config(basePath, sslConfig, apiKeys);
        return 0;
    }

    v1_pod_list_t *pod_list = NULL;

    pod_list = CoreV1API_listNamespacedPod(    apiClient,
                                               "csdb-amf",
                                                NULL,   // pretty
                                                0,  // allowWatchBookmarks
                                                NULL,       // _continue
                                                NULL,
                                                NULL,
                                                0,  // limit
                                                NULL, // resourceVersion
                                                0,  // timeoutSeconds
                                                0   // watch
                            );
    if(apiClient->response_code > 300)
    {
        return 0;
    }
    if(pod_list == NULL)
    {
        return 0;
    }

    // print code //

    v1_pod_list_free(pod_list);

    return 1;
}

@brendanburns here it is

brendandburns commented 3 years ago

Very odd. That's all in the generated code. Can you send the JSON for the object(s) that you receive. e.g. kubectl get pods -o json --namespace csdb-amf

That may help us reproduce the issue.

minerba commented 3 years ago

Sorry I can't serve my json File....

brendandburns commented 3 years ago

Ok, I will try to reproduce this locally.

clearday4 commented 3 years ago

217 // v1_pod_security_context->supplemental_groups 218 cJSON supplemental_groups = cJSON_GetObjectItemCaseSensitive(v1_pod_security_contextJSON, "supplementalGroups"); 219 list_t supplemental_groupsList; 220 if (supplemental_groups) { 221 cJSON *supplemental_groups_local; 222 if(!cJSON_IsArray(supplemental_groups)) { 223 goto end;//primitive container 224 } 225 supplemental_groupsList = list_create(); 226 227 cJSON_ArrayForEach(supplemental_groups_local, supplemental_groups) 228 { 229 if(!cJSON_IsNumber(supplemental_groups_local)) 230 { 231 goto end; 232 } 233 list_addElement(supplemental_groupsList , &supplemental_groups_local->valuedouble); <==== &supplemental_groups_local->valuedouble is a local pointer that points to the cJSON string. This address is unaccessible at the end of the function and can not be freed from other functions.

clearday4 commented 3 years ago

There are some cases like the above in kubernetes/model directory. call list_addElement() with local pointer value, and the local pointer doesn't allocate the memory. it is a garbage address.

./v1beta1_certificate_signing_request_spec.c:174: list_addElement(extraList , localMapKeyPair); ./v1_subject_access_review_spec.c:174: list_addElement(extraList , localMapKeyPair); ./v1_pod_security_context.c:233: list_addElement(supplemental_groupsList , &supplemental_groups_local->valuedouble); ./v1beta1_user_info.c:136: list_addElement(extraList , localMapKeyPair); ./v1_user_info.c:136: list_addElement(extraList , localMapKeyPair); ./v1_json_schema_props.c:850: list_addElement(definitionsList , localMapKeyPair); ./v1_json_schema_props.c:867: list_addElement(dependenciesList , localMapKeyPair); ./v1_json_schema_props.c:898: list_addElement(_enumList, _enumItem); ./v1_json_schema_props.c:1100: list_addElement(pattern_propertiesList , localMapKeyPair); ./v1_json_schema_props.c:1117: list_addElement(propertiesList , localMapKeyPair); ./v1beta1_pod_disruption_budget_status.c:164: list_addElement(disrupted_podsList , localMapKeyPair); ./v1_secret.c:184: list_addElement(dataList , localMapKeyPair); ./v1beta1_json_schema_props.c:850: list_addElement(definitionsList , localMapKeyPair); ./v1beta1_json_schema_props.c:867: list_addElement(dependenciesList , localMapKeyPair); ./v1beta1_json_schema_props.c:1100: list_addElement(pattern_propertiesList , localMapKeyPair); ./v1beta1_json_schema_props.c:1117: list_addElement(propertiesList , localMapKeyPair); ./v1_config_map.c:170: list_addElement(binary_dataList , localMapKeyPair); ./v1beta1_subject_access_review_spec.c:174: list_addElement(extraList , localMapKeyPair);

And I have another question. What is the purpose of this function?

object_t *object_parseFromJSON(char *jsonString){
     object_t *object = NULL;

     return object;
end:
     return NULL;
}

object_parseFromJSON() is called in 82 places.

ityuhui commented 3 years ago

Any code releated to object_t cannot work now.

The background is : object is a data type of OpenAPI specification, but the C programming language does not support OO (Object-Oriented) paradigm by itself. So the C client generated by OpenAPI-Generator/C-libcurl does not support object_t now. Please avoid using any function involved object_t ( do the serialization and deserialization by yourself or use generic client).

I may try to support object by implementing a "virtual function table".

ityuhui commented 3 years ago

Has loged a new issue https://github.com/kubernetes-client/c/issues/70 to trace the defect of @clearday4 appended and delete the defect description here.