Skip to content

Commit 18431c6

Browse files
authored
Merge pull request #169 from ityuhui/yh-mlk-0116
Fix memory leak when kubeconfig is invalid
2 parents 5911cc0 + cf0e04d commit 18431c6

File tree

5 files changed

+99
-13
lines changed

5 files changed

+99
-13
lines changed

examples/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
all:
22
cd create_pod; make
3+
cd list_pod_with_invalid_kubeconfig; make
34
cd list_pod; make
45
cd list_pod_incluster; make
56
cd delete_pod; make
@@ -15,6 +16,7 @@ all:
1516

1617
clean:
1718
cd create_pod; make clean
19+
cd list_pod_with_invalid_kubeconfig; make clean
1820
cd list_pod; make clean
1921
cd list_pod_incluster; make clean
2022
cd delete_pod; make clean
@@ -31,6 +33,7 @@ clean:
3133
test:
3234
cd create_pod; make test;
3335
kubectl wait --for=condition=ready --all pod -n default --timeout=60s
36+
cd list_pod_with_invalid_kubeconfig; make test
3437
cd list_pod; make test
3538
cd delete_pod; make test
3639
kubectl wait --for=delete pod/test-pod-6 -n default --timeout=120s
@@ -46,6 +49,7 @@ test:
4649
memcheck:
4750
cd create_pod; make memcheck;
4851
kubectl wait --for=condition=ready --all pod -n default --timeout=60s
52+
cd list_pod_with_invalid_kubeconfig; make memcheck
4953
cd list_pod; make memcheck
5054
cd delete_pod; make memcheck
5155
kubectl wait --for=delete pod/test-pod-6 -n default --timeout=120s
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
list_pod_with_invalid_kubeconfig
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
INCLUDE:=-I../../kubernetes/
2+
LIBS:=-L../../kubernetes/build -lyaml -lwebsockets -lkubernetes -L/usr/local/lib
3+
CFLAGS:=-g
4+
BIN:=list_pod_with_invalid_kubeconfig
5+
6+
.PHONY : all clean test memcheck
7+
all:
8+
gcc main.c $(CFLAGS) $(INCLUDE) $(LIBS) -o $(BIN)
9+
10+
test:
11+
./$(BIN)
12+
13+
memcheck:
14+
valgrind --tool=memcheck --leak-check=full ./$(BIN)
15+
16+
clean:
17+
rm ./$(BIN)
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#include <config/kube_config.h>
2+
#include <api/CoreV1API.h>
3+
#include <stdio.h>
4+
5+
void list_pod(apiClient_t * apiClient)
6+
{
7+
v1_pod_list_t *pod_list = NULL;
8+
pod_list = CoreV1API_listNamespacedPod(apiClient, "default", /*namespace */
9+
NULL, /* pretty */
10+
0, /* allowWatchBookmarks */
11+
NULL, /* continue */
12+
NULL, /* fieldSelector */
13+
NULL, /* labelSelector */
14+
0, /* limit */
15+
NULL, /* resourceVersion */
16+
NULL, /* resourceVersionMatch */
17+
0, /* timeoutSeconds */
18+
0 /* watch */
19+
);
20+
printf("The return code of HTTP request=%ld\n", apiClient->response_code);
21+
if (pod_list) {
22+
printf("Get pod list:\n");
23+
listEntry_t *listEntry = NULL;
24+
v1_pod_t *pod = NULL;
25+
list_ForEach(listEntry, pod_list->items) {
26+
pod = listEntry->data;
27+
printf("\tThe pod name: %s\n", pod->metadata->name);
28+
}
29+
v1_pod_list_free(pod_list);
30+
pod_list = NULL;
31+
} else {
32+
printf("Cannot get any pod.\n");
33+
}
34+
}
35+
36+
int main()
37+
{
38+
char *basePath = NULL;
39+
sslConfig_t *sslConfig = NULL;
40+
list_t *apiKeys = NULL;
41+
int rc = load_kube_config(&basePath, &sslConfig, &apiKeys, "non-existent-file");
42+
if (rc != 0) {
43+
printf("Cannot load kubernetes configuration.\n");
44+
/* Return 0 to avoid Github/Action check failures.
45+
You should return a non-zero value in a production environment. */
46+
return 0;
47+
}
48+
apiClient_t *apiClient = apiClient_create_with_base_path(basePath, sslConfig, apiKeys);
49+
if (!apiClient) {
50+
printf("Cannot create a kubernetes client.\n");
51+
/* Return 0 to avoid Github/Action check failures.
52+
You should return a non-zero value in a production environment. */
53+
return 0;
54+
}
55+
56+
list_pod(apiClient);
57+
58+
apiClient_free(apiClient);
59+
apiClient = NULL;
60+
free_client_config(basePath, sslConfig, apiKeys);
61+
basePath = NULL;
62+
sslConfig = NULL;
63+
apiKeys = NULL;
64+
apiClient_unsetupGlobalEnv();
65+
66+
return 0;
67+
}

kubernetes/config/kube_config_yaml.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ mapping :: = MAPPING - START(node node) * MAPPING - END
5757

5858
#define VALUE_TRUE_LOWERCASE_STRING "true"
5959

60-
static char *load_file_content(const char *path) {
60+
static char *load_file_content(const char *path)
61+
{
6162

6263
static char fname[] = "load_file_content()";
6364

@@ -73,8 +74,7 @@ static char *load_file_content(const char *path) {
7374
long s = ftell(fh);
7475
rewind(fh);
7576
buffer = malloc(s);
76-
if ( buffer != NULL )
77-
{
77+
if (buffer != NULL) {
7878
fread(buffer, s, 1, fh);
7979
}
8080
fclose(fh);
@@ -217,7 +217,7 @@ static int parse_kubeconfig_yaml_property_mapping(kubeconfig_property_t * proper
217217
} else if (0 == strcmp(key->data.scalar.value, KEY_SERVER)) {
218218
property->server = strdup(value->data.scalar.value);
219219
} else if (0 == strcmp(key->data.scalar.value, KEY_INSECURE_SKIP_TLS_VERIFY)) {
220-
property->insecure_skip_tls_verify = (0 == strcmp(value->data.scalar.value, VALUE_TRUE_LOWERCASE_STRING)); //libyaml fails to parse true, but it can parse "true"!
220+
property->insecure_skip_tls_verify = (0 == strcmp(value->data.scalar.value, VALUE_TRUE_LOWERCASE_STRING)); //libyaml fails to parse true, but it can parse "true"!
221221
}
222222
} else if (KUBECONFIG_PROPERTY_TYPE_USER == property->type) {
223223
if (0 == strcmp(key->data.scalar.value, KEY_CLIENT_CERTIFICATE)) {
@@ -425,14 +425,6 @@ int kubeyaml_load_kubeconfig(kubeconfig_t * kubeconfig)
425425
{
426426
static char fname[] = "kubeyaml_load_kubeconfig()";
427427

428-
yaml_parser_t parser;
429-
yaml_document_t document;
430-
431-
int done = 0;
432-
433-
/* Create the Parser object. */
434-
yaml_parser_initialize(&parser);
435-
436428
/* Set a file input. */
437429
FILE *input = NULL;
438430
if (kubeconfig->fileName) {
@@ -446,8 +438,14 @@ int kubeyaml_load_kubeconfig(kubeconfig_t * kubeconfig)
446438
return -1;
447439
}
448440

441+
yaml_parser_t parser;
442+
yaml_document_t document;
443+
444+
/* Create the Parser object. */
445+
yaml_parser_initialize(&parser);
449446
yaml_parser_set_input_file(&parser, input);
450447

448+
int done = 0;
451449
while (!done) {
452450

453451
if (!yaml_parser_load(&parser, &document)) {
@@ -1121,4 +1119,3 @@ int kubeyaml_save_kubeconfig(const kubeconfig_t * kubeconfig)
11211119

11221120
return -1;
11231121
}
1124-

0 commit comments

Comments
 (0)