> On Oct 21, 2020, at 11:09 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
> 
> On Wed, Oct 21, 2020 at 4:45 PM Qing Zhao <qing.z...@oracle.com> wrote:
>> 
>> 
>> 
>> -- q --
>> The CPU shall be in x87 mode upon entry to a function. Therefore,
>> every function that uses the MMX registers is required to issue an
>> emms or femms instruction after using MMX registers, before returning
>> or calling another function.
>> -- /q --
>> 
>> (The above requirement slightly contradicts its own ABI, since we have
>> 3 MMX argument registers and MMX return register, so the CPU obviously
>> can't be in x87 mode at all function boundaries).
>> 
>> So, assuming that the first sentence is not deliberately vague w.r.t
>> function exit, emms should not be needed. However, we are dealing with
>> x87 stack registers that have their own set of peculiarities. It is
>> not possible to load a random register in the way you show.  Also,
>> stack should be either empty or one (two in case of complex value
>> return) levels deep at the function return. I think you want a series
>> of 8 or 7(6) fldz insns, followed by a series of fstp insn to clear
>> the stack and mark stack slots empty.
>> 
>> 
>> Something like this:
>> 
>> --cut here--
>> long double
>> __attribute__ ((noinline))
>> test (long double a, long double b)
>> {
>> long double r = a + b;
>> 
>> asm volatile ("fldz;                \
>>       fldz;                \
>>       fldz;                \
>>       fldz;                \
>>       fldz;                \
>>       fldz;                \
>>       fldz;                \
>>       fstp %%st(0);            \
>>       fstp %%st(0);            \
>>       fstp %%st(0);            \
>>       fstp %%st(0);            \
>>       fstp %%st(0);            \
>>       fstp %%st(0);            \
>>       fstp %%st(0)" : : "X"(r));
>> return r;
>> }
>> 
>> int
>> main ()
>> {
>> long double a = 1.1, b = 1.2;
>> 
>> long double c = test (a, b);
>> 
>> printf ("%Lf\n", c);
>> 
>> return 0;
>> }
>> --cut here—
>> 
>> 
>> 
>> Okay, so,
>> 
>> 1. First compute how many st registers need to be zeroed,  num_of_zeroed_st
>> 2. Then issue (8 - num_of_zeroed_st) fldz to push 0 to the stack to clear 
>> all the dead stack slots;
>> 3. Then issue (8 - num_of_zeroed_st) fstp %st(0) to pop the stack and empty 
>> the stack.
>> 
>> Is the above understanding correctly?
> 
> Yes.
> 
>> Another thought is:
>> 
>> Looks like it’s very complicate to use the st/mm register set correctly, So,
>> I assume that this set of registers might be very hard to be used by the 
>> attacker correctly.
>> Right?
> 
> Correct, but "very hard to be used" depends on how determined the attacker is.

Okay, I see.
Then I will clear the st registers per the above algorithm you suggested.

Thanks a lot for the help.

Qing
> 
> Uros.

Reply via email to