Bounds check strings to print correctly in %trace mode.

In %trace mode, evaluating a macro which is undefined causes an invalid
read of 1 byte when searching for the end of the string:

trillian:~$ valgrind rpmspec --eval '%trace' --eval '%{?myUndefinedMacro}'
==21534== Memcheck, a memory error detector
==21534== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==21534== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==21534== Command: rpmspec --trace --eval %{?myUndefinedMacro}
==21534==

  1>   %{?myUndefinedMacro}^==21534== Invalid read of size 1
==21534==    at 0x55018D4: printMacro (macro.c:296)
==21534==    by 0x5502DFC: expandMacro (macro.c:1077)
==21534==    by 0x5503710: doExpandMacros (macro.c:1280)
==21534==    by 0x5504AB6: rpmExpand (macro.c:1629)
==21534==    by 0x508F59A: rpmcliAllArgCallback (poptALL.c:120)
==21534==    by 0x6DAF71D: invokeCallbacksOPTION (popt.c:156)
==21534==    by 0x6DAF75B: invokeCallbacksOPTION (popt.c:139)
==21534==    by 0x6DB1428: poptGetNextOpt (popt.c:1515)
==21534==    by 0x508F912: rpmcliInit (poptALL.c:302)
==21534==    by 0x1095B2: main (rpmspec.c:63)
==21534==  Address 0x8a010f3 is 0 bytes after a block of size 19 alloc'd
==21534==    at 0x4C2DB9D: malloc (vg_replace_malloc.c:299)
==21534==    by 0x5507C17: rmalloc (rpmmalloc.c:44)
==21534==    by 0x5502788: expandMacro (macro.c:927)
==21534==    by 0x5503710: doExpandMacros (macro.c:1280)
==21534==    by 0x5504AB6: rpmExpand (macro.c:1629)
==21534==    by 0x508F59A: rpmcliAllArgCallback (poptALL.c:120)
==21534==    by 0x6DAF71D: invokeCallbacksOPTION (popt.c:156)
==21534==    by 0x6DAF75B: invokeCallbacksOPTION (popt.c:139)
==21534==    by 0x6DB1428: poptGetNextOpt (popt.c:1515)
==21534==    by 0x508F912: rpmcliInit (poptALL.c:302)
==21534==    by 0x1095B2: main (rpmspec.c:63)
==21534==

  1>   %{?_transaction_color}^
  1>   %{?_prefer_color}^
  1>   %{_netsharedpath}^
  1>   %{_install_langs}^
==21534==
==21534== HEAP SUMMARY:
==21534==     in use at exit: 7,183 bytes in 71 blocks
==21534==   total heap usage: 7,811 allocs, 7,740 frees, 3,500,361 bytes allocated
==21534==
==21534== LEAK SUMMARY:
==21534==    definitely lost: 19 bytes in 1 blocks
==21534==    indirectly lost: 0 bytes in 0 blocks
==21534==      possibly lost: 0 bytes in 0 blocks
==21534==    still reachable: 7,164 bytes in 70 blocks
==21534==         suppressed: 0 bytes in 0 blocks
==21534== Rerun with --leak-check=full to see details of leaked memory
==21534==
==21534== For counts of detected and suppressed errors, rerun with: -v
==21534== ERROR SUMMARY: 5 errors from 1 contexts (suppressed: 0 from 0)
trillian:~$

This can easily be avoided by checking the first byte as well as the
second for our sentinal value (NUL).

Signed-off-by: Peter Jones <pjones@redhat.com>
This commit is contained in:
Peter Jones 2017-02-20 11:08:23 -05:00 committed by Florian Festi
parent 34b61a1f82
commit bf248badd3
1 changed files with 1 additions and 1 deletions

View File

@ -305,7 +305,7 @@ printMacro(MacroBuf mb, const char * s, const char * se)
/* Substitute caret at end-of-macro position */ /* Substitute caret at end-of-macro position */
fprintf(stderr, "%3d>%*s%%%.*s^", mb->depth, fprintf(stderr, "%3d>%*s%%%.*s^", mb->depth,
(2 * mb->depth + 1), "", (int)(se - s), s); (2 * mb->depth + 1), "", (int)(se - s), s);
if (se[1] != '\0' && (senl - (se+1)) > 0) if (se[0] != '\0' && se[1] != '\0' && (senl - (se+1)) > 0)
fprintf(stderr, "%-.*s%s", (int)(senl - (se+1)), se+1, ellipsis); fprintf(stderr, "%-.*s%s", (int)(senl - (se+1)), se+1, ellipsis);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }