Bug 454482 - vex amd64->IR: unhandled instruction bytes: 0xCD 0x80 0x89 0x45 0xFC 0x8B 0x45 0xFC 0x89 0x45
Summary: vex amd64->IR: unhandled instruction bytes: 0xCD 0x80 0x89 0x45 0xFC 0x8B 0x4...
Status: RESOLVED DUPLICATE of bug 342988
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (show other bugs)
Version: 3.19.0
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-05-27 12:44 UTC by Alfred Polanco
Modified: 2022-05-27 16:00 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
TAR file containing 2 text files with valgrind and gdb outputs (10.00 KB, application/octet-stream)
2022-05-27 12:46 UTC, Alfred Polanco
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alfred Polanco 2022-05-27 12:44:32 UTC
SUMMARY
***
When you compile code that executes assembly code to run the function __NR_getuid32 and run the code through valgrind, valgrind generates a core file for the process, raises a SIGILL signal and exits ungracefully.
***


STEPS TO REPRODUCE
1. Create a C++ file called usersamp.cpp with the following code:
-------------------------------------
#include <sys/types.h>
#include <sys/syscall.h>
#include <stdio.h>
#ifndef __NR_getuid32
#define __NR_getuid32 199
#endif
#define as_getuid() \
        ({ int id; asm ("int    $128": "=a" (id): "0" (__NR_getuid32)); id; })
int main()
{
    int userid = as_getuid();
    printf("Getuid definition =%d\n", __NR_getuid32);
    printf("This Id: %d\n", userid);
    return 0;
}
-------------------------------------

2. Execute the following GNU G++ to compile the code into a Linux debug binary:
 g++ -g -o usersamp usersamp.cpp

3. Execute the following Valgrind command to run the Linux debug binary:
valgrind --trace-children=yes --log-file=/tmp/vg_usersamp.out --num-callers=50 --error-limit=no --leak-check=full --show-reachable=yes --sigill-diagnostics=yes --verbose usersamp


OBSERVED RESULT
Valgrind generates an output saying "Illegal Instruction" then exits ungracefully. In the attached TAR file, there is a text file called vg_usersamp.out that has the output file generated by Valgrind and the output file, in part, has the following information:
----------------------------
vex amd64->IR: unhandled instruction bytes: 0xCD 0x80 0x89 0x45 0xFC 0x8B 0x45 0xFC 0x89 0x45
vex amd64->IR:   REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0
vex amd64->IR:   VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=NONE
vex amd64->IR:   PFX.66=0 PFX.F2=0 PFX.F3=0
==10197== valgrind: Unrecognised instruction at address 0x40054a.
==10197==    at 0x40054A: main (usersamp.cpp:11)
==10197== Your program just tried to execute an instruction that Valgrind
==10197== did not recognise.  There are two possible reasons for this.
==10197== 1. Your program has a bug and erroneously jumped to a non-code
==10197==    location.  If you are running Memcheck and you just saw a
==10197==    warning about a bad jump, it's probably your program's fault.
==10197== 2. The instruction is legitimate but Valgrind doesn't handle it,
==10197==    i.e. it's Valgrind's fault.  If you think this is the case or
==10197==    you are not sure, please let us know and we'll try to fix it.
==10197== Either way, Valgrind will now raise a SIGILL signal which will
==10197== probably kill your program.
==10197== 
==10197== Process terminating with default action of signal 4 (SIGILL): dumping core
==10197==  Illegal opcode at address 0x40054A
==10197==    at 0x40054A: main (usersamp.cpp:11)
==10197== 
----------------------------

EXPECTED RESULT
Valgrind should have executed the program to completion without exiting ungracefully.

SOFTWARE/OS VERSIONS
In the attached TAR file, there is a text file called vg_usersamp.out that has the output file generated by Valgrind and the output file, in part, has the following information:
----------------------------
--10197-- Contents of /proc/version:
--10197--   Linux version 3.10.0-957.12.2.el7.x86_64 (mockbuild@x86-037.build.eng.bos.redhat.com) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Fri Apr 19 21:09:07 UTC 2019
--10197-- 
--10197-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-ssse3-avx-avx2-bmi-f16c-rdrand-rdseed
----------------------------


ADDITIONAL INFORMATION
The attached vg_usersamp.tar TAR file contains the following text file:
vg_usersamp.out - The output file generated by Valgrind
vg_usersamp.gdb.core.10197.out - A UNIX script capture of the console output for a GDB session that examines the core file generated by Valgrind.
Comment 1 Alfred Polanco 2022-05-27 12:46:58 UTC
Created attachment 149258 [details]
TAR file containing 2 text files with valgrind and gdb outputs
Comment 2 Tom Hughes 2022-05-27 13:13:35 UTC
Why are you using int 0x80 to make a system call on x86_64 though?

Even newer x86_32 systems have better ways to make system calls and x86_64 has never really used that for them other that in artificial hand rolled code like yours.
Comment 3 Alfred Polanco 2022-05-27 14:39:34 UTC
Thank you for your response. The honest answer to your question is that this code was ported forward to 64-bit from an earlier 32-bit implementation. I acknowledge that this implementation can run into issues in the near future and I will raise a support ticket on my end to look into replacing this implementation. In the meantime, however, the implementation compiles and executes as expected for now. In addition, while the information of the link below agrees with you (and now, so do I) that this is a poor 64-bit implementation and alternatives exist, it does allude to a possible use-case for this implementation:
https://stackoverflow.com/questions/46087730/what-happens-if-you-use-the-32-bit-int-0x80-linux-abi-in-64-bit-code

However, in the majority of use cases, the main reason you can expect to see the use of 0x80 will be due to code that was lazily ported over to 64-bits from 32-bits, as is our case.  In our case, the intent of the code is to execute a call to getuid internally to prevent the function from being externally hijacked in an hacking attempt to impersonate a user. The 32-bit version of valgrind has no obvious issues executing this code so it came as a bit of a shock that the 64-bit version of valgrind immediately generated a core file. It is conceivable that others may run into a similar situation after porting similar code over.
Comment 4 Tom Hughes 2022-05-27 15:59:26 UTC
The point really is that I don't think we've ever bothered to implement in 0x80 on x86_64 because nothing uses it.
Comment 5 Tom Hughes 2022-05-27 16:00:36 UTC
We have in fact had one other report, seven years ago...

*** This bug has been marked as a duplicate of bug 342988 ***