Bug 188774

Summary: ftruncate writes register %ebx, which violates the syscall ABI
Product: [Fedora] Fedora Reporter: John Reiser <jreiser>
Component: kernelAssignee: Kernel Maintainer List <kernel-maint>
Status: CLOSED CURRENTRELEASE QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 5CC: wtogami
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: 2.6.18-1.2200.fc5 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2006-10-17 19:45:33 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description John Reiser 2006-04-13 01:54:14 UTC
Description of problem:
The ftruncate system call writes register %ebx instead of preserving %ebx.

Version-Release number of selected component (if applicable):
kernel-2.6.16-1.2080_FC5

How reproducible:
Always

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
#include <asm/unistd.h>

#define O_RDWR               02

_start: .globl _start
        nop
        int3
        movl $ O_RDWR,%ecx
        movl $ foo,%ebx
        movl $__NR_open,%eax
        int $0x80
        subl %ecx,%ecx  # 0
        movl %eax,%ebx  # fd
        movl $__NR_ftruncate,%eax
        int $0x80  # should not change %ebx, but does in 2.6.16-1.2080_FC5
        nop
        int3
        movl $__NR_exit,%eax
        int $0x80  # exit code is %ebx: should be fd returned by __NR_open

        .data
foo:
        .asciz "foo_file"
-----
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.
  
Actual results:
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
-----

Expected results:
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.]

Additional info:
%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.

Comment 1 John Reiser 2006-04-13 16:20:13 UTC
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
kernel stack
0xc014f271 <sys_ftruncate+18>:  jmp    0xc014f116 <do_sys_ftruncate>


Comment 2 Markus F.X.J. Oberhumer 2006-04-20 16:56:25 UTC
This problem has been fixed in the current 2.6.17 development tree. Please see
the following two git commits for details:

http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=0a489cb3b6a7b277030cdbc97c2c65905db94536


http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=385910f2b275a636238f70844f1b6da9fda6f2da


~Markus


Comment 3 Dave Jones 2006-10-16 18:48:05 UTC
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.

Thank you.

Comment 4 John Reiser 2006-10-17 19:45:33 UTC
Fixed in kernel-2.6.18-1.2200.fc5 (and also fixed long before that, too.)