Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP6
sudo.27421
sudo-1.9.5p2-no_free_alias_name.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File sudo-1.9.5p2-no_free_alias_name.patch of Package sudo.27421
diff --git a/plugins/sudoers/alias.c b/plugins/sudoers/alias.c index caaa984..bd1105c 100644 --- a/plugins/sudoers/alias.c +++ b/plugins/sudoers/alias.c @@ -127,22 +127,29 @@ alias_add(struct sudoers_parse_tree *parse_tree, char *name, int type, a = calloc(1, sizeof(*a)); if (a == NULL) debug_return_bool(false); + + /* Only set elements used by alias_compare() in case there is a dupe. */ a->name = name; a->type = type; - /* a->used = false; */ - a->file = rcstr_addref(file); - a->line = line; - a->column = column; - HLTQ_TO_TAILQ(&a->members, members, entries); switch (rbinsert(parse_tree->aliases, a, NULL)) { case 1: - alias_free(a); + free(a); errno = EEXIST; debug_return_bool(false); case -1: - alias_free(a); + free(a); debug_return_bool(false); } + + /* + * It is now safe to fill in the rest of the alias. We do this last + * since it modifies "file" (adds a ref) and "members" (tailq conversion). + */ + /* a->used = false; */ + a->file = rcstr_addref(file); + a->line = line; + a->column = column; + HLTQ_TO_TAILQ(&a->members, members, entries); debug_return_bool(true); } diff --git a/plugins/sudoers/gram.c b/plugins/sudoers/gram.c index 0bb7285..3005216 100644 --- a/plugins/sudoers/gram.c +++ b/plugins/sudoers/gram.c @@ -4,11 +4,11 @@ */ #include <config.h> -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.7.5. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -52,10 +52,10 @@ USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ -#define YYBISON 30704 +#define YYBISON 30705 /* Bison version string. */ -#define YYBISON_VERSION "3.7.4" +#define YYBISON_VERSION "3.7.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -142,6 +142,11 @@ char *errorfile = NULL; static int alias_line, alias_column; +#ifdef NO_LEAKS +static struct parser_leak_list parser_leak_list = + SLIST_HEAD_INITIALIZER(parser_leak_list); +#endif + struct sudoers_parse_tree parsed_policy = { TAILQ_HEAD_INITIALIZER(parsed_policy.userspecs), TAILQ_HEAD_INITIALIZER(parsed_policy.defaults), @@ -162,7 +167,7 @@ static struct sudo_command *new_command(char *, char *); static struct command_digest *new_digest(int, char *); static void alias_error(const char *name, int errnum); -#line 160 "gram.c" +#line 165 "gram.c" # ifndef YY_CAST # ifdef __cplusplus @@ -319,7 +324,7 @@ extern int sudoersdebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 83 "gram.y" +#line 88 "gram.y" struct cmndspec *cmndspec; struct defaults *defaults; @@ -333,7 +338,7 @@ union YYSTYPE char *string; int tok; -#line 331 "gram.c" +#line 336 "gram.c" }; typedef union YYSTYPE YYSTYPE; @@ -510,6 +515,18 @@ typedef int_least16_t yytype_int16; typedef short yytype_int16; #endif +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ @@ -607,9 +624,9 @@ typedef int yy_state_fast_t; /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) +# define YY_USE(E) ((void) (E)) #else -# define YYUSE(E) /* empty */ +# define YY_USE(E) /* empty */ #endif #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ @@ -839,21 +856,21 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 192, 192, 195, 198, 199, 202, 205, 208, 215, - 222, 228, 231, 234, 237, 240, 244, 248, 252, 256, - 262, 265, 271, 274, 280, 281, 287, 294, 301, 308, - 315, 324, 325, 329, 335, 349, 353, 359, 366, 373, - 380, 387, 396, 397, 456, 511, 518, 525, 532, 541, - 542, 548, 551, 572, 576, 582, 594, 606, 611, 615, - 620, 625, 630, 634, 639, 642, 647, 662, 671, 680, - 689, 706, 707, 708, 709, 710, 711, 712, 713, 714, - 715, 718, 724, 727, 731, 735, 743, 751, 762, 768, - 774, 780, 788, 791, 794, 797, 800, 803, 806, 809, - 812, 815, 818, 821, 824, 827, 830, 835, 842, 849, - 865, 866, 869, 869, 879, 882, 883, 889, 890, 893, - 893, 903, 906, 907, 913, 914, 917, 917, 927, 930, - 931, 934, 934, 944, 947, 948, 954, 958, 964, 971, - 978, 985, 992, 1001, 1002, 1008, 1012, 1018, 1025, 1032 + 0, 197, 197, 200, 203, 204, 207, 210, 213, 222, + 231, 237, 240, 243, 246, 249, 253, 257, 261, 265, + 271, 274, 280, 283, 289, 290, 297, 306, 315, 325, + 335, 347, 348, 353, 359, 376, 380, 386, 395, 403, + 412, 421, 432, 433, 493, 553, 562, 571, 580, 591, + 592, 599, 602, 624, 628, 634, 646, 658, 663, 667, + 672, 677, 682, 686, 691, 694, 699, 715, 726, 738, + 749, 767, 768, 769, 770, 771, 772, 773, 774, 775, + 776, 779, 785, 788, 793, 798, 807, 816, 828, 835, + 842, 849, 858, 861, 864, 867, 870, 873, 876, 879, + 882, 885, 888, 891, 894, 897, 900, 905, 913, 922, + 942, 943, 946, 946, 958, 961, 962, 969, 970, 973, + 973, 985, 988, 989, 996, 997, 1000, 1000, 1012, 1015, + 1016, 1019, 1019, 1031, 1034, 1035, 1042, 1046, 1052, 1061, + 1069, 1078, 1087, 1098, 1099, 1106, 1110, 1116, 1125, 1133 }; #endif @@ -999,9 +1016,9 @@ static const yytype_int16 yypgoto[] = }; /* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = +static const yytype_uint8 yydefgoto[] = { - -1, 20, 21, 22, 23, 24, 33, 34, 91, 92, + 0, 20, 21, 22, 23, 24, 33, 34, 91, 92, 41, 42, 170, 171, 54, 55, 56, 57, 201, 202, 203, 204, 205, 206, 207, 208, 209, 172, 178, 71, 72, 181, 210, 58, 73, 74, 118, 93, 77, 78, @@ -1233,7 +1250,7 @@ yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) { FILE *yyoutput = yyo; - YYUSE (yyoutput); + YY_USE (yyoutput); if (!yyvaluep) return; # ifdef YYPRINT @@ -1241,7 +1258,7 @@ yy_symbol_value_print (FILE *yyo, YYPRINT (yyo, yytoknum[yykind], *yyvaluep); # endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -1355,13 +1372,13 @@ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep) { - YYUSE (yyvaluep); + YY_USE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -1622,362 +1639,394 @@ yyreduce: switch (yyn) { case 2: /* file: %empty */ -#line 192 "gram.y" +#line 197 "gram.y" { ; /* empty file */ } -#line 1624 "gram.c" +#line 1641 "gram.c" break; case 6: /* entry: '\n' */ -#line 202 "gram.y" +#line 207 "gram.y" { ; /* blank line */ } -#line 1632 "gram.c" +#line 1649 "gram.c" break; case 7: /* entry: error '\n' */ -#line 205 "gram.y" +#line 210 "gram.y" { yyerrok; } -#line 1640 "gram.c" +#line 1657 "gram.c" break; case 8: /* entry: include */ -#line 208 "gram.y" +#line 213 "gram.y" { if (!push_include((yyvsp[0].string), false)) { + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); free((yyvsp[0].string)); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); free((yyvsp[0].string)); } -#line 1652 "gram.c" +#line 1671 "gram.c" break; case 9: /* entry: includedir */ -#line 215 "gram.y" +#line 222 "gram.y" { if (!push_include((yyvsp[0].string), true)) { + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); free((yyvsp[0].string)); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); free((yyvsp[0].string)); } -#line 1664 "gram.c" +#line 1685 "gram.c" break; case 10: /* entry: userlist privileges '\n' */ -#line 222 "gram.y" +#line 231 "gram.y" { if (!add_userspec((yyvsp[-2].member), (yyvsp[-1].privilege))) { sudoerserror(N_("unable to allocate memory")); YYERROR; } } -#line 1675 "gram.c" +#line 1696 "gram.c" break; case 11: /* entry: USERALIAS useraliases '\n' */ -#line 228 "gram.y" +#line 237 "gram.y" { ; } -#line 1683 "gram.c" +#line 1704 "gram.c" break; case 12: /* entry: HOSTALIAS hostaliases '\n' */ -#line 231 "gram.y" +#line 240 "gram.y" { ; } -#line 1691 "gram.c" +#line 1712 "gram.c" break; case 13: /* entry: CMNDALIAS cmndaliases '\n' */ -#line 234 "gram.y" +#line 243 "gram.y" { ; } -#line 1699 "gram.c" +#line 1720 "gram.c" break; case 14: /* entry: RUNASALIAS runasaliases '\n' */ -#line 237 "gram.y" +#line 246 "gram.y" { ; } -#line 1707 "gram.c" +#line 1728 "gram.c" break; case 15: /* entry: DEFAULTS defaults_list '\n' */ -#line 240 "gram.y" +#line 249 "gram.y" { if (!add_defaults(DEFAULTS, NULL, (yyvsp[-1].defaults))) YYERROR; } -#line 1716 "gram.c" +#line 1737 "gram.c" break; case 16: /* entry: DEFAULTS_USER userlist defaults_list '\n' */ -#line 244 "gram.y" +#line 253 "gram.y" { if (!add_defaults(DEFAULTS_USER, (yyvsp[-2].member), (yyvsp[-1].defaults))) YYERROR; } -#line 1725 "gram.c" +#line 1746 "gram.c" break; case 17: /* entry: DEFAULTS_RUNAS userlist defaults_list '\n' */ -#line 248 "gram.y" +#line 257 "gram.y" { if (!add_defaults(DEFAULTS_RUNAS, (yyvsp[-2].member), (yyvsp[-1].defaults))) YYERROR; } -#line 1734 "gram.c" +#line 1755 "gram.c" break; case 18: /* entry: DEFAULTS_HOST hostlist defaults_list '\n' */ -#line 252 "gram.y" +#line 261 "gram.y" { if (!add_defaults(DEFAULTS_HOST, (yyvsp[-2].member), (yyvsp[-1].defaults))) YYERROR; } -#line 1743 "gram.c" +#line 1764 "gram.c" break; case 19: /* entry: DEFAULTS_CMND cmndlist defaults_list '\n' */ -#line 256 "gram.y" +#line 265 "gram.y" { if (!add_defaults(DEFAULTS_CMND, (yyvsp[-2].member), (yyvsp[-1].defaults))) YYERROR; } -#line 1752 "gram.c" +#line 1773 "gram.c" break; case 20: /* include: INCLUDE WORD '\n' */ -#line 262 "gram.y" +#line 271 "gram.y" { (yyval.string) = (yyvsp[-1].string); } -#line 1760 "gram.c" +#line 1781 "gram.c" break; case 21: /* include: INCLUDE WORD error '\n' */ -#line 265 "gram.y" +#line 274 "gram.y" { yyerrok; (yyval.string) = (yyvsp[-2].string); } -#line 1769 "gram.c" +#line 1790 "gram.c" break; case 22: /* includedir: INCLUDEDIR WORD '\n' */ -#line 271 "gram.y" +#line 280 "gram.y" { (yyval.string) = (yyvsp[-1].string); } -#line 1777 "gram.c" +#line 1798 "gram.c" break; case 23: /* includedir: INCLUDEDIR WORD error '\n' */ -#line 274 "gram.y" +#line 283 "gram.y" { yyerrok; (yyval.string) = (yyvsp[-2].string); } -#line 1786 "gram.c" +#line 1807 "gram.c" break; case 25: /* defaults_list: defaults_list ',' defaults_entry */ -#line 281 "gram.y" +#line 290 "gram.y" { + parser_leak_remove(LEAK_DEFAULTS, (yyvsp[0].defaults)); HLTQ_CONCAT((yyvsp[-2].defaults), (yyvsp[0].defaults), entries); (yyval.defaults) = (yyvsp[-2].defaults); } -#line 1795 "gram.c" +#line 1817 "gram.c" break; case 26: /* defaults_entry: DEFVAR */ -#line 287 "gram.y" +#line 297 "gram.y" { (yyval.defaults) = new_default((yyvsp[0].string), NULL, true); if ((yyval.defaults) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_DEFAULTS, (yyval.defaults)); } -#line 1807 "gram.c" +#line 1831 "gram.c" break; case 27: /* defaults_entry: '!' DEFVAR */ -#line 294 "gram.y" +#line 306 "gram.y" { (yyval.defaults) = new_default((yyvsp[0].string), NULL, false); if ((yyval.defaults) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_DEFAULTS, (yyval.defaults)); } -#line 1819 "gram.c" +#line 1845 "gram.c" break; case 28: /* defaults_entry: DEFVAR '=' WORD */ -#line 301 "gram.y" +#line 315 "gram.y" { (yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), true); if ((yyval.defaults) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[-2].string)); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_DEFAULTS, (yyval.defaults)); } -#line 1831 "gram.c" +#line 1860 "gram.c" break; case 29: /* defaults_entry: DEFVAR '+' WORD */ -#line 308 "gram.y" +#line 325 "gram.y" { (yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), '+'); if ((yyval.defaults) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[-2].string)); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_DEFAULTS, (yyval.defaults)); } -#line 1843 "gram.c" +#line 1875 "gram.c" break; case 30: /* defaults_entry: DEFVAR '-' WORD */ -#line 315 "gram.y" +#line 335 "gram.y" { (yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), '-'); if ((yyval.defaults) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[-2].string)); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_DEFAULTS, (yyval.defaults)); } -#line 1855 "gram.c" +#line 1890 "gram.c" break; case 32: /* privileges: privileges ':' privilege */ -#line 325 "gram.y" +#line 348 "gram.y" { + parser_leak_remove(LEAK_PRIVILEGE, (yyvsp[0].privilege)); HLTQ_CONCAT((yyvsp[-2].privilege), (yyvsp[0].privilege), entries); (yyval.privilege) = (yyvsp[-2].privilege); } -#line 1864 "gram.c" +#line 1900 "gram.c" break; case 33: /* privileges: privileges ':' error */ -#line 329 "gram.y" +#line 353 "gram.y" { yyerrok; (yyval.privilege) = (yyvsp[-2].privilege); } -#line 1873 "gram.c" +#line 1909 "gram.c" break; case 34: /* privilege: hostlist '=' cmndspeclist */ -#line 335 "gram.y" +#line 359 "gram.y" { struct privilege *p = calloc(1, sizeof(*p)); if (p == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_PRIVILEGE, p); TAILQ_INIT(&p->defaults); + parser_leak_remove(LEAK_MEMBER, (yyvsp[-2].member)); HLTQ_TO_TAILQ(&p->hostlist, (yyvsp[-2].member), entries); + parser_leak_remove(LEAK_CMNDSPEC, (yyvsp[0].cmndspec)); HLTQ_TO_TAILQ(&p->cmndlist, (yyvsp[0].cmndspec), entries); HLTQ_INIT(p, entries); (yyval.privilege) = p; } -#line 1890 "gram.c" +#line 1929 "gram.c" break; case 35: /* ophost: host */ -#line 349 "gram.y" +#line 376 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = false; } -#line 1899 "gram.c" +#line 1938 "gram.c" break; case 36: /* ophost: '!' host */ -#line 353 "gram.y" +#line 380 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = true; } -#line 1908 "gram.c" +#line 1947 "gram.c" break; case 37: /* host: ALIAS */ -#line 359 "gram.y" +#line 386 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), ALIAS); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 1920 "gram.c" +#line 1961 "gram.c" break; case 38: /* host: ALL */ -#line 366 "gram.y" +#line 395 "gram.y" { (yyval.member) = new_member(NULL, ALL); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 1932 "gram.c" +#line 1974 "gram.c" break; case 39: /* host: NETGROUP */ -#line 373 "gram.y" +#line 403 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), NETGROUP); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 1944 "gram.c" +#line 1988 "gram.c" break; case 40: /* host: NTWKADDR */ -#line 380 "gram.y" +#line 412 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), NTWKADDR); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 1956 "gram.c" +#line 2002 "gram.c" break; case 41: /* host: WORD */ -#line 387 "gram.y" +#line 421 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), WORD); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 1968 "gram.c" +#line 2016 "gram.c" break; case 43: /* cmndspeclist: cmndspeclist ',' cmndspec */ -#line 397 "gram.y" +#line 433 "gram.y" { struct cmndspec *prev; prev = HLTQ_LAST((yyvsp[-2].cmndspec), cmndspec, entries); + parser_leak_remove(LEAK_CMNDSPEC, (yyvsp[0].cmndspec)); HLTQ_CONCAT((yyvsp[-2].cmndspec), (yyvsp[0].cmndspec), entries); /* propagate runcwd and runchroot */ @@ -2032,17 +2081,18 @@ yyreduce: } (yyval.cmndspec) = (yyvsp[-2].cmndspec); } -#line 2030 "gram.c" +#line 2079 "gram.c" break; case 44: /* cmndspec: runasspec options cmndtag digcmnd */ -#line 456 "gram.y" +#line 493 "gram.y" { struct cmndspec *cs = calloc(1, sizeof(*cs)); if (cs == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_CMNDSPEC, cs); if ((yyvsp[-3].runas) != NULL) { if ((yyvsp[-3].runas)->runasusers != NULL) { cs->runasuserlist = @@ -2052,6 +2102,7 @@ yyreduce: sudoerserror(N_("unable to allocate memory")); YYERROR; } + /* g/c done via runas container */ HLTQ_TO_TAILQ(cs->runasuserlist, (yyvsp[-3].runas)->runasusers, entries); } @@ -2063,9 +2114,11 @@ yyreduce: sudoerserror(N_("unable to allocate memory")); YYERROR; } + /* g/c done via runas container */ HLTQ_TO_TAILQ(cs->runasgrouplist, (yyvsp[-3].runas)->runasgroups, entries); } + parser_leak_remove(LEAK_RUNAS, (yyvsp[-3].runas)); free((yyvsp[-3].runas)); } #ifdef HAVE_SELINUX @@ -2083,6 +2136,7 @@ yyreduce: cs->runchroot = (yyvsp[-2].options).runchroot; cs->tags = (yyvsp[-1].tag); cs->cmnd = (yyvsp[0].member); + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); HLTQ_INIT(cs, entries); /* sudo "ALL" implies the SETENV tag */ if (cs->cmnd->type == ALL && !cs->cmnd->negated && @@ -2090,76 +2144,85 @@ yyreduce: cs->tags.setenv = IMPLIED; (yyval.cmndspec) = cs; } -#line 2088 "gram.c" +#line 2142 "gram.c" break; case 45: /* digestspec: SHA224_TOK ':' DIGEST */ -#line 511 "gram.y" +#line 553 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA224, (yyvsp[0].string)); if ((yyval.digest) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_DIGEST, (yyval.digest)); } -#line 2100 "gram.c" +#line 2156 "gram.c" break; case 46: /* digestspec: SHA256_TOK ':' DIGEST */ -#line 518 "gram.y" +#line 562 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA256, (yyvsp[0].string)); if ((yyval.digest) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_DIGEST, (yyval.digest)); } -#line 2112 "gram.c" +#line 2170 "gram.c" break; case 47: /* digestspec: SHA384_TOK ':' DIGEST */ -#line 525 "gram.y" +#line 571 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA384, (yyvsp[0].string)); if ((yyval.digest) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_DIGEST, (yyval.digest)); } -#line 2124 "gram.c" +#line 2184 "gram.c" break; case 48: /* digestspec: SHA512_TOK ':' DIGEST */ -#line 532 "gram.y" +#line 580 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA512, (yyvsp[0].string)); if ((yyval.digest) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_DIGEST, (yyval.digest)); } -#line 2136 "gram.c" +#line 2198 "gram.c" break; case 50: /* digestlist: digestlist ',' digestspec */ -#line 542 "gram.y" +#line 592 "gram.y" { + parser_leak_remove(LEAK_DIGEST, (yyvsp[0].digest)); HLTQ_CONCAT((yyvsp[-2].digest), (yyvsp[0].digest), entries); (yyval.digest) = (yyvsp[-2].digest); } -#line 2145 "gram.c" +#line 2208 "gram.c" break; case 51: /* digcmnd: opcmnd */ -#line 548 "gram.y" +#line 599 "gram.y" { (yyval.member) = (yyvsp[0].member); } -#line 2153 "gram.c" +#line 2216 "gram.c" break; case 52: /* digcmnd: digestlist opcmnd */ -#line 551 "gram.y" +#line 602 "gram.y" { struct sudo_command *c = (struct sudo_command *) (yyvsp[0].member)->name; @@ -2176,32 +2239,33 @@ yyreduce: } (yyvsp[0].member)->name = (char *)c; } + parser_leak_remove(LEAK_DIGEST, (yyvsp[-1].digest)); HLTQ_TO_TAILQ(&c->digests, (yyvsp[-1].digest), entries); (yyval.member) = (yyvsp[0].member); } -#line 2177 "gram.c" +#line 2241 "gram.c" break; case 53: /* opcmnd: cmnd */ -#line 572 "gram.y" +#line 624 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = false; } -#line 2186 "gram.c" +#line 2250 "gram.c" break; case 54: /* opcmnd: '!' cmnd */ -#line 576 "gram.y" +#line 628 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = true; } -#line 2195 "gram.c" +#line 2259 "gram.c" break; case 55: /* chdirspec: CWD '=' WORD */ -#line 582 "gram.y" +#line 634 "gram.y" { if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') { if (strcmp((yyvsp[0].string), "*") != 0) { @@ -2212,11 +2276,11 @@ yyreduce: } (yyval.string) = (yyvsp[0].string); } -#line 2210 "gram.c" +#line 2274 "gram.c" break; case 56: /* chrootspec: CHROOT '=' WORD */ -#line 594 "gram.y" +#line 646 "gram.y" { if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') { if (strcmp((yyvsp[0].string), "*") != 0) { @@ -2227,83 +2291,83 @@ yyreduce: } (yyval.string) = (yyvsp[0].string); } -#line 2225 "gram.c" +#line 2289 "gram.c" break; case 57: /* timeoutspec: CMND_TIMEOUT '=' WORD */ -#line 606 "gram.y" +#line 658 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2233 "gram.c" +#line 2297 "gram.c" break; case 58: /* notbeforespec: NOTBEFORE '=' WORD */ -#line 611 "gram.y" +#line 663 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2241 "gram.c" +#line 2305 "gram.c" break; case 59: /* notafterspec: NOTAFTER '=' WORD */ -#line 615 "gram.y" +#line 667 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2249 "gram.c" +#line 2313 "gram.c" break; case 60: /* rolespec: ROLE '=' WORD */ -#line 620 "gram.y" +#line 672 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2257 "gram.c" +#line 2321 "gram.c" break; case 61: /* typespec: TYPE '=' WORD */ -#line 625 "gram.y" +#line 677 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2265 "gram.c" +#line 2329 "gram.c" break; case 62: /* privsspec: PRIVS '=' WORD */ -#line 630 "gram.y" +#line 682 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2273 "gram.c" +#line 2337 "gram.c" break; case 63: /* limitprivsspec: LIMITPRIVS '=' WORD */ -#line 634 "gram.y" +#line 686 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2281 "gram.c" +#line 2345 "gram.c" break; case 64: /* runasspec: %empty */ -#line 639 "gram.y" +#line 691 "gram.y" { (yyval.runas) = NULL; } -#line 2289 "gram.c" +#line 2353 "gram.c" break; case 65: /* runasspec: '(' runaslist ')' */ -#line 642 "gram.y" +#line 694 "gram.y" { (yyval.runas) = (yyvsp[-1].runas); } -#line 2297 "gram.c" +#line 2361 "gram.c" break; case 66: /* runaslist: %empty */ -#line 647 "gram.y" +#line 699 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) != NULL) { @@ -2318,54 +2382,62 @@ yyreduce: sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_RUNAS, (yyval.runas)); } -#line 2317 "gram.c" +#line 2382 "gram.c" break; case 67: /* runaslist: userlist */ -#line 662 "gram.y" +#line 715 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_RUNAS, (yyval.runas)); + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); (yyval.runas)->runasusers = (yyvsp[0].member); /* $$->runasgroups = NULL; */ } -#line 2331 "gram.c" +#line 2398 "gram.c" break; case 68: /* runaslist: userlist ':' grouplist */ -#line 671 "gram.y" +#line 726 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_RUNAS, (yyval.runas)); + parser_leak_remove(LEAK_MEMBER, (yyvsp[-2].member)); + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); (yyval.runas)->runasusers = (yyvsp[-2].member); (yyval.runas)->runasgroups = (yyvsp[0].member); } -#line 2345 "gram.c" +#line 2415 "gram.c" break; case 69: /* runaslist: ':' grouplist */ -#line 680 "gram.y" +#line 738 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_RUNAS, (yyval.runas)); + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); /* $$->runasusers = NULL; */ (yyval.runas)->runasgroups = (yyvsp[0].member); } -#line 2359 "gram.c" +#line 2431 "gram.c" break; case 70: /* runaslist: ':' */ -#line 689 "gram.y" +#line 749 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) != NULL) { @@ -2380,135 +2452,141 @@ yyreduce: sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_RUNAS, (yyval.runas)); } -#line 2379 "gram.c" +#line 2452 "gram.c" break; case 71: /* reserved_word: ALL */ -#line 706 "gram.y" +#line 767 "gram.y" { (yyval.string) = "ALL"; } -#line 2385 "gram.c" +#line 2458 "gram.c" break; case 72: /* reserved_word: CHROOT */ -#line 707 "gram.y" +#line 768 "gram.y" { (yyval.string) = "CHROOT"; } -#line 2391 "gram.c" +#line 2464 "gram.c" break; case 73: /* reserved_word: CWD */ -#line 708 "gram.y" +#line 769 "gram.y" { (yyval.string) = "CWD"; } -#line 2397 "gram.c" +#line 2470 "gram.c" break; case 74: /* reserved_word: CMND_TIMEOUT */ -#line 709 "gram.y" +#line 770 "gram.y" { (yyval.string) = "CMND_TIMEOUT"; } -#line 2403 "gram.c" +#line 2476 "gram.c" break; case 75: /* reserved_word: NOTBEFORE */ -#line 710 "gram.y" +#line 771 "gram.y" { (yyval.string) = "NOTBEFORE"; } -#line 2409 "gram.c" +#line 2482 "gram.c" break; case 76: /* reserved_word: NOTAFTER */ -#line 711 "gram.y" +#line 772 "gram.y" { (yyval.string) = "NOTAFTER"; } -#line 2415 "gram.c" +#line 2488 "gram.c" break; case 77: /* reserved_word: ROLE */ -#line 712 "gram.y" +#line 773 "gram.y" { (yyval.string) = "ROLE"; } -#line 2421 "gram.c" +#line 2494 "gram.c" break; case 78: /* reserved_word: TYPE */ -#line 713 "gram.y" +#line 774 "gram.y" { (yyval.string) = "TYPE"; } -#line 2427 "gram.c" +#line 2500 "gram.c" break; case 79: /* reserved_word: PRIVS */ -#line 714 "gram.y" +#line 775 "gram.y" { (yyval.string) = "PRIVS"; } -#line 2433 "gram.c" +#line 2506 "gram.c" break; case 80: /* reserved_word: LIMITPRIVS */ -#line 715 "gram.y" +#line 776 "gram.y" { (yyval.string) = "LIMITPRIVS"; } -#line 2439 "gram.c" +#line 2512 "gram.c" break; case 81: /* reserved_alias: reserved_word */ -#line 718 "gram.y" +#line 779 "gram.y" { sudoerserrorf(U_("syntax error, reserved word %s used as an alias name"), (yyvsp[0].string)); YYERROR; } -#line 2448 "gram.c" +#line 2521 "gram.c" break; case 82: /* options: %empty */ -#line 724 "gram.y" +#line 785 "gram.y" { init_options(&(yyval.options)); } -#line 2456 "gram.c" +#line 2529 "gram.c" break; case 83: /* options: options chdirspec */ -#line 727 "gram.y" +#line 788 "gram.y" { free((yyval.options).runcwd); (yyval.options).runcwd = (yyvsp[0].string); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); } -#line 2465 "gram.c" +#line 2539 "gram.c" break; case 84: /* options: options chrootspec */ -#line 731 "gram.y" +#line 793 "gram.y" { free((yyval.options).runchroot); (yyval.options).runchroot = (yyvsp[0].string); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); } -#line 2474 "gram.c" +#line 2549 "gram.c" break; case 85: /* options: options notbeforespec */ -#line 735 "gram.y" +#line 798 "gram.y" { (yyval.options).notbefore = parse_gentime((yyvsp[0].string)); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); free((yyvsp[0].string)); if ((yyval.options).notbefore == -1) { sudoerserror(N_("invalid notbefore value")); YYERROR; } } -#line 2487 "gram.c" +#line 2563 "gram.c" break; case 86: /* options: options notafterspec */ -#line 743 "gram.y" +#line 807 "gram.y" { (yyval.options).notafter = parse_gentime((yyvsp[0].string)); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); free((yyvsp[0].string)); if ((yyval.options).notafter == -1) { sudoerserror(N_("invalid notafter value")); YYERROR; } } -#line 2500 "gram.c" +#line 2577 "gram.c" break; case 87: /* options: options timeoutspec */ -#line 751 "gram.y" +#line 816 "gram.y" { (yyval.options).timeout = parse_timeout((yyvsp[0].string)); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); free((yyvsp[0].string)); if ((yyval.options).timeout == -1) { if (errno == ERANGE) @@ -2518,199 +2596,206 @@ yyreduce: YYERROR; } } -#line 2516 "gram.c" +#line 2594 "gram.c" break; case 88: /* options: options rolespec */ -#line 762 "gram.y" +#line 828 "gram.y" { #ifdef HAVE_SELINUX free((yyval.options).role); (yyval.options).role = (yyvsp[0].string); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); #endif } -#line 2527 "gram.c" +#line 2606 "gram.c" break; case 89: /* options: options typespec */ -#line 768 "gram.y" +#line 835 "gram.y" { #ifdef HAVE_SELINUX free((yyval.options).type); (yyval.options).type = (yyvsp[0].string); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); #endif } -#line 2538 "gram.c" +#line 2618 "gram.c" break; case 90: /* options: options privsspec */ -#line 774 "gram.y" +#line 842 "gram.y" { #ifdef HAVE_PRIV_SET free((yyval.options).privs); (yyval.options).privs = (yyvsp[0].string); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); #endif } -#line 2549 "gram.c" +#line 2630 "gram.c" break; case 91: /* options: options limitprivsspec */ -#line 780 "gram.y" +#line 849 "gram.y" { #ifdef HAVE_PRIV_SET free((yyval.options).limitprivs); (yyval.options).limitprivs = (yyvsp[0].string); + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); #endif } -#line 2560 "gram.c" +#line 2642 "gram.c" break; case 92: /* cmndtag: %empty */ -#line 788 "gram.y" +#line 858 "gram.y" { TAGS_INIT(&(yyval.tag)); } -#line 2568 "gram.c" +#line 2650 "gram.c" break; case 93: /* cmndtag: cmndtag NOPASSWD */ -#line 791 "gram.y" +#line 861 "gram.y" { (yyval.tag).nopasswd = true; } -#line 2576 "gram.c" +#line 2658 "gram.c" break; case 94: /* cmndtag: cmndtag PASSWD */ -#line 794 "gram.y" +#line 864 "gram.y" { (yyval.tag).nopasswd = false; } -#line 2584 "gram.c" +#line 2666 "gram.c" break; case 95: /* cmndtag: cmndtag NOEXEC */ -#line 797 "gram.y" +#line 867 "gram.y" { (yyval.tag).noexec = true; } -#line 2592 "gram.c" +#line 2674 "gram.c" break; case 96: /* cmndtag: cmndtag EXEC */ -#line 800 "gram.y" +#line 870 "gram.y" { (yyval.tag).noexec = false; } -#line 2600 "gram.c" +#line 2682 "gram.c" break; case 97: /* cmndtag: cmndtag SETENV */ -#line 803 "gram.y" +#line 873 "gram.y" { (yyval.tag).setenv = true; } -#line 2608 "gram.c" +#line 2690 "gram.c" break; case 98: /* cmndtag: cmndtag NOSETENV */ -#line 806 "gram.y" +#line 876 "gram.y" { (yyval.tag).setenv = false; } -#line 2616 "gram.c" +#line 2698 "gram.c" break; case 99: /* cmndtag: cmndtag LOG_INPUT */ -#line 809 "gram.y" +#line 879 "gram.y" { (yyval.tag).log_input = true; } -#line 2624 "gram.c" +#line 2706 "gram.c" break; case 100: /* cmndtag: cmndtag NOLOG_INPUT */ -#line 812 "gram.y" +#line 882 "gram.y" { (yyval.tag).log_input = false; } -#line 2632 "gram.c" +#line 2714 "gram.c" break; case 101: /* cmndtag: cmndtag LOG_OUTPUT */ -#line 815 "gram.y" +#line 885 "gram.y" { (yyval.tag).log_output = true; } -#line 2640 "gram.c" +#line 2722 "gram.c" break; case 102: /* cmndtag: cmndtag NOLOG_OUTPUT */ -#line 818 "gram.y" +#line 888 "gram.y" { (yyval.tag).log_output = false; } -#line 2648 "gram.c" +#line 2730 "gram.c" break; case 103: /* cmndtag: cmndtag FOLLOWLNK */ -#line 821 "gram.y" +#line 891 "gram.y" { (yyval.tag).follow = true; } -#line 2656 "gram.c" +#line 2738 "gram.c" break; case 104: /* cmndtag: cmndtag NOFOLLOWLNK */ -#line 824 "gram.y" +#line 894 "gram.y" { (yyval.tag).follow = false; } -#line 2664 "gram.c" +#line 2746 "gram.c" break; case 105: /* cmndtag: cmndtag MAIL */ -#line 827 "gram.y" +#line 897 "gram.y" { (yyval.tag).send_mail = true; } -#line 2672 "gram.c" +#line 2754 "gram.c" break; case 106: /* cmndtag: cmndtag NOMAIL */ -#line 830 "gram.y" +#line 900 "gram.y" { (yyval.tag).send_mail = false; } -#line 2680 "gram.c" +#line 2762 "gram.c" break; case 107: /* cmnd: ALL */ -#line 835 "gram.y" +#line 905 "gram.y" { (yyval.member) = new_member(NULL, ALL); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 2692 "gram.c" +#line 2775 "gram.c" break; case 108: /* cmnd: ALIAS */ -#line 842 "gram.y" +#line 913 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), ALIAS); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 2704 "gram.c" +#line 2789 "gram.c" break; case 109: /* cmnd: COMMAND */ -#line 849 "gram.y" +#line 922 "gram.y" { struct sudo_command *c; @@ -2724,264 +2809,294 @@ yyreduce: sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].command).cmnd); + if ((yyvsp[0].command).args != NULL) + parser_leak_remove(LEAK_PTR, (yyvsp[0].command).args); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 2723 "gram.c" +#line 2812 "gram.c" break; case 112: /* $@1: %empty */ -#line 869 "gram.y" +#line 946 "gram.y" { alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } -#line 2732 "gram.c" +#line 2821 "gram.c" break; case 113: /* hostalias: ALIAS $@1 '=' hostlist */ -#line 872 "gram.y" +#line 949 "gram.y" { if (!alias_add(&parsed_policy, (yyvsp[-3].string), HOSTALIAS, sudoers, alias_line, alias_column, (yyvsp[0].member))) { alias_error((yyvsp[-3].string), errno); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[-3].string)); + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); } -#line 2744 "gram.c" +#line 2835 "gram.c" break; case 116: /* hostlist: hostlist ',' ophost */ -#line 883 "gram.y" +#line 962 "gram.y" { + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries); (yyval.member) = (yyvsp[-2].member); } -#line 2753 "gram.c" +#line 2845 "gram.c" break; case 119: /* $@2: %empty */ -#line 893 "gram.y" +#line 973 "gram.y" { alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } -#line 2762 "gram.c" +#line 2854 "gram.c" break; case 120: /* cmndalias: ALIAS $@2 '=' cmndlist */ -#line 896 "gram.y" +#line 976 "gram.y" { if (!alias_add(&parsed_policy, (yyvsp[-3].string), CMNDALIAS, sudoers, alias_line, alias_column, (yyvsp[0].member))) { alias_error((yyvsp[-3].string), errno); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[-3].string)); + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); } -#line 2774 "gram.c" +#line 2868 "gram.c" break; case 123: /* cmndlist: cmndlist ',' digcmnd */ -#line 907 "gram.y" +#line 989 "gram.y" { + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries); (yyval.member) = (yyvsp[-2].member); } -#line 2783 "gram.c" +#line 2878 "gram.c" break; case 126: /* $@3: %empty */ -#line 917 "gram.y" +#line 1000 "gram.y" { alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } -#line 2792 "gram.c" +#line 2887 "gram.c" break; case 127: /* runasalias: ALIAS $@3 '=' userlist */ -#line 920 "gram.y" +#line 1003 "gram.y" { if (!alias_add(&parsed_policy, (yyvsp[-3].string), RUNASALIAS, sudoers, alias_line, alias_column, (yyvsp[0].member))) { alias_error((yyvsp[-3].string), errno); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[-3].string)); + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); } -#line 2804 "gram.c" +#line 2901 "gram.c" break; case 131: /* $@4: %empty */ -#line 934 "gram.y" +#line 1019 "gram.y" { alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } -#line 2813 "gram.c" +#line 2910 "gram.c" break; case 132: /* useralias: ALIAS $@4 '=' userlist */ -#line 937 "gram.y" +#line 1022 "gram.y" { if (!alias_add(&parsed_policy, (yyvsp[-3].string), USERALIAS, sudoers, alias_line, alias_column, (yyvsp[0].member))) { alias_error((yyvsp[-3].string), errno); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[-3].string)); + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); } -#line 2825 "gram.c" +#line 2924 "gram.c" break; case 135: /* userlist: userlist ',' opuser */ -#line 948 "gram.y" +#line 1035 "gram.y" { + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries); (yyval.member) = (yyvsp[-2].member); } -#line 2834 "gram.c" +#line 2934 "gram.c" break; case 136: /* opuser: user */ -#line 954 "gram.y" +#line 1042 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = false; } -#line 2843 "gram.c" +#line 2943 "gram.c" break; case 137: /* opuser: '!' user */ -#line 958 "gram.y" +#line 1046 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = true; } -#line 2852 "gram.c" +#line 2952 "gram.c" break; case 138: /* user: ALIAS */ -#line 964 "gram.y" +#line 1052 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), ALIAS); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 2864 "gram.c" +#line 2966 "gram.c" break; case 139: /* user: ALL */ -#line 971 "gram.y" +#line 1061 "gram.y" { (yyval.member) = new_member(NULL, ALL); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 2876 "gram.c" +#line 2979 "gram.c" break; case 140: /* user: NETGROUP */ -#line 978 "gram.y" +#line 1069 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), NETGROUP); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 2888 "gram.c" +#line 2993 "gram.c" break; case 141: /* user: USERGROUP */ -#line 985 "gram.y" +#line 1078 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), USERGROUP); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 2900 "gram.c" +#line 3007 "gram.c" break; case 142: /* user: WORD */ -#line 992 "gram.y" +#line 1087 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), WORD); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 2912 "gram.c" +#line 3021 "gram.c" break; case 144: /* grouplist: grouplist ',' opgroup */ -#line 1002 "gram.y" +#line 1099 "gram.y" { + parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries); (yyval.member) = (yyvsp[-2].member); } -#line 2921 "gram.c" +#line 3031 "gram.c" break; case 145: /* opgroup: group */ -#line 1008 "gram.y" +#line 1106 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = false; } -#line 2930 "gram.c" +#line 3040 "gram.c" break; case 146: /* opgroup: '!' group */ -#line 1012 "gram.y" +#line 1110 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = true; } -#line 2939 "gram.c" +#line 3049 "gram.c" break; case 147: /* group: ALIAS */ -#line 1018 "gram.y" +#line 1116 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), ALIAS); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 2951 "gram.c" +#line 3063 "gram.c" break; case 148: /* group: ALL */ -#line 1025 "gram.y" +#line 1125 "gram.y" { (yyval.member) = new_member(NULL, ALL); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 2963 "gram.c" +#line 3076 "gram.c" break; case 149: /* group: WORD */ -#line 1032 "gram.y" +#line 1133 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), WORD); if ((yyval.member) == NULL) { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); + parser_leak_add(LEAK_MEMBER, (yyval.member)); } -#line 2975 "gram.c" +#line 3090 "gram.c" break; -#line 2979 "gram.c" +#line 3094 "gram.c" default: break; } @@ -3175,7 +3290,7 @@ yyreturn: return yyresult; } -#line 1040 "gram.y" +#line 1143 "gram.y" /* Like yyerror() but takes a printf-style format string. */ void @@ -3327,6 +3442,7 @@ new_command(char *cmnd, char *args) "unable to allocate memory"); debug_return_ptr(NULL); } + /* garbage collected as part of struct member */ c->cmnd = cmnd; c->args = args; @@ -3383,15 +3499,18 @@ add_defaults(int type, struct member *bmem, struct defaults *defs) sudoerserror(N_("unable to allocate memory")); debug_return_bool(false); } - if (bmem != NULL) + if (bmem != NULL) { + parser_leak_remove(LEAK_MEMBER, bmem); HLTQ_TO_TAILQ(binding, bmem, entries); - else + } else { TAILQ_INIT(binding); + } /* * Set type and binding (who it applies to) for new entries. * Then add to the global defaults list. */ + parser_leak_remove(LEAK_DEFAULTS, defs); HLTQ_FOREACH_SAFE(d, defs, entries, next) { d->type = type; d->binding = binding; @@ -3420,7 +3539,9 @@ add_userspec(struct member *members, struct privilege *privs) u->line = this_lineno; u->column = sudolinebuf.toke_start + 1; u->file = rcstr_addref(sudoers); + parser_leak_remove(LEAK_MEMBER, members); HLTQ_TO_TAILQ(&u->users, members, entries); + parser_leak_remove(LEAK_PRIVILEGE, privs); HLTQ_TO_TAILQ(&u->privileges, privs, entries); STAILQ_INIT(&u->comments); TAILQ_INSERT_TAIL(&parsed_policy.userspecs, u, entries); @@ -3506,12 +3627,9 @@ free_default(struct defaults *def, struct member_list **binding) } void -free_privilege(struct privilege *priv) +free_cmndspecs(struct cmndspec_list *csl) { struct member_list *runasuserlist = NULL, *runasgrouplist = NULL; - struct member_list *prev_binding = NULL; - struct cmndspec *cs; - struct defaults *def; char *runcwd = NULL, *runchroot = NULL; #ifdef HAVE_SELINUX char *role = NULL, *type = NULL; @@ -3519,12 +3637,12 @@ free_privilege(struct privilege *priv) #ifdef HAVE_PRIV_SET char *privs = NULL, *limitprivs = NULL; #endif /* HAVE_PRIV_SET */ - debug_decl(free_privilege, SUDOERS_DEBUG_PARSER); + struct cmndspec *cs; + debug_decl(free_cmndspecs, SUDOERS_DEBUG_PARSER); + + while ((cs = TAILQ_FIRST(csl)) != NULL) { + TAILQ_REMOVE(csl, cs, entries); - free(priv->ldap_role); - free_members(&priv->hostlist); - while ((cs = TAILQ_FIRST(&priv->cmndlist)) != NULL) { - TAILQ_REMOVE(&priv->cmndlist, cs, entries); /* Only free the first instance of runcwd/runchroot. */ if (cs->runcwd != runcwd) { runcwd = cs->runcwd; @@ -3570,6 +3688,20 @@ free_privilege(struct privilege *priv) free_member(cs->cmnd); free(cs); } + + debug_return; +} + +void +free_privilege(struct privilege *priv) +{ + struct member_list *prev_binding = NULL; + struct defaults *def; + debug_decl(free_privilege, SUDOERS_DEBUG_PARSER); + + free(priv->ldap_role); + free_members(&priv->hostlist); + free_cmndspecs(&priv->cmndlist); while ((def = TAILQ_FIRST(&priv->defaults)) != NULL) { TAILQ_REMOVE(&priv->defaults, def, entries); free_default(def, &prev_binding); @@ -3665,6 +3797,7 @@ init_parser(const char *path, bool quiet, bool strict) debug_decl(init_parser, SUDOERS_DEBUG_PARSER); free_parse_tree(&parsed_policy); + parser_leak_init(); init_lexer(); rcstr_delref(sudoers); @@ -3707,3 +3840,215 @@ init_options(struct command_options *opts) opts->limitprivs = NULL; #endif } + +bool +parser_leak_add(enum parser_leak_types type, void *v) +{ +#ifdef NO_LEAKS + struct parser_leak_entry *entry; + debug_decl(parser_leak_add, SUDOERS_DEBUG_PARSER); + + if (v == NULL) + debug_return_bool(false); + + entry = calloc(1, sizeof(*entry)); + if (entry == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + debug_return_bool(false); + } + switch (type) { + case LEAK_PRIVILEGE: + entry->u.p = v; + break; + case LEAK_CMNDSPEC: + entry->u.cs = v; + break; + case LEAK_DEFAULTS: + entry->u.d = v; + break; + case LEAK_MEMBER: + entry->u.m = v; + break; + case LEAK_DIGEST: + entry->u.dig = v; + break; + case LEAK_RUNAS: + entry->u.rc = v; + break; + case LEAK_PTR: + entry->u.ptr = v; + break; + default: + free(entry); + sudo_warnx("unexpected leak type %d", type); + debug_return_bool(false); + } + entry->type = type; + SLIST_INSERT_HEAD(&parser_leak_list, entry, entries); + debug_return_bool(true); +#else + return true; +#endif /* NO_LEAKS */ +} + +bool +parser_leak_remove(enum parser_leak_types type, void *v) +{ +#ifdef NO_LEAKS + struct parser_leak_entry *entry, *prev = NULL; + debug_decl(parser_leak_remove, SUDOERS_DEBUG_PARSER); + + SLIST_FOREACH(entry, &parser_leak_list, entries) { + switch (entry->type) { + case LEAK_PRIVILEGE: + if (entry->u.p == v) + goto found; + break; + case LEAK_CMNDSPEC: + if (entry->u.cs == v) + goto found; + break; + case LEAK_DEFAULTS: + if (entry->u.d == v) + goto found; + break; + case LEAK_MEMBER: + if (entry->u.m == v) + goto found; + break; + case LEAK_DIGEST: + if (entry->u.dig == v) + goto found; + break; + case LEAK_RUNAS: + if (entry->u.rc == v) + goto found; + break; + case LEAK_PTR: + if (entry->u.ptr == v) + goto found; + break; + default: + sudo_warnx("unexpected leak type %d in %p", entry->type, entry); + } + prev = entry; + } + /* If this happens, there is a bug in the leak tracking code. */ + sudo_warnx("%s: unable to find %p, type %d", __func__, v, type); + return false; +found: + if (prev == NULL) + SLIST_REMOVE_HEAD(&parser_leak_list, entries); + else + SLIST_REMOVE_AFTER(prev, entries); + free(entry); + return true; +#endif /* NO_LEAKS */ +} + +void +parser_leak_free(void) +{ +#ifdef NO_LEAKS + struct parser_leak_entry *entry; + void *next; + debug_decl(parser_leak_run, SUDOERS_DEBUG_PARSER); + + /* Free the leaks. */ + while ((entry = SLIST_FIRST(&parser_leak_list))) { + SLIST_REMOVE_HEAD(&parser_leak_list, entries); + switch (entry->type) { + case LEAK_PRIVILEGE: + { + struct privilege *priv; + + HLTQ_FOREACH_SAFE(priv, entry->u.p, entries, next) + free_privilege(priv); + free(entry); + } + break; + case LEAK_CMNDSPEC: + { + struct cmndspec_list specs; + + HLTQ_TO_TAILQ(&specs, entry->u.cs, entries); + free_cmndspecs(&specs); + free(entry); + } + break; + case LEAK_DEFAULTS: + { + struct defaults_list defs; + + HLTQ_TO_TAILQ(&defs, entry->u.d, entries); + free_defaults(&defs); + free(entry); + } + break; + case LEAK_MEMBER: + { + struct member *m; + + HLTQ_FOREACH_SAFE(m, entry->u.m, entries, next) + free_member(m); + free(entry); + } + break; + case LEAK_DIGEST: + { + struct command_digest *dig; + + HLTQ_FOREACH_SAFE(dig, entry->u.dig, entries, next) { + free(dig->digest_str); + free(dig); + } + free(entry); + } + break; + case LEAK_RUNAS: + { + struct member *m; + + if (entry->u.rc->runasusers != NULL) { + HLTQ_FOREACH_SAFE(m, entry->u.rc->runasusers, entries, next) + free_member(m); + } + if (entry->u.rc->runasgroups != NULL) { + HLTQ_FOREACH_SAFE(m, entry->u.rc->runasgroups, entries, next) + free_member(m); + } + free(entry->u.rc); + free(entry); + break; + } + case LEAK_PTR: + free(entry->u.ptr); + free(entry); + break; + default: + sudo_warnx("unexpected garbage type %d", entry->type); + } + } + + debug_return; +#endif /* NO_LEAKS */ +} + +void +parser_leak_init(void) +{ +#ifdef NO_LEAKS + static bool initialized; + debug_decl(parser_leak_init, SUDOERS_DEBUG_PARSER); + + if (!initialized) { + atexit(parser_leak_free); + initialized = true; + debug_return; + } + + /* Already initialized, free existing leaks. */ + parser_leak_free(); + debug_return; +#endif /* NO_LEAKS */ +} diff --git a/plugins/sudoers/gram.h b/plugins/sudoers/gram.h index 97c6638..e862e11 100644 --- a/plugins/sudoers/gram.h +++ b/plugins/sudoers/gram.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.7.5. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -167,7 +167,7 @@ extern int sudoersdebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 83 "gram.y" +#line 88 "gram.y" struct cmndspec *cmndspec; struct defaults *defaults; diff --git a/plugins/sudoers/gram.y b/plugins/sudoers/gram.y index d4dcf0d..236f697 100644 --- a/plugins/sudoers/gram.y +++ b/plugins/sudoers/gram.y @@ -59,6 +59,11 @@ char *errorfile = NULL; static int alias_line, alias_column; +#ifdef NO_LEAKS +static struct parser_leak_list parser_leak_list = + SLIST_HEAD_INITIALIZER(parser_leak_list); +#endif + struct sudoers_parse_tree parsed_policy = { TAILQ_HEAD_INITIALIZER(parsed_policy.userspecs), TAILQ_HEAD_INITIALIZER(parsed_policy.defaults), @@ -207,16 +212,20 @@ entry : '\n' { } | include { if (!push_include($1, false)) { + parser_leak_remove(LEAK_PTR, $1); free($1); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); free($1); } | includedir { if (!push_include($1, true)) { + parser_leak_remove(LEAK_PTR, $1); free($1); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); free($1); } | userlist privileges '\n' { @@ -279,6 +288,7 @@ includedir : INCLUDEDIR WORD '\n' { defaults_list : defaults_entry | defaults_list ',' defaults_entry { + parser_leak_remove(LEAK_DEFAULTS, $3); HLTQ_CONCAT($1, $3, entries); $$ = $1; } @@ -290,6 +300,8 @@ defaults_entry : DEFVAR { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_DEFAULTS, $$); } | '!' DEFVAR { $$ = new_default($2, NULL, false); @@ -297,6 +309,8 @@ defaults_entry : DEFVAR { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $2); + parser_leak_add(LEAK_DEFAULTS, $$); } | DEFVAR '=' WORD { $$ = new_default($1, $3, true); @@ -304,6 +318,9 @@ defaults_entry : DEFVAR { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_remove(LEAK_PTR, $3); + parser_leak_add(LEAK_DEFAULTS, $$); } | DEFVAR '+' WORD { $$ = new_default($1, $3, '+'); @@ -311,6 +328,9 @@ defaults_entry : DEFVAR { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_remove(LEAK_PTR, $3); + parser_leak_add(LEAK_DEFAULTS, $$); } | DEFVAR '-' WORD { $$ = new_default($1, $3, '-'); @@ -318,11 +338,15 @@ defaults_entry : DEFVAR { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_remove(LEAK_PTR, $3); + parser_leak_add(LEAK_DEFAULTS, $$); } ; privileges : privilege | privileges ':' privilege { + parser_leak_remove(LEAK_PRIVILEGE, $3); HLTQ_CONCAT($1, $3, entries); $$ = $1; } @@ -338,8 +362,11 @@ privilege : hostlist '=' cmndspeclist { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_PRIVILEGE, p); TAILQ_INIT(&p->defaults); + parser_leak_remove(LEAK_MEMBER, $1); HLTQ_TO_TAILQ(&p->hostlist, $1, entries); + parser_leak_remove(LEAK_CMNDSPEC, $3); HLTQ_TO_TAILQ(&p->cmndlist, $3, entries); HLTQ_INIT(p, entries); $$ = p; @@ -362,6 +389,8 @@ host : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_MEMBER, $$); } | ALL { $$ = new_member(NULL, ALL); @@ -369,6 +398,7 @@ host : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_MEMBER, $$); } | NETGROUP { $$ = new_member($1, NETGROUP); @@ -376,6 +406,8 @@ host : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_MEMBER, $$); } | NTWKADDR { $$ = new_member($1, NTWKADDR); @@ -383,6 +415,8 @@ host : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_MEMBER, $$); } | WORD { $$ = new_member($1, WORD); @@ -390,6 +424,8 @@ host : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_MEMBER, $$); } ; @@ -397,6 +433,7 @@ cmndspeclist : cmndspec | cmndspeclist ',' cmndspec { struct cmndspec *prev; prev = HLTQ_LAST($1, cmndspec, entries); + parser_leak_remove(LEAK_CMNDSPEC, $3); HLTQ_CONCAT($1, $3, entries); /* propagate runcwd and runchroot */ @@ -459,6 +496,7 @@ cmndspec : runasspec options cmndtag digcmnd { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_CMNDSPEC, cs); if ($1 != NULL) { if ($1->runasusers != NULL) { cs->runasuserlist = @@ -468,6 +506,7 @@ cmndspec : runasspec options cmndtag digcmnd { sudoerserror(N_("unable to allocate memory")); YYERROR; } + /* g/c done via runas container */ HLTQ_TO_TAILQ(cs->runasuserlist, $1->runasusers, entries); } @@ -479,9 +518,11 @@ cmndspec : runasspec options cmndtag digcmnd { sudoerserror(N_("unable to allocate memory")); YYERROR; } + /* g/c done via runas container */ HLTQ_TO_TAILQ(cs->runasgrouplist, $1->runasgroups, entries); } + parser_leak_remove(LEAK_RUNAS, $1); free($1); } #ifdef HAVE_SELINUX @@ -499,6 +540,7 @@ cmndspec : runasspec options cmndtag digcmnd { cs->runchroot = $2.runchroot; cs->tags = $3; cs->cmnd = $4; + parser_leak_remove(LEAK_MEMBER, $4); HLTQ_INIT(cs, entries); /* sudo "ALL" implies the SETENV tag */ if (cs->cmnd->type == ALL && !cs->cmnd->negated && @@ -514,6 +556,8 @@ digestspec : SHA224_TOK ':' DIGEST { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $3); + parser_leak_add(LEAK_DIGEST, $$); } | SHA256_TOK ':' DIGEST { $$ = new_digest(SUDO_DIGEST_SHA256, $3); @@ -521,6 +565,8 @@ digestspec : SHA224_TOK ':' DIGEST { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $3); + parser_leak_add(LEAK_DIGEST, $$); } | SHA384_TOK ':' DIGEST { $$ = new_digest(SUDO_DIGEST_SHA384, $3); @@ -528,6 +574,8 @@ digestspec : SHA224_TOK ':' DIGEST { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $3); + parser_leak_add(LEAK_DIGEST, $$); } | SHA512_TOK ':' DIGEST { $$ = new_digest(SUDO_DIGEST_SHA512, $3); @@ -535,11 +583,14 @@ digestspec : SHA224_TOK ':' DIGEST { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $3); + parser_leak_add(LEAK_DIGEST, $$); } ; digestlist : digestspec | digestlist ',' digestspec { + parser_leak_remove(LEAK_DIGEST, $3); HLTQ_CONCAT($1, $3, entries); $$ = $1; } @@ -564,6 +615,7 @@ digcmnd : opcmnd { } $2->name = (char *)c; } + parser_leak_remove(LEAK_DIGEST, $1); HLTQ_TO_TAILQ(&c->digests, $1, entries); $$ = $2; } @@ -658,6 +710,7 @@ runaslist : /* empty */ { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_RUNAS, $$); } | userlist { $$ = calloc(1, sizeof(struct runascontainer)); @@ -665,6 +718,8 @@ runaslist : /* empty */ { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_RUNAS, $$); + parser_leak_remove(LEAK_MEMBER, $1); $$->runasusers = $1; /* $$->runasgroups = NULL; */ } @@ -674,6 +729,9 @@ runaslist : /* empty */ { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_RUNAS, $$); + parser_leak_remove(LEAK_MEMBER, $1); + parser_leak_remove(LEAK_MEMBER, $3); $$->runasusers = $1; $$->runasgroups = $3; } @@ -683,6 +741,8 @@ runaslist : /* empty */ { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_RUNAS, $$); + parser_leak_remove(LEAK_MEMBER, $2); /* $$->runasusers = NULL; */ $$->runasgroups = $2; } @@ -700,6 +760,7 @@ runaslist : /* empty */ { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_RUNAS, $$); } ; @@ -727,13 +788,16 @@ options : /* empty */ { | options chdirspec { free($$.runcwd); $$.runcwd = $2; + parser_leak_remove(LEAK_PTR, $2); } | options chrootspec { free($$.runchroot); $$.runchroot = $2; + parser_leak_remove(LEAK_PTR, $2); } | options notbeforespec { $$.notbefore = parse_gentime($2); + parser_leak_remove(LEAK_PTR, $2); free($2); if ($$.notbefore == -1) { sudoerserror(N_("invalid notbefore value")); @@ -742,6 +806,7 @@ options : /* empty */ { } | options notafterspec { $$.notafter = parse_gentime($2); + parser_leak_remove(LEAK_PTR, $2); free($2); if ($$.notafter == -1) { sudoerserror(N_("invalid notafter value")); @@ -750,6 +815,7 @@ options : /* empty */ { } | options timeoutspec { $$.timeout = parse_timeout($2); + parser_leak_remove(LEAK_PTR, $2); free($2); if ($$.timeout == -1) { if (errno == ERANGE) @@ -763,24 +829,28 @@ options : /* empty */ { #ifdef HAVE_SELINUX free($$.role); $$.role = $2; + parser_leak_remove(LEAK_PTR, $2); #endif } | options typespec { #ifdef HAVE_SELINUX free($$.type); $$.type = $2; + parser_leak_remove(LEAK_PTR, $2); #endif } | options privsspec { #ifdef HAVE_PRIV_SET free($$.privs); $$.privs = $2; + parser_leak_remove(LEAK_PTR, $2); #endif } | options limitprivsspec { #ifdef HAVE_PRIV_SET free($$.limitprivs); $$.limitprivs = $2; + parser_leak_remove(LEAK_PTR, $2); #endif } ; @@ -838,6 +908,7 @@ cmnd : ALL { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_MEMBER, $$); } | ALIAS { $$ = new_member($1, ALIAS); @@ -845,6 +916,8 @@ cmnd : ALL { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_MEMBER, $$); } | COMMAND { struct sudo_command *c; @@ -859,6 +932,10 @@ cmnd : ALL { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1.cmnd); + if ($1.args != NULL) + parser_leak_remove(LEAK_PTR, $1.args); + parser_leak_add(LEAK_MEMBER, $$); } ; @@ -875,12 +952,15 @@ hostalias : ALIAS { alias_error($1, errno); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_remove(LEAK_MEMBER, $4); } | reserved_alias '=' hostlist ; hostlist : ophost | hostlist ',' ophost { + parser_leak_remove(LEAK_MEMBER, $3); HLTQ_CONCAT($1, $3, entries); $$ = $1; } @@ -899,12 +979,15 @@ cmndalias : ALIAS { alias_error($1, errno); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_remove(LEAK_MEMBER, $4); } | reserved_alias '=' cmndlist ; cmndlist : digcmnd | cmndlist ',' digcmnd { + parser_leak_remove(LEAK_MEMBER, $3); HLTQ_CONCAT($1, $3, entries); $$ = $1; } @@ -923,6 +1006,8 @@ runasalias : ALIAS { alias_error($1, errno); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_remove(LEAK_MEMBER, $4); } | reserved_alias '=' userlist ; @@ -940,12 +1025,15 @@ useralias : ALIAS { alias_error($1, errno); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_remove(LEAK_MEMBER, $4); } | reserved_alias '=' userlist ; userlist : opuser | userlist ',' opuser { + parser_leak_remove(LEAK_MEMBER, $3); HLTQ_CONCAT($1, $3, entries); $$ = $1; } @@ -967,6 +1055,8 @@ user : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_MEMBER, $$); } | ALL { $$ = new_member(NULL, ALL); @@ -974,6 +1064,7 @@ user : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_MEMBER, $$); } | NETGROUP { $$ = new_member($1, NETGROUP); @@ -981,6 +1072,8 @@ user : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_MEMBER, $$); } | USERGROUP { $$ = new_member($1, USERGROUP); @@ -988,6 +1081,8 @@ user : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_MEMBER, $$); } | WORD { $$ = new_member($1, WORD); @@ -995,11 +1090,14 @@ user : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_MEMBER, $$); } ; grouplist : opgroup | grouplist ',' opgroup { + parser_leak_remove(LEAK_MEMBER, $3); HLTQ_CONCAT($1, $3, entries); $$ = $1; } @@ -1021,6 +1119,8 @@ group : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_MEMBER, $$); } | ALL { $$ = new_member(NULL, ALL); @@ -1028,6 +1128,7 @@ group : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_add(LEAK_MEMBER, $$); } | WORD { $$ = new_member($1, WORD); @@ -1035,6 +1136,8 @@ group : ALIAS { sudoerserror(N_("unable to allocate memory")); YYERROR; } + parser_leak_remove(LEAK_PTR, $1); + parser_leak_add(LEAK_MEMBER, $$); } ; %% @@ -1188,6 +1291,7 @@ new_command(char *cmnd, char *args) "unable to allocate memory"); debug_return_ptr(NULL); } + /* garbage collected as part of struct member */ c->cmnd = cmnd; c->args = args; @@ -1244,15 +1348,18 @@ add_defaults(int type, struct member *bmem, struct defaults *defs) sudoerserror(N_("unable to allocate memory")); debug_return_bool(false); } - if (bmem != NULL) + if (bmem != NULL) { + parser_leak_remove(LEAK_MEMBER, bmem); HLTQ_TO_TAILQ(binding, bmem, entries); - else + } else { TAILQ_INIT(binding); + } /* * Set type and binding (who it applies to) for new entries. * Then add to the global defaults list. */ + parser_leak_remove(LEAK_DEFAULTS, defs); HLTQ_FOREACH_SAFE(d, defs, entries, next) { d->type = type; d->binding = binding; @@ -1281,7 +1388,9 @@ add_userspec(struct member *members, struct privilege *privs) u->line = this_lineno; u->column = sudolinebuf.toke_start + 1; u->file = rcstr_addref(sudoers); + parser_leak_remove(LEAK_MEMBER, members); HLTQ_TO_TAILQ(&u->users, members, entries); + parser_leak_remove(LEAK_PRIVILEGE, privs); HLTQ_TO_TAILQ(&u->privileges, privs, entries); STAILQ_INIT(&u->comments); TAILQ_INSERT_TAIL(&parsed_policy.userspecs, u, entries); @@ -1367,12 +1476,9 @@ free_default(struct defaults *def, struct member_list **binding) } void -free_privilege(struct privilege *priv) +free_cmndspecs(struct cmndspec_list *csl) { struct member_list *runasuserlist = NULL, *runasgrouplist = NULL; - struct member_list *prev_binding = NULL; - struct cmndspec *cs; - struct defaults *def; char *runcwd = NULL, *runchroot = NULL; #ifdef HAVE_SELINUX char *role = NULL, *type = NULL; @@ -1380,12 +1486,12 @@ free_privilege(struct privilege *priv) #ifdef HAVE_PRIV_SET char *privs = NULL, *limitprivs = NULL; #endif /* HAVE_PRIV_SET */ - debug_decl(free_privilege, SUDOERS_DEBUG_PARSER); + struct cmndspec *cs; + debug_decl(free_cmndspecs, SUDOERS_DEBUG_PARSER); + + while ((cs = TAILQ_FIRST(csl)) != NULL) { + TAILQ_REMOVE(csl, cs, entries); - free(priv->ldap_role); - free_members(&priv->hostlist); - while ((cs = TAILQ_FIRST(&priv->cmndlist)) != NULL) { - TAILQ_REMOVE(&priv->cmndlist, cs, entries); /* Only free the first instance of runcwd/runchroot. */ if (cs->runcwd != runcwd) { runcwd = cs->runcwd; @@ -1431,6 +1537,20 @@ free_privilege(struct privilege *priv) free_member(cs->cmnd); free(cs); } + + debug_return; +} + +void +free_privilege(struct privilege *priv) +{ + struct member_list *prev_binding = NULL; + struct defaults *def; + debug_decl(free_privilege, SUDOERS_DEBUG_PARSER); + + free(priv->ldap_role); + free_members(&priv->hostlist); + free_cmndspecs(&priv->cmndlist); while ((def = TAILQ_FIRST(&priv->defaults)) != NULL) { TAILQ_REMOVE(&priv->defaults, def, entries); free_default(def, &prev_binding); @@ -1526,6 +1646,7 @@ init_parser(const char *path, bool quiet, bool strict) debug_decl(init_parser, SUDOERS_DEBUG_PARSER); free_parse_tree(&parsed_policy); + parser_leak_init(); init_lexer(); rcstr_delref(sudoers); @@ -1568,3 +1689,215 @@ init_options(struct command_options *opts) opts->limitprivs = NULL; #endif } + +bool +parser_leak_add(enum parser_leak_types type, void *v) +{ +#ifdef NO_LEAKS + struct parser_leak_entry *entry; + debug_decl(parser_leak_add, SUDOERS_DEBUG_PARSER); + + if (v == NULL) + debug_return_bool(false); + + entry = calloc(1, sizeof(*entry)); + if (entry == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + debug_return_bool(false); + } + switch (type) { + case LEAK_PRIVILEGE: + entry->u.p = v; + break; + case LEAK_CMNDSPEC: + entry->u.cs = v; + break; + case LEAK_DEFAULTS: + entry->u.d = v; + break; + case LEAK_MEMBER: + entry->u.m = v; + break; + case LEAK_DIGEST: + entry->u.dig = v; + break; + case LEAK_RUNAS: + entry->u.rc = v; + break; + case LEAK_PTR: + entry->u.ptr = v; + break; + default: + free(entry); + sudo_warnx("unexpected leak type %d", type); + debug_return_bool(false); + } + entry->type = type; + SLIST_INSERT_HEAD(&parser_leak_list, entry, entries); + debug_return_bool(true); +#else + return true; +#endif /* NO_LEAKS */ +} + +bool +parser_leak_remove(enum parser_leak_types type, void *v) +{ +#ifdef NO_LEAKS + struct parser_leak_entry *entry, *prev = NULL; + debug_decl(parser_leak_remove, SUDOERS_DEBUG_PARSER); + + SLIST_FOREACH(entry, &parser_leak_list, entries) { + switch (entry->type) { + case LEAK_PRIVILEGE: + if (entry->u.p == v) + goto found; + break; + case LEAK_CMNDSPEC: + if (entry->u.cs == v) + goto found; + break; + case LEAK_DEFAULTS: + if (entry->u.d == v) + goto found; + break; + case LEAK_MEMBER: + if (entry->u.m == v) + goto found; + break; + case LEAK_DIGEST: + if (entry->u.dig == v) + goto found; + break; + case LEAK_RUNAS: + if (entry->u.rc == v) + goto found; + break; + case LEAK_PTR: + if (entry->u.ptr == v) + goto found; + break; + default: + sudo_warnx("unexpected leak type %d in %p", entry->type, entry); + } + prev = entry; + } + /* If this happens, there is a bug in the leak tracking code. */ + sudo_warnx("%s: unable to find %p, type %d", __func__, v, type); + return false; +found: + if (prev == NULL) + SLIST_REMOVE_HEAD(&parser_leak_list, entries); + else + SLIST_REMOVE_AFTER(prev, entries); + free(entry); + return true; +#endif /* NO_LEAKS */ +} + +void +parser_leak_free(void) +{ +#ifdef NO_LEAKS + struct parser_leak_entry *entry; + void *next; + debug_decl(parser_leak_run, SUDOERS_DEBUG_PARSER); + + /* Free the leaks. */ + while ((entry = SLIST_FIRST(&parser_leak_list))) { + SLIST_REMOVE_HEAD(&parser_leak_list, entries); + switch (entry->type) { + case LEAK_PRIVILEGE: + { + struct privilege *priv; + + HLTQ_FOREACH_SAFE(priv, entry->u.p, entries, next) + free_privilege(priv); + free(entry); + } + break; + case LEAK_CMNDSPEC: + { + struct cmndspec_list specs; + + HLTQ_TO_TAILQ(&specs, entry->u.cs, entries); + free_cmndspecs(&specs); + free(entry); + } + break; + case LEAK_DEFAULTS: + { + struct defaults_list defs; + + HLTQ_TO_TAILQ(&defs, entry->u.d, entries); + free_defaults(&defs); + free(entry); + } + break; + case LEAK_MEMBER: + { + struct member *m; + + HLTQ_FOREACH_SAFE(m, entry->u.m, entries, next) + free_member(m); + free(entry); + } + break; + case LEAK_DIGEST: + { + struct command_digest *dig; + + HLTQ_FOREACH_SAFE(dig, entry->u.dig, entries, next) { + free(dig->digest_str); + free(dig); + } + free(entry); + } + break; + case LEAK_RUNAS: + { + struct member *m; + + if (entry->u.rc->runasusers != NULL) { + HLTQ_FOREACH_SAFE(m, entry->u.rc->runasusers, entries, next) + free_member(m); + } + if (entry->u.rc->runasgroups != NULL) { + HLTQ_FOREACH_SAFE(m, entry->u.rc->runasgroups, entries, next) + free_member(m); + } + free(entry->u.rc); + free(entry); + break; + } + case LEAK_PTR: + free(entry->u.ptr); + free(entry); + break; + default: + sudo_warnx("unexpected garbage type %d", entry->type); + } + } + + debug_return; +#endif /* NO_LEAKS */ +} + +void +parser_leak_init(void) +{ +#ifdef NO_LEAKS + static bool initialized; + debug_decl(parser_leak_init, SUDOERS_DEBUG_PARSER); + + if (!initialized) { + atexit(parser_leak_free); + initialized = true; + debug_return; + } + + /* Already initialized, free existing leaks. */ + parser_leak_free(); + debug_return; +#endif /* NO_LEAKS */ +} diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h index 711bf87..b38d3a0 100644 --- a/plugins/sudoers/parse.h +++ b/plugins/sudoers/parse.h @@ -294,6 +294,37 @@ struct cmnd_info { int status; }; +/* + * The parser passes pointers to data structures that are not stored anywhere. + * We add them to the leak list at allocation time and remove them from + * the list when they are stored in another data structure. + * This makes it possible to free data on error that would otherwise be leaked. + */ +enum parser_leak_types { + LEAK_UNKNOWN, + LEAK_PRIVILEGE, + LEAK_CMNDSPEC, + LEAK_DEFAULTS, + LEAK_MEMBER, + LEAK_DIGEST, + LEAK_RUNAS, + LEAK_PTR +}; +struct parser_leak_entry { + SLIST_ENTRY(parser_leak_entry) entries; + enum parser_leak_types type; + union { + struct command_digest *dig; + struct privilege *p; + struct cmndspec *cs; + struct defaults *d; + struct member *m; + struct runascontainer *rc; + void *ptr; + } u; +}; +SLIST_HEAD(parser_leak_list, parser_leak_entry); + /* alias.c */ struct rbtree *alloc_aliases(void); void free_aliases(struct rbtree *aliases); @@ -313,6 +344,7 @@ bool init_parser(const char *path, bool quiet, bool strict); struct member *new_member_all(char *name); void free_member(struct member *m); void free_members(struct member_list *members); +void free_cmndspecs(struct cmndspec_list *csl); void free_privilege(struct privilege *priv); void free_userspec(struct userspec *us); void free_userspecs(struct userspec_list *usl); @@ -321,6 +353,9 @@ void free_defaults(struct defaults_list *defs); void init_parse_tree(struct sudoers_parse_tree *parse_tree, const char *lhost, const char *shost); void free_parse_tree(struct sudoers_parse_tree *parse_tree); void reparent_parse_tree(struct sudoers_parse_tree *new_tree); +bool parser_leak_add(enum parser_leak_types type, void *v); +bool parser_leak_remove(enum parser_leak_types type, void *v); +void parser_leak_init(void); /* match_addr.c */ bool addr_matches(char *n); diff --git a/plugins/sudoers/toke.c b/plugins/sudoers/toke.c index 366f805..127473c 100644 --- a/plugins/sudoers/toke.c +++ b/plugins/sudoers/toke.c @@ -3105,13 +3105,14 @@ YY_RULE_SETUP LEXTRACE("DEFVAR "); if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); return DEFVAR; } YY_BREAK case 4: YY_RULE_SETUP -#line 134 "toke.l" +#line 135 "toke.l" { BEGIN STARTDEFS; LEXTRACE(", "); @@ -3120,7 +3121,7 @@ YY_RULE_SETUP YY_BREAK case 5: YY_RULE_SETUP -#line 140 "toke.l" +#line 141 "toke.l" { LEXTRACE("= "); return '='; @@ -3128,7 +3129,7 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -#line 145 "toke.l" +#line 146 "toke.l" { LEXTRACE("+= "); return '+'; @@ -3136,7 +3137,7 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP -#line 150 "toke.l" +#line 151 "toke.l" { LEXTRACE("-= "); return '-'; @@ -3144,7 +3145,7 @@ YY_RULE_SETUP YY_BREAK case 8: YY_RULE_SETUP -#line 155 "toke.l" +#line 156 "toke.l" { LEXTRACE("BEGINSTR "); sudoerslval.string = NULL; @@ -3154,11 +3155,12 @@ YY_RULE_SETUP YY_BREAK case 9: YY_RULE_SETUP -#line 162 "toke.l" +#line 163 "toke.l" { LEXTRACE("WORD(2) "); if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); return WORD; } YY_BREAK @@ -3167,7 +3169,7 @@ YY_RULE_SETUP case 10: /* rule 10 can match eol */ YY_RULE_SETUP -#line 171 "toke.l" +#line 173 "toke.l" { /* Line continuation char followed by newline. */ sudolineno++; @@ -3176,7 +3178,7 @@ YY_RULE_SETUP YY_BREAK case 11: YY_RULE_SETUP -#line 177 "toke.l" +#line 179 "toke.l" { LEXTRACE("ENDSTR "); BEGIN prev_state; @@ -3192,29 +3194,34 @@ YY_RULE_SETUP if (sudoerslval.string[1] == '\0' || (sudoerslval.string[1] == ':' && sudoerslval.string[2] == '\0')) { + free(sudoerslval.string); sudoerserror(N_("empty group")); LEXTRACE("ERROR "); return ERROR; } + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("USERGROUP "); return USERGROUP; case '+': if (sudoerslval.string[1] == '\0') { + free(sudoerslval.string); sudoerserror(N_("empty netgroup")); LEXTRACE("ERROR "); return ERROR; } + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NETGROUP "); return NETGROUP; } } + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("WORD(4) "); return WORD; } YY_BREAK case 12: YY_RULE_SETUP -#line 212 "toke.l" +#line 219 "toke.l" { LEXTRACE("BACKSLASH "); if (!append(sudoerstext, sudoersleng)) @@ -3223,7 +3230,7 @@ YY_RULE_SETUP YY_BREAK case 13: YY_RULE_SETUP -#line 218 "toke.l" +#line 225 "toke.l" { LEXTRACE("STRBODY "); if (!append(sudoerstext, sudoersleng)) @@ -3234,7 +3241,7 @@ YY_RULE_SETUP case 14: YY_RULE_SETUP -#line 226 "toke.l" +#line 233 "toke.l" { /* quoted fnmatch glob char, pass verbatim */ LEXTRACE("QUOTEDCHAR "); @@ -3245,7 +3252,7 @@ YY_RULE_SETUP YY_BREAK case 15: YY_RULE_SETUP -#line 234 "toke.l" +#line 241 "toke.l" { /* quoted sudoers special char, strip backslash */ LEXTRACE("QUOTEDCHAR "); @@ -3257,17 +3264,19 @@ YY_RULE_SETUP case 16: /* rule 16 can match eol */ YY_RULE_SETUP -#line 242 "toke.l" +#line 249 "toke.l" { BEGIN INITIAL; sudoersless(0); yy_set_bol(0); + parser_leak_add(LEAK_PTR, sudoerslval.command.cmnd); + parser_leak_add(LEAK_PTR, sudoerslval.command.args); return COMMAND; } /* end of command line args */ YY_BREAK case 17: YY_RULE_SETUP -#line 249 "toke.l" +#line 258 "toke.l" { LEXTRACE("ARG "); if (!fill_args(sudoerstext, sudoersleng, sawspace)) @@ -3278,7 +3287,7 @@ YY_RULE_SETUP case 18: YY_RULE_SETUP -#line 257 "toke.l" +#line 266 "toke.l" { /* Only return DIGEST if the length is correct. */ yy_size_t digest_len = @@ -3286,6 +3295,7 @@ YY_RULE_SETUP if ((yy_size_t)sudoersleng == digest_len * 2) { if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); BEGIN INITIAL; LEXTRACE("DIGEST "); return DIGEST; @@ -3296,7 +3306,7 @@ YY_RULE_SETUP YY_BREAK case 19: YY_RULE_SETUP -#line 272 "toke.l" +#line 282 "toke.l" { /* Only return DIGEST if the length is correct. */ yy_size_t len, digest_len = @@ -3311,6 +3321,7 @@ YY_RULE_SETUP if ((yy_size_t)sudoersleng == len) { if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); BEGIN INITIAL; LEXTRACE("DIGEST "); return DIGEST; @@ -3321,7 +3332,7 @@ YY_RULE_SETUP YY_BREAK case 20: YY_RULE_SETUP -#line 294 "toke.l" +#line 305 "toke.l" { if (continued) { sudoerserror(N_("invalid line continuation")); @@ -3336,7 +3347,7 @@ YY_RULE_SETUP YY_BREAK case 21: YY_RULE_SETUP -#line 306 "toke.l" +#line 317 "toke.l" { if (continued) { sudoerserror(N_("invalid line continuation")); @@ -3352,7 +3363,7 @@ YY_RULE_SETUP case 22: /* rule 22 can match eol */ YY_RULE_SETUP -#line 318 "toke.l" +#line 329 "toke.l" { if (continued) { sudoerserror(N_("invalid line continuation")); @@ -3372,7 +3383,7 @@ YY_RULE_SETUP case 23: /* rule 23 can match eol */ YY_RULE_SETUP -#line 334 "toke.l" +#line 345 "toke.l" { if (continued) { sudoerserror(N_("invalid line continuation")); @@ -3391,7 +3402,7 @@ YY_RULE_SETUP YY_BREAK case 24: YY_RULE_SETUP -#line 350 "toke.l" +#line 361 "toke.l" { char deftype; int n; @@ -3435,7 +3446,7 @@ YY_RULE_SETUP YY_BREAK case 25: YY_RULE_SETUP -#line 391 "toke.l" +#line 402 "toke.l" { int n; @@ -3465,7 +3476,7 @@ YY_RULE_SETUP YY_BREAK case 26: YY_RULE_SETUP -#line 418 "toke.l" +#line 429 "toke.l" { /* cmnd does not require passwd for this user */ LEXTRACE("NOPASSWD "); @@ -3474,7 +3485,7 @@ YY_RULE_SETUP YY_BREAK case 27: YY_RULE_SETUP -#line 424 "toke.l" +#line 435 "toke.l" { /* cmnd requires passwd for this user */ LEXTRACE("PASSWD "); @@ -3483,7 +3494,7 @@ YY_RULE_SETUP YY_BREAK case 28: YY_RULE_SETUP -#line 430 "toke.l" +#line 441 "toke.l" { LEXTRACE("NOEXEC "); return NOEXEC; @@ -3491,7 +3502,7 @@ YY_RULE_SETUP YY_BREAK case 29: YY_RULE_SETUP -#line 435 "toke.l" +#line 446 "toke.l" { LEXTRACE("EXEC "); return EXEC; @@ -3499,7 +3510,7 @@ YY_RULE_SETUP YY_BREAK case 30: YY_RULE_SETUP -#line 440 "toke.l" +#line 451 "toke.l" { LEXTRACE("SETENV "); return SETENV; @@ -3507,7 +3518,7 @@ YY_RULE_SETUP YY_BREAK case 31: YY_RULE_SETUP -#line 445 "toke.l" +#line 456 "toke.l" { LEXTRACE("NOSETENV "); return NOSETENV; @@ -3515,7 +3526,7 @@ YY_RULE_SETUP YY_BREAK case 32: YY_RULE_SETUP -#line 450 "toke.l" +#line 461 "toke.l" { LEXTRACE("LOG_OUTPUT "); return LOG_OUTPUT; @@ -3523,7 +3534,7 @@ YY_RULE_SETUP YY_BREAK case 33: YY_RULE_SETUP -#line 455 "toke.l" +#line 466 "toke.l" { LEXTRACE("NOLOG_OUTPUT "); return NOLOG_OUTPUT; @@ -3531,7 +3542,7 @@ YY_RULE_SETUP YY_BREAK case 34: YY_RULE_SETUP -#line 460 "toke.l" +#line 471 "toke.l" { LEXTRACE("LOG_INPUT "); return LOG_INPUT; @@ -3539,7 +3550,7 @@ YY_RULE_SETUP YY_BREAK case 35: YY_RULE_SETUP -#line 465 "toke.l" +#line 476 "toke.l" { LEXTRACE("NOLOG_INPUT "); return NOLOG_INPUT; @@ -3547,7 +3558,7 @@ YY_RULE_SETUP YY_BREAK case 36: YY_RULE_SETUP -#line 470 "toke.l" +#line 481 "toke.l" { LEXTRACE("MAIL "); return MAIL; @@ -3555,7 +3566,7 @@ YY_RULE_SETUP YY_BREAK case 37: YY_RULE_SETUP -#line 475 "toke.l" +#line 486 "toke.l" { LEXTRACE("NOMAIL "); return NOMAIL; @@ -3563,7 +3574,7 @@ YY_RULE_SETUP YY_BREAK case 38: YY_RULE_SETUP -#line 480 "toke.l" +#line 491 "toke.l" { LEXTRACE("FOLLOW "); return FOLLOWLNK; @@ -3571,7 +3582,7 @@ YY_RULE_SETUP YY_BREAK case 39: YY_RULE_SETUP -#line 485 "toke.l" +#line 496 "toke.l" { LEXTRACE("NOFOLLOW "); return NOFOLLOWLNK; @@ -3579,7 +3590,7 @@ YY_RULE_SETUP YY_BREAK case 40: YY_RULE_SETUP -#line 490 "toke.l" +#line 501 "toke.l" { if (sudoerstext[0] == '+') sudoerserror(N_("empty netgroup")); @@ -3591,49 +3602,53 @@ YY_RULE_SETUP YY_BREAK case 41: YY_RULE_SETUP -#line 499 "toke.l" +#line 510 "toke.l" { /* netgroup */ if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NETGROUP "); return NETGROUP; } YY_BREAK case 42: YY_RULE_SETUP -#line 507 "toke.l" +#line 519 "toke.l" { /* group */ if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("USERGROUP "); return USERGROUP; } YY_BREAK case 43: YY_RULE_SETUP -#line 515 "toke.l" +#line 528 "toke.l" { if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NTWKADDR "); return NTWKADDR; } YY_BREAK case 44: YY_RULE_SETUP -#line 522 "toke.l" +#line 536 "toke.l" { if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NTWKADDR "); return NTWKADDR; } YY_BREAK case 45: YY_RULE_SETUP -#line 529 "toke.l" +#line 544 "toke.l" { if (!ipv6_valid(sudoerstext)) { sudoerserror(N_("invalid IPv6 address")); @@ -3642,13 +3657,14 @@ YY_RULE_SETUP } if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NTWKADDR "); return NTWKADDR; } YY_BREAK case 46: YY_RULE_SETUP -#line 541 "toke.l" +#line 557 "toke.l" { if (!ipv6_valid(sudoerstext)) { sudoerserror(N_("invalid IPv6 address")); @@ -3657,13 +3673,14 @@ YY_RULE_SETUP } if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NTWKADDR "); return NTWKADDR; } YY_BREAK case 47: YY_RULE_SETUP -#line 553 "toke.l" +#line 570 "toke.l" { LEXTRACE("ALL "); return ALL; @@ -3672,7 +3689,7 @@ YY_RULE_SETUP YY_BREAK case 48: YY_RULE_SETUP -#line 559 "toke.l" +#line 576 "toke.l" { LEXTRACE("CMND_TIMEOUT "); return CMND_TIMEOUT; @@ -3680,7 +3697,7 @@ YY_RULE_SETUP YY_BREAK case 49: YY_RULE_SETUP -#line 564 "toke.l" +#line 581 "toke.l" { LEXTRACE("NOTBEFORE "); return NOTBEFORE; @@ -3688,7 +3705,7 @@ YY_RULE_SETUP YY_BREAK case 50: YY_RULE_SETUP -#line 569 "toke.l" +#line 586 "toke.l" { LEXTRACE("NOTAFTER "); return NOTAFTER; @@ -3696,7 +3713,7 @@ YY_RULE_SETUP YY_BREAK case 51: YY_RULE_SETUP -#line 574 "toke.l" +#line 591 "toke.l" { LEXTRACE("CWD "); prev_state = YY_START; @@ -3706,7 +3723,7 @@ YY_RULE_SETUP YY_BREAK case 52: YY_RULE_SETUP -#line 581 "toke.l" +#line 598 "toke.l" { LEXTRACE("CHROOT "); prev_state = YY_START; @@ -3716,7 +3733,7 @@ YY_RULE_SETUP YY_BREAK case 53: YY_RULE_SETUP -#line 588 "toke.l" +#line 605 "toke.l" { #ifdef HAVE_SELINUX LEXTRACE("ROLE "); @@ -3728,7 +3745,7 @@ YY_RULE_SETUP YY_BREAK case 54: YY_RULE_SETUP -#line 597 "toke.l" +#line 614 "toke.l" { #ifdef HAVE_SELINUX LEXTRACE("TYPE "); @@ -3740,7 +3757,7 @@ YY_RULE_SETUP YY_BREAK case 55: YY_RULE_SETUP -#line 605 "toke.l" +#line 622 "toke.l" { #ifdef HAVE_PRIV_SET LEXTRACE("PRIVS "); @@ -3752,7 +3769,7 @@ YY_RULE_SETUP YY_BREAK case 56: YY_RULE_SETUP -#line 614 "toke.l" +#line 631 "toke.l" { #ifdef HAVE_PRIV_SET LEXTRACE("LIMITPRIVS "); @@ -3764,30 +3781,33 @@ YY_RULE_SETUP YY_BREAK case 57: YY_RULE_SETUP -#line 623 "toke.l" +#line 640 "toke.l" { got_alias: if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("ALIAS "); return ALIAS; } YY_BREAK case 58: YY_RULE_SETUP -#line 631 "toke.l" +#line 649 "toke.l" { /* XXX - no way to specify digest for command */ /* no command args allowed for Defaults!/path */ if (!fill_cmnd(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.command.cmnd); + parser_leak_add(LEAK_PTR, sudoerslval.command.args); LEXTRACE("COMMAND "); return COMMAND; } YY_BREAK case 59: YY_RULE_SETUP -#line 640 "toke.l" +#line 660 "toke.l" { digest_type = SUDO_DIGEST_SHA224; BEGIN WANTDIGEST; @@ -3797,7 +3817,7 @@ YY_RULE_SETUP YY_BREAK case 60: YY_RULE_SETUP -#line 647 "toke.l" +#line 667 "toke.l" { digest_type = SUDO_DIGEST_SHA256; BEGIN WANTDIGEST; @@ -3807,7 +3827,7 @@ YY_RULE_SETUP YY_BREAK case 61: YY_RULE_SETUP -#line 654 "toke.l" +#line 674 "toke.l" { digest_type = SUDO_DIGEST_SHA384; BEGIN WANTDIGEST; @@ -3817,7 +3837,7 @@ YY_RULE_SETUP YY_BREAK case 62: YY_RULE_SETUP -#line 661 "toke.l" +#line 681 "toke.l" { digest_type = SUDO_DIGEST_SHA512; BEGIN WANTDIGEST; @@ -3827,7 +3847,7 @@ YY_RULE_SETUP YY_BREAK case 63: YY_RULE_SETUP -#line 668 "toke.l" +#line 688 "toke.l" { BEGIN GOTCMND; LEXTRACE("COMMAND "); @@ -3837,24 +3857,26 @@ YY_RULE_SETUP YY_BREAK case 64: YY_RULE_SETUP -#line 675 "toke.l" +#line 695 "toke.l" { BEGIN prev_state; if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("WORD(5) "); return WORD; } YY_BREAK case 65: YY_RULE_SETUP -#line 683 "toke.l" +#line 704 "toke.l" { /* directories can't have args... */ if (sudoerstext[sudoersleng - 1] == '/') { LEXTRACE("COMMAND "); if (!fill_cmnd(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.command.cmnd); return COMMAND; } BEGIN GOTCMND; @@ -3865,7 +3887,7 @@ YY_RULE_SETUP YY_BREAK case 66: YY_RULE_SETUP -#line 697 "toke.l" +#line 719 "toke.l" { LEXTRACE("BEGINSTR "); sudoerslval.string = NULL; @@ -3875,11 +3897,12 @@ YY_RULE_SETUP YY_BREAK case 67: YY_RULE_SETUP -#line 704 "toke.l" +#line 726 "toke.l" { /* a word */ if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("WORD(6) "); return WORD; } @@ -3887,11 +3910,12 @@ YY_RULE_SETUP case 68: YY_RULE_SETUP -#line 713 "toke.l" +#line 736 "toke.l" { /* include file/directory */ if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); BEGIN INITIAL; LEXTRACE("WORD(7) "); return WORD; @@ -3899,7 +3923,7 @@ YY_RULE_SETUP YY_BREAK case 69: YY_RULE_SETUP -#line 722 "toke.l" +#line 746 "toke.l" { LEXTRACE("BEGINSTR "); sudoerslval.string = NULL; @@ -3910,7 +3934,7 @@ YY_RULE_SETUP case 70: YY_RULE_SETUP -#line 730 "toke.l" +#line 754 "toke.l" { LEXTRACE("( "); return '('; @@ -3918,7 +3942,7 @@ YY_RULE_SETUP YY_BREAK case 71: YY_RULE_SETUP -#line 735 "toke.l" +#line 759 "toke.l" { LEXTRACE(") "); return ')'; @@ -3926,7 +3950,7 @@ YY_RULE_SETUP YY_BREAK case 72: YY_RULE_SETUP -#line 740 "toke.l" +#line 764 "toke.l" { LEXTRACE(", "); return ','; @@ -3934,7 +3958,7 @@ YY_RULE_SETUP YY_BREAK case 73: YY_RULE_SETUP -#line 745 "toke.l" +#line 769 "toke.l" { LEXTRACE("= "); return '='; @@ -3942,7 +3966,7 @@ YY_RULE_SETUP YY_BREAK case 74: YY_RULE_SETUP -#line 750 "toke.l" +#line 774 "toke.l" { LEXTRACE(": "); return ':'; @@ -3950,7 +3974,7 @@ YY_RULE_SETUP YY_BREAK case 75: YY_RULE_SETUP -#line 755 "toke.l" +#line 779 "toke.l" { if (sudoersleng & 1) { LEXTRACE("!"); @@ -3961,7 +3985,7 @@ YY_RULE_SETUP case 76: /* rule 76 can match eol */ YY_RULE_SETUP -#line 762 "toke.l" +#line 786 "toke.l" { if (YY_START == INSTR) { /* re-scan after changing state */ @@ -3980,7 +4004,7 @@ YY_RULE_SETUP YY_BREAK case 77: YY_RULE_SETUP -#line 778 "toke.l" +#line 802 "toke.l" { /* throw away space/tabs */ sawspace = true; /* but remember for fill_args */ } @@ -3988,7 +4012,7 @@ YY_RULE_SETUP case 78: /* rule 78 can match eol */ YY_RULE_SETUP -#line 782 "toke.l" +#line 806 "toke.l" { sawspace = true; /* remember for fill_args */ sudolineno++; @@ -3998,7 +4022,7 @@ YY_RULE_SETUP case 79: /* rule 79 can match eol */ YY_RULE_SETUP -#line 788 "toke.l" +#line 812 "toke.l" { if (sudoerstext[sudoersleng - 1] == '\n') { /* comment ending in a newline */ @@ -4016,7 +4040,7 @@ YY_RULE_SETUP YY_BREAK case 80: YY_RULE_SETUP -#line 803 "toke.l" +#line 827 "toke.l" { LEXTRACE("NOMATCH "); return NOMATCH; @@ -4031,7 +4055,7 @@ case YY_STATE_EOF(INSTR): case YY_STATE_EOF(WANTDIGEST): case YY_STATE_EOF(GOTINC): case YY_STATE_EOF(EXPECTPATH): -#line 808 "toke.l" +#line 832 "toke.l" { if (!pop_include()) yyterminate(); @@ -4039,10 +4063,10 @@ case YY_STATE_EOF(EXPECTPATH): YY_BREAK case 81: YY_RULE_SETUP -#line 813 "toke.l" +#line 837 "toke.l" ECHO; YY_BREAK -#line 4040 "toke.c" +#line 4064 "toke.c" case YY_END_OF_BUFFER: { @@ -5003,7 +5027,7 @@ void sudoersfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 813 "toke.l" +#line 837 "toke.l" struct path_list { diff --git a/plugins/sudoers/toke.l b/plugins/sudoers/toke.l index cf5a7d4..3714c06 100644 --- a/plugins/sudoers/toke.l +++ b/plugins/sudoers/toke.l @@ -127,6 +127,7 @@ DEFVAR [a-z_]+ LEXTRACE("DEFVAR "); if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); return DEFVAR; } @@ -163,6 +164,7 @@ DEFVAR [a-z_]+ LEXTRACE("WORD(2) "); if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); return WORD; } } @@ -189,22 +191,27 @@ DEFVAR [a-z_]+ if (sudoerslval.string[1] == '\0' || (sudoerslval.string[1] == ':' && sudoerslval.string[2] == '\0')) { + free(sudoerslval.string); sudoerserror(N_("empty group")); LEXTRACE("ERROR "); return ERROR; } + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("USERGROUP "); return USERGROUP; case '+': if (sudoerslval.string[1] == '\0') { + free(sudoerslval.string); sudoerserror(N_("empty netgroup")); LEXTRACE("ERROR "); return ERROR; } + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NETGROUP "); return NETGROUP; } } + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("WORD(4) "); return WORD; } @@ -243,6 +250,8 @@ DEFVAR [a-z_]+ BEGIN INITIAL; sudoersless(0); yy_set_bol(0); + parser_leak_add(LEAK_PTR, sudoerslval.command.cmnd); + parser_leak_add(LEAK_PTR, sudoerslval.command.args); return COMMAND; } /* end of command line args */ @@ -261,6 +270,7 @@ DEFVAR [a-z_]+ if ((yy_size_t)sudoersleng == digest_len * 2) { if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); BEGIN INITIAL; LEXTRACE("DIGEST "); return DIGEST; @@ -283,6 +293,7 @@ DEFVAR [a-z_]+ if ((yy_size_t)sudoersleng == len) { if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); BEGIN INITIAL; LEXTRACE("DIGEST "); return DIGEST; @@ -500,6 +511,7 @@ NOFOLLOW[[:blank:]]*: { /* netgroup */ if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NETGROUP "); return NETGROUP; } @@ -508,6 +520,7 @@ NOFOLLOW[[:blank:]]*: { /* group */ if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("USERGROUP "); return USERGROUP; } @@ -515,6 +528,7 @@ NOFOLLOW[[:blank:]]*: { {IPV4ADDR}(\/{IPV4ADDR})? { if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NTWKADDR "); return NTWKADDR; } @@ -522,6 +536,7 @@ NOFOLLOW[[:blank:]]*: { {IPV4ADDR}\/([12]?[0-9]|3[0-2]) { if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NTWKADDR "); return NTWKADDR; } @@ -534,6 +549,7 @@ NOFOLLOW[[:blank:]]*: { } if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NTWKADDR "); return NTWKADDR; } @@ -546,6 +562,7 @@ NOFOLLOW[[:blank:]]*: { } if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("NTWKADDR "); return NTWKADDR; } @@ -624,6 +641,7 @@ ALL { got_alias: if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("ALIAS "); return ALIAS; } @@ -633,6 +651,8 @@ ALL { /* no command args allowed for Defaults!/path */ if (!fill_cmnd(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.command.cmnd); + parser_leak_add(LEAK_PTR, sudoerslval.command.args); LEXTRACE("COMMAND "); return COMMAND; } @@ -676,6 +696,7 @@ sudoedit { BEGIN prev_state; if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("WORD(5) "); return WORD; } @@ -686,6 +707,7 @@ sudoedit { LEXTRACE("COMMAND "); if (!fill_cmnd(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.command.cmnd); return COMMAND; } BEGIN GOTCMND; @@ -705,6 +727,7 @@ sudoedit { /* a word */ if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); LEXTRACE("WORD(6) "); return WORD; } @@ -714,6 +737,7 @@ sudoedit { /* include file/directory */ if (!fill(sudoerstext, sudoersleng)) yyterminate(); + parser_leak_add(LEAK_PTR, sudoerslval.string); BEGIN INITIAL; LEXTRACE("WORD(7) "); return WORD; diff --git a/plugins/sudoers/toke_util.c b/plugins/sudoers/toke_util.c index 5307666..61e8ce0 100644 --- a/plugins/sudoers/toke_util.c +++ b/plugins/sudoers/toke_util.c @@ -156,8 +156,8 @@ fill_args(const char *s, size_t len, int addspace) if (p == NULL) { sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); goto bad; - } else - sudoerslval.command.args = p; + } + sudoerslval.command.args = p; } /* Efficiently append the arg (with a leading space if needed). */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor