* Fix memory leak when kubeconfig is invalid

* Add a test for this case
This commit is contained in:
Hui Yu
2023-01-16 15:41:01 +08:00
parent 5911cc0ae4
commit 2887dd5fee
5 changed files with 93 additions and 8 deletions

View File

@@ -31,6 +31,7 @@ clean:
test:
cd create_pod; make test;
kubectl wait --for=condition=ready --all pod -n default --timeout=60s
cd list_pod_with_invalid_kubeconfig; make test
cd list_pod; make test
cd delete_pod; make test
kubectl wait --for=delete pod/test-pod-6 -n default --timeout=120s
@@ -46,6 +47,7 @@ test:
memcheck:
cd create_pod; make memcheck;
kubectl wait --for=condition=ready --all pod -n default --timeout=60s
cd list_pod_with_invalid_kubeconfig; make memcheck
cd list_pod; make memcheck
cd delete_pod; make memcheck
kubectl wait --for=delete pod/test-pod-6 -n default --timeout=120s

View File

@@ -0,0 +1 @@
list_pod_with_invalid_kubeconfig

View File

@@ -0,0 +1,17 @@
INCLUDE:=-I../../kubernetes/
LIBS:=-L../../kubernetes/build -lyaml -lwebsockets -lkubernetes -L/usr/local/lib
CFLAGS:=-g
BIN:=list_pod_with_invalid_kubeconfig
.PHONY : all clean test memcheck
all:
gcc main.c $(CFLAGS) $(INCLUDE) $(LIBS) -o $(BIN)
test:
./$(BIN)
memcheck:
valgrind --tool=memcheck --leak-check=full ./$(BIN)
clean:
rm ./$(BIN)

View File

@@ -0,0 +1,67 @@
#include <config/kube_config.h>
#include <api/CoreV1API.h>
#include <stdio.h>
void list_pod(apiClient_t * apiClient)
{
v1_pod_list_t *pod_list = NULL;
pod_list = CoreV1API_listNamespacedPod(apiClient, "default", /*namespace */
NULL, /* pretty */
0, /* allowWatchBookmarks */
NULL, /* continue */
NULL, /* fieldSelector */
NULL, /* labelSelector */
0, /* limit */
NULL, /* resourceVersion */
NULL, /* resourceVersionMatch */
0, /* timeoutSeconds */
0 /* watch */
);
printf("The return code of HTTP request=%ld\n", apiClient->response_code);
if (pod_list) {
printf("Get pod list:\n");
listEntry_t *listEntry = NULL;
v1_pod_t *pod = NULL;
list_ForEach(listEntry, pod_list->items) {
pod = listEntry->data;
printf("\tThe pod name: %s\n", pod->metadata->name);
}
v1_pod_list_free(pod_list);
pod_list = NULL;
} else {
printf("Cannot get any pod.\n");
}
}
int main()
{
char *basePath = NULL;
sslConfig_t *sslConfig = NULL;
list_t *apiKeys = NULL;
int rc = load_kube_config(&basePath, &sslConfig, &apiKeys, "non-existent-file");
if (rc != 0) {
printf("Cannot load kubernetes configuration.\n");
/* Return 0 to avoid Github/Action check failures.
You should return a non-zero value in a production environment. */
return 0;
}
apiClient_t *apiClient = apiClient_create_with_base_path(basePath, sslConfig, apiKeys);
if (!apiClient) {
printf("Cannot create a kubernetes client.\n");
/* Return 0 to avoid Github/Action check failures.
You should return a non-zero value in a production environment. */
return 0;
}
list_pod(apiClient);
apiClient_free(apiClient);
apiClient = NULL;
free_client_config(basePath, sslConfig, apiKeys);
basePath = NULL;
sslConfig = NULL;
apiKeys = NULL;
apiClient_unsetupGlobalEnv();
return 0;
}

View File

@@ -425,14 +425,6 @@ int kubeyaml_load_kubeconfig(kubeconfig_t * kubeconfig)
{
static char fname[] = "kubeyaml_load_kubeconfig()";
yaml_parser_t parser;
yaml_document_t document;
int done = 0;
/* Create the Parser object. */
yaml_parser_initialize(&parser);
/* Set a file input. */
FILE *input = NULL;
if (kubeconfig->fileName) {
@@ -446,8 +438,14 @@ int kubeyaml_load_kubeconfig(kubeconfig_t * kubeconfig)
return -1;
}
yaml_parser_t parser;
yaml_document_t document;
/* Create the Parser object. */
yaml_parser_initialize(&parser);
yaml_parser_set_input_file(&parser, input);
int done = 0;
while (!done) {
if (!yaml_parser_load(&parser, &document)) {