public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Jan Beulich <jbeulich@suse.com>
To: "H.J. Lu" <hjl.tools@gmail.com>
Cc: Binutils <binutils@sourceware.org>, Alan Modra <amodra@gmail.com>
Subject: Re: [PATCH v2] x86: avoid i386_dis_printf()'s staging area for potentially long strings
Date: Tue, 16 Aug 2022 08:06:20 +0200	[thread overview]
Message-ID: <02a83431-ad0a-be06-f7bc-7757f80faa7c@suse.com> (raw)
In-Reply-To: <CAMe9rOogrdgpojG1dxF_N8A-RYxH1Sk4GBuSUQiy04Vd5fOMRA@mail.gmail.com>

On 15.08.2022 21:19, H.J. Lu wrote:
> On Mon, Aug 15, 2022 at 8:38 AM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> PR binutils/29483
>>
>> When print_insn() processes op_txt[], it may pass strings into
>> i386_dis_printf() which staging_area[] cannot fit; this was observed for
>> an invalid form of VPSCATTERDD (both broadcast and zeroing-masking bits
>> set). Rather than arbitrarily enlarging that local array, avoid its use
>> altogether when the format string is simply "%s". This merely requires
>> two local variables to have their type constified.
>>
>> While limiting the scope of "res" it became apparent that
>> - no caller cares about the function's return value,
>> - the comment about the return value was wrong,
>> - a particular positive return value would have been meaningless to the
>>   caller.
>> Therefore convert the function to return "void" at the same time.
>> ---
>> An alternative to the special casing would be to introduce something
>> like i386_dis_puts(), then to be used by all call sites which currently
>> pass "%s" or format strings without any format characters at all (plus,
>> of course, i386_dis_printf() itself).
>> ---
>> v2: Add testcase.
>>
>> --- a/gas/testsuite/gas/i386/i386.exp
>> +++ b/gas/testsuite/gas/i386/i386.exp
>> @@ -1349,6 +1349,7 @@ if [gas_64_check] then {
>>         run_dump_test ehinterp
>>      }
>>      run_dump_test pr27198
>> +    run_dump_test pr29483
>>
>>      set ASFLAGS "$old_ASFLAGS --64"
>>
>> --- /dev/null
>> +++ b/gas/testsuite/gas/i386/pr29483.d
>> @@ -0,0 +1,11 @@
>> +#objdump: -dw
>> +#name: x86-64 PR binutils/29483
>> +
>> +.*: +file format .*
>> +
>> +Disassembly of section .text:
>> +
>> +0+ <pr29483>:
>> +[      ]*[a-f0-9]+:    65 62 62 7d 97 a0 94 ff 20 20 20 ae     vpscatterdd .*
>> +
>> +0x65,0x62,0x62,0x7d,0x97,0xa0,0x94,0xff,0x20,0x20,0x20,0xae
>> --- /dev/null
>> +++ b/gas/testsuite/gas/i386/pr29483.s
>> @@ -0,0 +1,5 @@
>> +       .text
>> +pr29483:
>> +       # This (VPSCATTERDD with EVEX.br and EVEX.z invalidly set) should not
>> +       # crash the disassembler.
>> +       .byte 0x65,0x62,0x62,0x7d,0x97,0xa0,0x94,0xff,0x20,0x20,0x20,0xae
>> --- a/opcodes/i386-dis.c
>> +++ b/opcodes/i386-dis.c
>> @@ -9264,31 +9264,40 @@ oappend_register (instr_info *ins, const
>>     STYLE is the default style to use in the fprintf_styled_func calls,
>>     however, FMT might include embedded style markers (see oappend_style),
>>     these embedded markers are not printed, but instead change the style
>> -   used in the next fprintf_styled_func call.
>> +   used in the next fprintf_styled_func call.  */
>>
>> -   Return non-zero to indicate the print call was a success.  */
>> -
>> -static int ATTRIBUTE_PRINTF_3
>> +static void ATTRIBUTE_PRINTF_3
>>  i386_dis_printf (instr_info *ins, enum disassembler_style style,
>>                  const char *fmt, ...)
>>  {
>>    va_list ap;
>>    enum disassembler_style curr_style = style;
>> -  char *start, *curr;
>> +  const char *start, *curr;
>>    char staging_area[100];
>> -  int res;
>>
>>    va_start (ap, fmt);
>> -  res = vsnprintf (staging_area, sizeof (staging_area), fmt, ap);
>> -  va_end (ap);
>> +  /* In particular print_insn()'s processing of op_txt[] can hand rather long
>> +     strings here.  Bypass vsnprintf() in such cases to avoid capacity issues
>> +     with the staging area.  */
>> +  if (strcmp (fmt, "%s"))
>> +    {
>> +      int res = vsnprintf (staging_area, sizeof (staging_area), fmt, ap);
>>
>> -  if (res < 0)
>> -    return res;
>> +      va_end (ap);
>>
>> -  if ((size_t) res >= sizeof (staging_area))
>> -    abort ();
>> +      if (res < 0)
>> +       return;
>>
>> -  start = curr = staging_area;
>> +      if ((size_t) res >= sizeof (staging_area))
>> +       abort ();
>> +
>> +      start = curr = staging_area;
>> +    }
>> +  else
>> +    {
>> +      start = curr = va_arg (ap, const char *);
>> +      va_end (ap);
>> +    }
>>
>>    do
>>      {
>> @@ -9303,10 +9312,7 @@ i386_dis_printf (instr_info *ins, enum d
>>                                                      curr_style,
>>                                                      "%.*s", len, start);
>>           if (n < 0)
>> -           {
>> -             res = n;
>> -             break;
>> -           }
>> +           break;
>>
>>           if (*curr == '\0')
>>             break;
>> @@ -9340,8 +9346,6 @@ i386_dis_printf (instr_info *ins, enum d
>>         ++curr;
>>      }
>>    while (true);
>> -
>> -  return res;
>>  }
>>
>>  static int
> 
> I prefer something like this with the disassembler output:
> 
>   0: 65 62 62 7d 97 a0 94 ff 20 20 20 ae vpscatterdd
> %xmm26,%gs:-0x51dfdfe0(%rdi,%xmm23,8){bad}{%k7}{z}/(bad)

But the precise representation of the "badness" isn't relevant to this
testcase. All we care about is that there's no crash (and perhaps, see
below, no overrun of the other buffer, but I view this as a separate
aspect).

As to the attachment - I figure honoring op_out[]'s 2nd dimension is
a necessary thing. I don't think I agree with bumping the buffer size,
though: 128 is as arbitrary as 100. Or else there would want to be a
comment next to MAX_OPERAND_BUFFER_SIZE explaining how the value was
determined and hence making clear under what conditions it might need
further bumping.

Yet you're the maintainer - if you want to go with your fix, I won't
be able to stop you.

Jan

  reply	other threads:[~2022-08-16  6:06 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-15 15:38 Jan Beulich
2022-08-15 19:19 ` H.J. Lu
2022-08-16  6:06   ` Jan Beulich [this message]
2022-08-16 15:14     ` H.J. Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=02a83431-ad0a-be06-f7bc-7757f80faa7c@suse.com \
    --to=jbeulich@suse.com \
    --cc=amodra@gmail.com \
    --cc=binutils@sourceware.org \
    --cc=hjl.tools@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).