From f30670a42f3a7b80a7ce8e876a58d008e5a30542 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 1 Feb 2021 19:56:52 -0700 Subject: [PATCH] Plug a few more parser leaks. --- MANIFEST | 5 + plugins/sudoers/gram.c | 232 +++++++++--------- plugins/sudoers/gram.y | 12 +- plugins/sudoers/regress/sudoers/test25.in | 3 + .../sudoers/regress/sudoers/test25.json.ok | 0 .../sudoers/regress/sudoers/test25.ldif.ok | 0 plugins/sudoers/regress/sudoers/test25.out.ok | 1 + .../sudoers/regress/sudoers/test25.toke.ok | 3 + plugins/sudoers/toke.c | 19 +- plugins/sudoers/toke.l | 3 + plugins/sudoers/toke_util.c | 5 + 11 files changed, 153 insertions(+), 130 deletions(-) create mode 100644 plugins/sudoers/regress/sudoers/test25.in create mode 100644 plugins/sudoers/regress/sudoers/test25.json.ok create mode 100644 plugins/sudoers/regress/sudoers/test25.ldif.ok create mode 100644 plugins/sudoers/regress/sudoers/test25.out.ok create mode 100644 plugins/sudoers/regress/sudoers/test25.toke.ok diff --git a/MANIFEST b/MANIFEST index 1386ced13..d5bce7ca2 100644 --- a/MANIFEST +++ b/MANIFEST @@ -790,6 +790,11 @@ plugins/sudoers/regress/sudoers/test24.ldif2sudo.ok plugins/sudoers/regress/sudoers/test24.out.ok plugins/sudoers/regress/sudoers/test24.sudo.ok plugins/sudoers/regress/sudoers/test24.toke.ok +plugins/sudoers/regress/sudoers/test25.in +plugins/sudoers/regress/sudoers/test25.json.ok +plugins/sudoers/regress/sudoers/test25.ldif.ok +plugins/sudoers/regress/sudoers/test25.out.ok +plugins/sudoers/regress/sudoers/test25.toke.ok plugins/sudoers/regress/sudoers/test3.in plugins/sudoers/regress/sudoers/test3.json.ok plugins/sudoers/regress/sudoers/test3.ldif.ok diff --git a/plugins/sudoers/gram.c b/plugins/sudoers/gram.c index d2818bc26..9539c5bd5 100644 --- a/plugins/sudoers/gram.c +++ b/plugins/sudoers/gram.c @@ -860,12 +860,12 @@ static const yytype_int16 yyrline[] = 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, + 412, 421, 432, 433, 493, 559, 568, 577, 586, 597, + 598, 605, 608, 630, 634, 640, 652, 664, 669, 673, + 678, 683, 688, 692, 697, 700, 705, 721, 732, 744, + 755, 773, 774, 775, 776, 777, 778, 779, 780, 781, + 782, 785, 791, 794, 798, 802, 811, 820, 832, 838, + 844, 850, 858, 861, 864, 867, 870, 873, 876, 879, 882, 885, 888, 891, 894, 897, 900, 905, 913, 922, 941, 942, 945, 945, 957, 960, 961, 968, 969, 972, 972, 984, 987, 988, 995, 996, 999, 999, 1011, 1014, @@ -2123,17 +2123,23 @@ yyreduce: } #ifdef HAVE_SELINUX cs->role = (yyvsp[-2].options).role; + parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).role); cs->type = (yyvsp[-2].options).type; + parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).type); #endif #ifdef HAVE_PRIV_SET cs->privs = (yyvsp[-2].options).privs; + parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).privs); cs->limitprivs = (yyvsp[-2].options).limitprivs; + parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).limitprivs); #endif cs->notbefore = (yyvsp[-2].options).notbefore; cs->notafter = (yyvsp[-2].options).notafter; cs->timeout = (yyvsp[-2].options).timeout; cs->runcwd = (yyvsp[-2].options).runcwd; + parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).runcwd); cs->runchroot = (yyvsp[-2].options).runchroot; + parser_leak_remove(LEAK_PTR, (yyvsp[-2].options).runchroot); cs->tags = (yyvsp[-1].tag); cs->cmnd = (yyvsp[0].member); parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member)); @@ -2144,11 +2150,11 @@ yyreduce: cs->tags.setenv = IMPLIED; (yyval.cmndspec) = cs; } -#line 2142 "gram.c" +#line 2148 "gram.c" break; case 45: /* digestspec: SHA224_TOK ':' DIGEST */ -#line 553 "gram.y" +#line 559 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA224, (yyvsp[0].string)); if ((yyval.digest) == NULL) { @@ -2158,11 +2164,11 @@ yyreduce: parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); parser_leak_add(LEAK_DIGEST, (yyval.digest)); } -#line 2156 "gram.c" +#line 2162 "gram.c" break; case 46: /* digestspec: SHA256_TOK ':' DIGEST */ -#line 562 "gram.y" +#line 568 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA256, (yyvsp[0].string)); if ((yyval.digest) == NULL) { @@ -2172,11 +2178,11 @@ yyreduce: parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); parser_leak_add(LEAK_DIGEST, (yyval.digest)); } -#line 2170 "gram.c" +#line 2176 "gram.c" break; case 47: /* digestspec: SHA384_TOK ':' DIGEST */ -#line 571 "gram.y" +#line 577 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA384, (yyvsp[0].string)); if ((yyval.digest) == NULL) { @@ -2186,11 +2192,11 @@ yyreduce: parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); parser_leak_add(LEAK_DIGEST, (yyval.digest)); } -#line 2184 "gram.c" +#line 2190 "gram.c" break; case 48: /* digestspec: SHA512_TOK ':' DIGEST */ -#line 580 "gram.y" +#line 586 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA512, (yyvsp[0].string)); if ((yyval.digest) == NULL) { @@ -2200,29 +2206,29 @@ yyreduce: parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); parser_leak_add(LEAK_DIGEST, (yyval.digest)); } -#line 2198 "gram.c" +#line 2204 "gram.c" break; case 50: /* digestlist: digestlist ',' digestspec */ -#line 592 "gram.y" +#line 598 "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 2208 "gram.c" +#line 2214 "gram.c" break; case 51: /* digcmnd: opcmnd */ -#line 599 "gram.y" +#line 605 "gram.y" { (yyval.member) = (yyvsp[0].member); } -#line 2216 "gram.c" +#line 2222 "gram.c" break; case 52: /* digcmnd: digestlist opcmnd */ -#line 602 "gram.y" +#line 608 "gram.y" { struct sudo_command *c = (struct sudo_command *) (yyvsp[0].member)->name; @@ -2243,29 +2249,29 @@ yyreduce: HLTQ_TO_TAILQ(&c->digests, (yyvsp[-1].digest), entries); (yyval.member) = (yyvsp[0].member); } -#line 2241 "gram.c" +#line 2247 "gram.c" break; case 53: /* opcmnd: cmnd */ -#line 624 "gram.y" +#line 630 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = false; } -#line 2250 "gram.c" +#line 2256 "gram.c" break; case 54: /* opcmnd: '!' cmnd */ -#line 628 "gram.y" +#line 634 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = true; } -#line 2259 "gram.c" +#line 2265 "gram.c" break; case 55: /* chdirspec: CWD '=' WORD */ -#line 634 "gram.y" +#line 640 "gram.y" { if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') { if (strcmp((yyvsp[0].string), "*") != 0) { @@ -2276,11 +2282,11 @@ yyreduce: } (yyval.string) = (yyvsp[0].string); } -#line 2274 "gram.c" +#line 2280 "gram.c" break; case 56: /* chrootspec: CHROOT '=' WORD */ -#line 646 "gram.y" +#line 652 "gram.y" { if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') { if (strcmp((yyvsp[0].string), "*") != 0) { @@ -2291,83 +2297,83 @@ yyreduce: } (yyval.string) = (yyvsp[0].string); } -#line 2289 "gram.c" +#line 2295 "gram.c" break; case 57: /* timeoutspec: CMND_TIMEOUT '=' WORD */ -#line 658 "gram.y" +#line 664 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2297 "gram.c" +#line 2303 "gram.c" break; case 58: /* notbeforespec: NOTBEFORE '=' WORD */ -#line 663 "gram.y" +#line 669 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2305 "gram.c" +#line 2311 "gram.c" break; case 59: /* notafterspec: NOTAFTER '=' WORD */ -#line 667 "gram.y" +#line 673 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2313 "gram.c" +#line 2319 "gram.c" break; case 60: /* rolespec: ROLE '=' WORD */ -#line 672 "gram.y" +#line 678 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2321 "gram.c" +#line 2327 "gram.c" break; case 61: /* typespec: TYPE '=' WORD */ -#line 677 "gram.y" +#line 683 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2329 "gram.c" +#line 2335 "gram.c" break; case 62: /* privsspec: PRIVS '=' WORD */ -#line 682 "gram.y" +#line 688 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2337 "gram.c" +#line 2343 "gram.c" break; case 63: /* limitprivsspec: LIMITPRIVS '=' WORD */ -#line 686 "gram.y" +#line 692 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2345 "gram.c" +#line 2351 "gram.c" break; case 64: /* runasspec: %empty */ -#line 691 "gram.y" +#line 697 "gram.y" { (yyval.runas) = NULL; } -#line 2353 "gram.c" +#line 2359 "gram.c" break; case 65: /* runasspec: '(' runaslist ')' */ -#line 694 "gram.y" +#line 700 "gram.y" { (yyval.runas) = (yyvsp[-1].runas); } -#line 2361 "gram.c" +#line 2367 "gram.c" break; case 66: /* runaslist: %empty */ -#line 699 "gram.y" +#line 705 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) != NULL) { @@ -2384,11 +2390,11 @@ yyreduce: } parser_leak_add(LEAK_RUNAS, (yyval.runas)); } -#line 2382 "gram.c" +#line 2388 "gram.c" break; case 67: /* runaslist: userlist */ -#line 715 "gram.y" +#line 721 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) == NULL) { @@ -2400,11 +2406,11 @@ yyreduce: (yyval.runas)->runasusers = (yyvsp[0].member); /* $$->runasgroups = NULL; */ } -#line 2398 "gram.c" +#line 2404 "gram.c" break; case 68: /* runaslist: userlist ':' grouplist */ -#line 726 "gram.y" +#line 732 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) == NULL) { @@ -2417,11 +2423,11 @@ yyreduce: (yyval.runas)->runasusers = (yyvsp[-2].member); (yyval.runas)->runasgroups = (yyvsp[0].member); } -#line 2415 "gram.c" +#line 2421 "gram.c" break; case 69: /* runaslist: ':' grouplist */ -#line 738 "gram.y" +#line 744 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) == NULL) { @@ -2433,11 +2439,11 @@ yyreduce: /* $$->runasusers = NULL; */ (yyval.runas)->runasgroups = (yyvsp[0].member); } -#line 2431 "gram.c" +#line 2437 "gram.c" break; case 70: /* runaslist: ':' */ -#line 749 "gram.y" +#line 755 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) != NULL) { @@ -2454,108 +2460,106 @@ yyreduce: } parser_leak_add(LEAK_RUNAS, (yyval.runas)); } -#line 2452 "gram.c" - break; - - case 71: /* reserved_word: ALL */ -#line 767 "gram.y" - { (yyval.string) = "ALL"; } #line 2458 "gram.c" break; - case 72: /* reserved_word: CHROOT */ -#line 768 "gram.y" - { (yyval.string) = "CHROOT"; } + case 71: /* reserved_word: ALL */ +#line 773 "gram.y" + { (yyval.string) = "ALL"; } #line 2464 "gram.c" break; - case 73: /* reserved_word: CWD */ -#line 769 "gram.y" - { (yyval.string) = "CWD"; } + case 72: /* reserved_word: CHROOT */ +#line 774 "gram.y" + { (yyval.string) = "CHROOT"; } #line 2470 "gram.c" break; - case 74: /* reserved_word: CMND_TIMEOUT */ -#line 770 "gram.y" - { (yyval.string) = "CMND_TIMEOUT"; } + case 73: /* reserved_word: CWD */ +#line 775 "gram.y" + { (yyval.string) = "CWD"; } #line 2476 "gram.c" break; - case 75: /* reserved_word: NOTBEFORE */ -#line 771 "gram.y" - { (yyval.string) = "NOTBEFORE"; } + case 74: /* reserved_word: CMND_TIMEOUT */ +#line 776 "gram.y" + { (yyval.string) = "CMND_TIMEOUT"; } #line 2482 "gram.c" break; - case 76: /* reserved_word: NOTAFTER */ -#line 772 "gram.y" - { (yyval.string) = "NOTAFTER"; } + case 75: /* reserved_word: NOTBEFORE */ +#line 777 "gram.y" + { (yyval.string) = "NOTBEFORE"; } #line 2488 "gram.c" break; - case 77: /* reserved_word: ROLE */ -#line 773 "gram.y" - { (yyval.string) = "ROLE"; } + case 76: /* reserved_word: NOTAFTER */ +#line 778 "gram.y" + { (yyval.string) = "NOTAFTER"; } #line 2494 "gram.c" break; - case 78: /* reserved_word: TYPE */ -#line 774 "gram.y" - { (yyval.string) = "TYPE"; } + case 77: /* reserved_word: ROLE */ +#line 779 "gram.y" + { (yyval.string) = "ROLE"; } #line 2500 "gram.c" break; - case 79: /* reserved_word: PRIVS */ -#line 775 "gram.y" - { (yyval.string) = "PRIVS"; } + case 78: /* reserved_word: TYPE */ +#line 780 "gram.y" + { (yyval.string) = "TYPE"; } #line 2506 "gram.c" break; - case 80: /* reserved_word: LIMITPRIVS */ -#line 776 "gram.y" - { (yyval.string) = "LIMITPRIVS"; } + case 79: /* reserved_word: PRIVS */ +#line 781 "gram.y" + { (yyval.string) = "PRIVS"; } #line 2512 "gram.c" break; + case 80: /* reserved_word: LIMITPRIVS */ +#line 782 "gram.y" + { (yyval.string) = "LIMITPRIVS"; } +#line 2518 "gram.c" + break; + case 81: /* reserved_alias: reserved_word */ -#line 779 "gram.y" +#line 785 "gram.y" { sudoerserrorf(U_("syntax error, reserved word %s used as an alias name"), (yyvsp[0].string)); YYERROR; } -#line 2521 "gram.c" +#line 2527 "gram.c" break; case 82: /* options: %empty */ -#line 785 "gram.y" +#line 791 "gram.y" { init_options(&(yyval.options)); } -#line 2529 "gram.c" +#line 2535 "gram.c" break; case 83: /* options: options chdirspec */ -#line 788 "gram.y" +#line 794 "gram.y" { free((yyval.options).runcwd); (yyval.options).runcwd = (yyvsp[0].string); - parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); } -#line 2539 "gram.c" +#line 2544 "gram.c" break; case 84: /* options: options chrootspec */ -#line 793 "gram.y" +#line 798 "gram.y" { free((yyval.options).runchroot); (yyval.options).runchroot = (yyvsp[0].string); - parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); } -#line 2549 "gram.c" +#line 2553 "gram.c" break; case 85: /* options: options notbeforespec */ -#line 798 "gram.y" +#line 802 "gram.y" { (yyval.options).notbefore = parse_gentime((yyvsp[0].string)); parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); @@ -2565,11 +2569,11 @@ yyreduce: YYERROR; } } -#line 2563 "gram.c" +#line 2567 "gram.c" break; case 86: /* options: options notafterspec */ -#line 807 "gram.y" +#line 811 "gram.y" { (yyval.options).notafter = parse_gentime((yyvsp[0].string)); parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); @@ -2579,11 +2583,11 @@ yyreduce: YYERROR; } } -#line 2577 "gram.c" +#line 2581 "gram.c" break; case 87: /* options: options timeoutspec */ -#line 816 "gram.y" +#line 820 "gram.y" { (yyval.options).timeout = parse_timeout((yyvsp[0].string)); parser_leak_remove(LEAK_PTR, (yyvsp[0].string)); @@ -2596,52 +2600,48 @@ yyreduce: YYERROR; } } -#line 2594 "gram.c" +#line 2598 "gram.c" break; case 88: /* options: options rolespec */ -#line 828 "gram.y" +#line 832 "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 2606 "gram.c" +#line 2609 "gram.c" break; case 89: /* options: options typespec */ -#line 835 "gram.y" +#line 838 "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 2618 "gram.c" +#line 2620 "gram.c" break; case 90: /* options: options privsspec */ -#line 842 "gram.y" +#line 844 "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 2630 "gram.c" +#line 2631 "gram.c" break; case 91: /* options: options limitprivsspec */ -#line 849 "gram.y" +#line 850 "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 2642 "gram.c" diff --git a/plugins/sudoers/gram.y b/plugins/sudoers/gram.y index b472af31d..ffa51f023 100644 --- a/plugins/sudoers/gram.y +++ b/plugins/sudoers/gram.y @@ -527,17 +527,23 @@ cmndspec : runasspec options cmndtag digcmnd { } #ifdef HAVE_SELINUX cs->role = $2.role; + parser_leak_remove(LEAK_PTR, $2.role); cs->type = $2.type; + parser_leak_remove(LEAK_PTR, $2.type); #endif #ifdef HAVE_PRIV_SET cs->privs = $2.privs; + parser_leak_remove(LEAK_PTR, $2.privs); cs->limitprivs = $2.limitprivs; + parser_leak_remove(LEAK_PTR, $2.limitprivs); #endif cs->notbefore = $2.notbefore; cs->notafter = $2.notafter; cs->timeout = $2.timeout; cs->runcwd = $2.runcwd; + parser_leak_remove(LEAK_PTR, $2.runcwd); cs->runchroot = $2.runchroot; + parser_leak_remove(LEAK_PTR, $2.runchroot); cs->tags = $3; cs->cmnd = $4; parser_leak_remove(LEAK_MEMBER, $4); @@ -788,12 +794,10 @@ 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); @@ -829,28 +833,24 @@ 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 } ; diff --git a/plugins/sudoers/regress/sudoers/test25.in b/plugins/sudoers/regress/sudoers/test25.in new file mode 100644 index 000000000..fe3558790 --- /dev/null +++ b/plugins/sudoers/regress/sudoers/test25.in @@ -0,0 +1,3 @@ +# Test continuation character when there is nothing to continue +# Used to leak "~ron" when run under address sanitizer +foo ALL = CWD=~ron /bin/ls \ diff --git a/plugins/sudoers/regress/sudoers/test25.json.ok b/plugins/sudoers/regress/sudoers/test25.json.ok new file mode 100644 index 000000000..e69de29bb diff --git a/plugins/sudoers/regress/sudoers/test25.ldif.ok b/plugins/sudoers/regress/sudoers/test25.ldif.ok new file mode 100644 index 000000000..e69de29bb diff --git a/plugins/sudoers/regress/sudoers/test25.out.ok b/plugins/sudoers/regress/sudoers/test25.out.ok new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/plugins/sudoers/regress/sudoers/test25.out.ok @@ -0,0 +1 @@ + diff --git a/plugins/sudoers/regress/sudoers/test25.toke.ok b/plugins/sudoers/regress/sudoers/test25.toke.ok new file mode 100644 index 000000000..e58461e0b --- /dev/null +++ b/plugins/sudoers/regress/sudoers/test25.toke.ok @@ -0,0 +1,3 @@ +# +# +WORD(6) ALL = CWD = WORD(5) COMMAND <*> \ No newline at end of file diff --git a/plugins/sudoers/toke.c b/plugins/sudoers/toke.c index 127473cce..97a115492 100644 --- a/plugins/sudoers/toke.c +++ b/plugins/sudoers/toke.c @@ -3988,6 +3988,9 @@ YY_RULE_SETUP #line 786 "toke.l" { if (YY_START == INSTR) { + /* throw away old string */ + free(sudoerslval.string); + sudoerslval.string = NULL; /* re-scan after changing state */ BEGIN INITIAL; sudoersless(0); @@ -4004,7 +4007,7 @@ YY_RULE_SETUP YY_BREAK case 77: YY_RULE_SETUP -#line 802 "toke.l" +#line 805 "toke.l" { /* throw away space/tabs */ sawspace = true; /* but remember for fill_args */ } @@ -4012,7 +4015,7 @@ YY_RULE_SETUP case 78: /* rule 78 can match eol */ YY_RULE_SETUP -#line 806 "toke.l" +#line 809 "toke.l" { sawspace = true; /* remember for fill_args */ sudolineno++; @@ -4022,7 +4025,7 @@ YY_RULE_SETUP case 79: /* rule 79 can match eol */ YY_RULE_SETUP -#line 812 "toke.l" +#line 815 "toke.l" { if (sudoerstext[sudoersleng - 1] == '\n') { /* comment ending in a newline */ @@ -4040,7 +4043,7 @@ YY_RULE_SETUP YY_BREAK case 80: YY_RULE_SETUP -#line 827 "toke.l" +#line 830 "toke.l" { LEXTRACE("NOMATCH "); return NOMATCH; @@ -4055,7 +4058,7 @@ case YY_STATE_EOF(INSTR): case YY_STATE_EOF(WANTDIGEST): case YY_STATE_EOF(GOTINC): case YY_STATE_EOF(EXPECTPATH): -#line 832 "toke.l" +#line 835 "toke.l" { if (!pop_include()) yyterminate(); @@ -4063,10 +4066,10 @@ case YY_STATE_EOF(EXPECTPATH): YY_BREAK case 81: YY_RULE_SETUP -#line 837 "toke.l" +#line 840 "toke.l" ECHO; YY_BREAK -#line 4064 "toke.c" +#line 4067 "toke.c" case YY_END_OF_BUFFER: { @@ -5027,7 +5030,7 @@ void sudoersfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 837 "toke.l" +#line 840 "toke.l" struct path_list { diff --git a/plugins/sudoers/toke.l b/plugins/sudoers/toke.l index 3714c06ef..fe391e738 100644 --- a/plugins/sudoers/toke.l +++ b/plugins/sudoers/toke.l @@ -785,6 +785,9 @@ sudoedit { <*>\r?\n { if (YY_START == INSTR) { + /* throw away old string */ + free(sudoerslval.string); + sudoerslval.string = NULL; /* re-scan after changing state */ BEGIN INITIAL; sudoersless(0); diff --git a/plugins/sudoers/toke_util.c b/plugins/sudoers/toke_util.c index 61e8ce0be..7106d01f3 100644 --- a/plugins/sudoers/toke_util.c +++ b/plugins/sudoers/toke_util.c @@ -48,6 +48,11 @@ fill_txt(const char *src, size_t len, size_t olen) dst = olen ? realloc(sudoerslval.string, olen + len + 1) : malloc(len + 1); if (dst == NULL) { + if (olen != 0) { + /* realloc failure, avoid leaking original */ + free(sudoerslval.string); + sudoerslval.string = NULL; + } sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); sudoerserror(NULL); debug_return_bool(false);