Red Hat Bugzilla – Bug 188774
ftruncate writes register %ebx, which violates the syscall ABI
Last modified: 2007-11-30 17:11:30 EST
Description of problem:
The ftruncate system call writes register %ebx instead of preserving %ebx.
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. Create a throw-away read-write file named foo_file using "date >foo_file".
2. Compile this program with "gcc -o ebx -nostartfiles -nostdlib ebx.S"
The 'int3' are for ease of use with gdb.
-----input file ebx.S
#define O_RDWR 02
_start: .globl _start
movl $ O_RDWR,%ecx
movl $ foo,%ebx
subl %ecx,%ecx # 0
movl %eax,%ebx # fd
int $0x80 # should not change %ebx, but does in 2.6.16-1.2080_FC5
int $0x80 # exit code is %ebx: should be fd returned by __NR_open
The program truncates 'foo_file' to have length 0, then exits with return code
equal what was left in %ebx by ftruncate, which should be the fd (the first
parameter to ftruncate.)
3. Run executable file ebx under gdb. Step through, and note that the ftruncate
syscall chagnes %ebx.
The ftruncate syscall changes %ebx. The values I see under gdb are %ebx=6 before
the call, and %ebx=1 after the call. When run under strace, the __NR_open
returns 3, the __NR_ftruncate changes %ebx from 3 to 1, and the __NR_exit
process return value is 1 instead of 3:
$ strace ./ebx
execve("./ebx", ["./ebx"], [/* 34 vars */]) = 0
open("foo_file", O_RDWR) = 3
ftruncate(3, 0) = 0
_exit(1) = ? ## should be _exit(3) instead
Process 13430 detached
ftrunctate, like all syscalls, should preserve %ebx, %esi, %edi, %ebp, %esp.
(Registers %eax, %ecx, %edx, and %eflags may change.)
[This is the same convention as C subroutine calls.]
%ebx is preserved in RHEL4 (nahant) kernel-2.6.9-22.0.1.EL,
and in Fedora Core 4 kernel-2.6.14-1.1637_FC4.
Here is confirmation of the problem:
$ gdb vmlinux
(gdb) x/5i sys_ftruncate
0xc014f25f <sys_ftruncate>: mov 0x4(%esp),%eax
0xc014f263 <sys_ftruncate+4>: xor %ecx,%ecx
0xc014f265 <sys_ftruncate+6>: mov 0x8(%esp),%edx
0xc014f269 <sys_ftruncate+10>: movl $0x1,0x4(%esp) ## changes saved %ebx on
0xc014f271 <sys_ftruncate+18>: jmp 0xc014f116 <do_sys_ftruncate>
This problem has been fixed in the current 2.6.17 development tree. Please see
the following two git commits for details:
A new kernel update has been released (Version: 2.6.18-1.2200.fc5)
based upon a new upstream kernel release.
Please retest against this new kernel, as a large number of patches
go into each upstream release, possibly including changes that
may address this problem.
This bug has been placed in NEEDINFO state.
Due to the large volume of inactive bugs in bugzilla, if this bug is
still in this state in two weeks time, it will be closed.
Should this bug still be relevant after this period, the reporter
can reopen the bug at any time. Any other users on the Cc: list
of this bug can request that the bug be reopened by adding a
comment to the bug.
In the last few updates, some users upgrading from FC4->FC5
have reported that installing a kernel update has left their
systems unbootable. If you have been affected by this problem
please check you only have one version of device-mapper & lvm2
installed. See bug 207474 for further details.
If this bug is a problem preventing you from installing the
release this version is filed against, please see bug 169613.
If this bug has been fixed, but you are now experiencing a different
problem, please file a separate bug for the new problem.
Fixed in kernel-2.6.18-1.2200.fc5 (and also fixed long before that, too.)