• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

drakenclimber / libcgroup / 22781467195

06 Mar 2026 08:49PM UTC coverage: 56.167% (-0.05%) from 56.221%
22781467195

push

github

drakenclimber
Testing out a fix from codex

• Fix Details

  - Freed the lexer-owned ID strings whenever cgroup_dictionary_create or
    cgroup_dictionary_add fail, matching the leak reported in issue
    #518 where parse errors left duplicated tokens allocated. src/parse.y:236,
    src/parse.y:247 citeturn8open0
  - Initialized the temporary dictionary pointer to NULL before creation so
    the failure path can safely skip cgroup_dictionary_free,
    preventing accidental use of an uninitialized address while reclaiming
    the leaking strings. src/parse.y:236

Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>

1 of 7 new or added lines in 1 file covered. (14.29%)

5 existing lines in 2 files now uncovered.

5606 of 9981 relevant lines covered (56.17%)

598.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

17.73
/src/parse.y
1
// SPDX-License-Identifier: LGPL-2.1-only
2
/**
3
 * Copyright IBM Corporation. 2007
4
 *
5
 * Authors:        Balbir Singh <balbir@linux.vnet.ibm.com>
6
 *
7
 * NOTE: The grammar has been modified, not to be the most efficient, but
8
 * to allow easy updation of internal data structures.
9
 */
10

11
%{
12
#include <stdlib.h>
13
#include <stdio.h>
14
#include <string.h>
15
#include <libcgroup.h>
16
#include <libcgroup-internal.h>
17

18
int yylex(void);
19
extern int line_no;
20
extern char *yytext;
21

22
static void yyerror(const char *s)
1✔
23
{
24
        fprintf(stderr, "error at line number %d at %s:%s\n", line_no, yytext, s);
1✔
25
}
1✔
26

27
int yywrap(void)
26✔
28
{
29
        return 1;
26✔
30
}
31

32
%}
33

34
%token <name> ID MOUNT GROUP PERM TASK ADMIN NAMESPACE DEFAULT TEMPLATE SYSTEMD
35

36
%union {
37
        char *name;
38
        char chr;
39
        int val;
40
        struct cgroup_dictionary *values;
41
}
42
%type <name> group_name
43
%type <val> mountvalue_conf mount task_namevalue_conf admin_namevalue_conf
44
%type <val> admin_conf task_conf task_or_admin group_conf group start
45
%type <val> namespace namespace_conf default default_conf
46
%type <values> namevalue_conf
47
%type <val> template template_conf
48
%type <val> template_task_or_admin template_task_namevalue_conf
49
%type <val> template_admin_namevalue_conf template_task_conf
50
%type <val> template_admin_conf
51
%type <val> systemdvalue_conf systemd
52
%start start
53
%%
54

55
start   : start group
56
        {
57
                $$ = $1;
16✔
58
        }
59
        | start mount
60
        {
61
                $$ = $1;
×
62
        }
63
        | start default
64
        {
65
          $$ = $1;
×
66
        }
67
        | start namespace
68
        {
69
                $$ = $1;
×
70
        }
71
        | start template
72
        {
73
                $$ = $1;
×
74
        }
75
        | start systemd
76
        {
77
                $$ = $1;
13✔
78
        }
79
        |
80
        {
81
                $$ = 1;
32✔
82
        }
83
        ;
84

85
default :       DEFAULT '{' default_conf '}'
86
        {
87
                $$ = $3;
×
88
                if ($$) {
×
89
                        cgroup_config_define_default();
×
90
                }
91
        }
92
        ;
93

94
default_conf
95
        :       PERM '{' task_or_admin '}'
96
        {
97
                $$ = $3;
×
98
        }
99
        ;
100

101
group   :       GROUP group_name '{' group_conf '}'
102
        {
103
                $$ = $4;
16✔
104
                if ($$) {
16✔
105
                        $$ = cgroup_config_insert_cgroup($2);
16✔
106
                        if (!$$) {
16✔
107
                                fprintf(stderr, "failed to insert group check size and memory");
×
108
                                $$ = ECGOTHER;
×
109
                                return $$;
×
110
                        }
111
                } else {
112
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
113
                        $$ = ECGCONFIGPARSEFAIL;
×
114
                        return $$;
×
115
                }
116
        }
117
        ;
118

119
group_name
120
        :        ID
121
        {
122
                $$ = $1;
16✔
123
        }
124
        |        DEFAULT
125
        {
126
                $$ = $1;
×
127
        }
128

129
group_conf
130
        :       ID '{' namevalue_conf '}'
131
        {
132
                $$ = cgroup_config_parse_controller_options($1, $3);
16✔
133
                cgroup_dictionary_free($3);
16✔
134
                if (!$$) {
16✔
135
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
136
                        $$ = ECGCONFIGPARSEFAIL;
×
137
                        return $$;
×
138
                }
139
        }
140
        |       group_conf ID '{' namevalue_conf '}'
141
        {
142
                $$ = cgroup_config_parse_controller_options($2, $4);
×
143
                cgroup_dictionary_free($4);
×
144
                if (!$$) {
×
145
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
146
                        $$ = ECGCONFIGPARSEFAIL;
×
147
                        return $$;
×
148
                }
149
        }
150
        |       PERM '{' task_or_admin '}'
151
        {
152
                $$ = $3;
×
153
                if (!$$) {
×
154
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
155
                        $$ = ECGCONFIGPARSEFAIL;
×
156
                        return $$;
×
157
                }
158
        }
159
        ;
160

161
template  :     TEMPLATE ID '{' template_conf '}'
162
        {
163
                $$ = $4;
×
164
                if ($$) {
×
165
                        $$ = template_config_insert_cgroup($2);
×
166
                        if (!$$) {
×
167
                                fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
168
                                $$ = ECGOTHER;
×
169
                                return $$;
×
170
                        }
171
                } else {
172
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
173
                        $$ = ECGCONFIGPARSEFAIL;
×
174
                        return $$;
×
175
                }
176
        }
177
        ;
178

179

180
template_conf
181
        :       ID '{' namevalue_conf '}'
182
        {
183
                $$ = template_config_parse_controller_options($1, $3);
×
184
                cgroup_dictionary_free($3);
×
185
                if (!$$) {
×
186
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
187
                        $$ = ECGCONFIGPARSEFAIL;
×
188
                        return $$;
×
189
                }
190
        }
191
        |       template_conf ID '{' namevalue_conf '}'
192
        {
193
                $$ = template_config_parse_controller_options($2, $4);
×
194
                cgroup_dictionary_free($4);
×
195
                if (!$$) {
×
196
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
197
                        $$ = ECGCONFIGPARSEFAIL;
×
198
                        return $$;
×
199
                }
200
        }
201
        |       PERM '{' template_task_or_admin '}'
202
        {
203
                $$ = $3;
×
204
                if (!$$) {
×
205
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
206
                        $$ = ECGCONFIGPARSEFAIL;
×
207
                        return $$;
×
208
                }
209
        }
210
        ;
211

212
template_task_or_admin
213
        :        TASK '{' template_task_namevalue_conf '}' template_admin_conf
214
        {
215
        $$ = $3 && $5;
×
216
                if (!$$) {
×
217
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
218
                        $$ = ECGCONFIGPARSEFAIL;
×
219
                        return $$;
×
220
                }
221
        }
222
        |       ADMIN '{' template_admin_namevalue_conf '}' template_task_conf
223
        {
224
                $$ = $3 && $5;
×
225
                if (!$$) {
×
226
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
227
                        $$ = ECGCONFIGPARSEFAIL;
×
228
                return $$;
×
229
                }
230
        }
231
        ;
232

233

234
namevalue_conf
235
        :       ID '=' ID ';'
236
        {
237
                struct cgroup_dictionary *dict = NULL;
12✔
238
                int ret;
239
                ret = cgroup_dictionary_create(&dict, 0);
12✔
240
                if (ret == 0)
12✔
241
                        ret = cgroup_dictionary_add(dict, $1, $3);
12✔
242
                if (ret) {
12✔
243
                        fprintf(stderr, "parsing failed at line number %d:%s\n", line_no,
×
244
                                cgroup_strerror(ret));
245
                        $$ = NULL;
×
NEW
246
                        free($1);
×
NEW
247
                        free($3);
×
NEW
248
                        if (dict)
×
NEW
249
                                cgroup_dictionary_free(dict);
×
UNCOV
250
                        return ECGCONFIGPARSEFAIL;
×
251
                }
252
                $$ = dict;
12✔
253
        }
254
        |       namevalue_conf ID '=' ID ';'
255
        {
256
                int ret = 0;
12✔
257
                ret = cgroup_dictionary_add($1, $2, $4);
12✔
258
                if (ret != 0) {
12✔
259
                        fprintf(stderr, "parsing failed at line number %d: %s\n", line_no,
×
260
                                cgroup_strerror(ret));
261
                        $$ = NULL;
×
NEW
262
                        free($2);
×
NEW
263
                        free($4);
×
UNCOV
264
                        return ECGCONFIGPARSEFAIL;
×
265
                }
266
                $$ = $1;
12✔
267
        }
268
        |
269
        {
270
                $$ = NULL;
4✔
271
        }
272
        ;
273

274
task_namevalue_conf
275
        :       ID '=' ID ';'
276
        {
277
                $$ = cgroup_config_group_task_perm($1, $3);
×
278
                if (!$$) {
×
279
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
280
                        $$ = ECGCONFIGPARSEFAIL;
×
281
                        return $$;
×
282
                }
283
        }
284
        |       task_namevalue_conf ID '=' ID ';'
285
        {
286
                $$ = $1 && cgroup_config_group_task_perm($2, $4);
×
287
                if (!$$) {
×
288
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
289
                        $$ = ECGCONFIGPARSEFAIL;
×
290
                        return $$;
×
291
                }
292
        }
293
        ;
294

295
admin_namevalue_conf
296
        :       ID '=' ID ';'
297
        {
298
                $$ = cgroup_config_group_admin_perm($1, $3);
×
299
                if (!$$) {
×
300
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
301
                        $$ = ECGCONFIGPARSEFAIL;
×
302
                        return $$;
×
303
                }
304
        }
305
        |       admin_namevalue_conf ID '=' ID ';'
306
        {
307
                $$ = $1 && cgroup_config_group_admin_perm($2, $4);
×
308
                if (!$$) {
×
309
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
310
                        $$ = ECGCONFIGPARSEFAIL;
×
311
                        return $$;
×
312
                }
313
        }
314
        ;
315

316
template_task_namevalue_conf
317
        :       ID '=' ID ';'
318
        {
319
                $$ = template_config_group_task_perm($1, $3);
×
320
                if (!$$) {
×
321
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
322
                        $$ = ECGCONFIGPARSEFAIL;
×
323
                        return $$;
×
324
                }
325
        }
326
        |       template_task_namevalue_conf ID '=' ID ';'
327
        {
328
                $$ = $1 && template_config_group_task_perm($2, $4);
×
329
                if (!$$) {
×
330
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
331
                        $$ = ECGCONFIGPARSEFAIL;
×
332
                        return $$;
×
333
                }
334
        }
335
        ;
336

337
template_admin_namevalue_conf
338
        :       ID '=' ID ';'
339
        {
340
                $$ = template_config_group_admin_perm($1, $3);
×
341
                if (!$$) {
×
342
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
343
                        $$ = ECGCONFIGPARSEFAIL;
×
344
                        return $$;
×
345
                }
346
        }
347
        |       template_admin_namevalue_conf ID '=' ID ';'
348
        {
349
                $$ = $1 && template_config_group_admin_perm($2, $4);
×
350
                if (!$$) {
×
351
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
352
                        $$ = ECGCONFIGPARSEFAIL;
×
353
                        return $$;
×
354
                }
355
        }
356
        ;
357

358

359
task_or_admin
360
        :       TASK '{' task_namevalue_conf '}' admin_conf
361
        {
362
                $$ = $3 && $5;
×
363
                if (!$$) {
×
364
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
365
                        $$ = ECGCONFIGPARSEFAIL;
×
366
                        return $$;
×
367
                }
368
        }
369
        |       ADMIN '{' admin_namevalue_conf '}' task_conf
370
        {
371
                $$ = $3 && $5;
×
372
                if (!$$) {
×
373
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
374
                        $$ = ECGCONFIGPARSEFAIL;
×
375
                        return $$;
×
376
                }
377
        }
378
        ;
379

380
admin_conf:        ADMIN '{' admin_namevalue_conf '}'
381
        {
382
                $$ = $3;
×
383
                if (!$$) {
×
384
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
385
                        $$ = ECGCONFIGPARSEFAIL;
×
386
                        return $$;
×
387
                }
388
        }
389
        ;
390

391
task_conf:        TASK '{' task_namevalue_conf '}'
392
        {
393
                $$ = $3;
×
394
                if (!$$) {
×
395
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
396
                        $$ = ECGCONFIGPARSEFAIL;
×
397
                        return $$;
×
398
                }
399
        }
400
        ;
401

402
template_admin_conf:        ADMIN '{' template_admin_namevalue_conf '}'
403
        {
404
                $$ = $3;
×
405
                if (!$$) {
×
406
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
407
                        $$ = ECGCONFIGPARSEFAIL;
×
408
                        return $$;
×
409
                }
410
        }
411
        ;
412

413
template_task_conf:        TASK '{' template_task_namevalue_conf '}'
414
        {
415
                $$ = $3;
×
416
                if (!$$) {
×
417
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
418
                        $$ = ECGCONFIGPARSEFAIL;
×
419
                        return $$;
×
420
                }
421
        }
422
        ;
423

424
mountvalue_conf
425
        :       ID '=' ID ';'
426
        {
427
                if (!cgroup_config_insert_into_mount_table($1, $3)) {
×
428
                        cgroup_config_cleanup_mount_table();
×
429
                        $$ = ECGCONFIGPARSEFAIL;
×
430
                        return $$;
×
431
                }
432
                $$ = 1;
×
433
        }
434
        |       mountvalue_conf ID '=' ID ';'
435
        {
436
                if (!cgroup_config_insert_into_mount_table($2, $4)) {
×
437
                        cgroup_config_cleanup_mount_table();
×
438
                        $$ = ECGCONFIGPARSEFAIL;
×
439
                        return $$;
×
440
                }
441
                $$ = 1;
×
442
        }
443
        ;
444

445
mount   :       MOUNT '{' mountvalue_conf '}'
446
        {
447
                $$ = $3;
×
448
                if (!$$) {
×
449
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
450
                        $$ = ECGCONFIGPARSEFAIL;
×
451
                        return $$;
×
452
                }
453
        }
454
        ;
455

456
namespace_conf
457
        :       ID '=' ID ';'
458
        {
459
                if (!cgroup_config_insert_into_namespace_table($1, $3)) {
×
460
                        cgroup_config_cleanup_namespace_table();
×
461
                        $$ = ECGCONFIGPARSEFAIL;
×
462
                        return $$;
×
463
                }
464
                $$ = 1;
×
465
        }
466
        |       namespace_conf ID '=' ID ';'
467
        {
468
                if (!cgroup_config_insert_into_namespace_table($2, $4)) {
×
469
                        cgroup_config_cleanup_namespace_table();
×
470
                        $$ = ECGCONFIGPARSEFAIL;
×
471
                        return $$;
×
472
                }
473
                $$ = 1;
×
474
        }
475
        ;
476

477
namespace   :       NAMESPACE '{' namespace_conf '}'
478
        {
479
                $$ = $3;
×
480
                if (!$$) {
×
481
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
482
                        $$ = ECGCONFIGPARSEFAIL;
×
483
                        return $$;
×
484
                }
485
        }
486
        ;
487

488
systemdvalue_conf
489
        :        ID '=' ID ';'
490
        {
491
                if (!cgroup_alloc_systemd_opts($1, $3)) {
18✔
492
                        cgroup_cleanup_systemd_opts();
3✔
493
                        $$ = ECGCONFIGPARSEFAIL;
3✔
494
                        return $$;
3✔
495
                }
496
                $$ = 1;
15✔
497
        }
498
        |        systemdvalue_conf ID '=' ID ';'
499
        {
500
                if (!cgroup_add_systemd_opts($2, $4)) {
28✔
501
                        cgroup_cleanup_systemd_opts();
2✔
502
                        $$ = ECGCONFIGPARSEFAIL;
2✔
503
                        return $$;
2✔
504
                }
505
                $$ = 1;
26✔
506
        }
507
        ;
508

509
systemd   :          SYSTEMD '{' systemdvalue_conf '}'
510
        {
511
                $$ = $3;
13✔
512
                if (!$$) {
13✔
513
                        fprintf(stderr, "parsing failed at line number %d\n", line_no);
×
514
                        $$ = ECGCONFIGPARSEFAIL;
×
515
                        return $$;
×
516
                }
517
        }
518
        ;
519
%%
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc