aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-04-18 16:02:48 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-18 16:02:48 -0400
commit0a489cb3b6a7b277030cdbc97c2c65905db94536 (patch)
tree1a746dc22ed12badc30198c8eb5065535a76bbb0 /fs
parentac69e973ff0660e455f4ba1ddd4dcce4ae70ed1a (diff)
x86: don't allow tail-calls in sys_ftruncate[64]()
Gcc thinks it owns the incoming argument stack, but that's not true for "asmlinkage" functions, and it corrupts the caller-set-up argument stack when it pushes the third argument onto the stack. Which can result in %ebx getting corrupted in user space. Now, normally nobody sane would ever notice, since libc will save and restore %ebx anyway over the system call, but it's still wrong. I'd much rather have "asmlinkage" tell gcc directly that it doesn't own the stack, but no such attribute exists, so we're stuck with our hacky manual "prevent_tail_call()" macro once more (we've had the same issue before with sys_waitpid() and sys_wait4()). Thanks to Hans-Werner Hilse <hilse@sub.uni-goettingen.de> for reporting the issue and testing the fix. Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/open.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/open.c b/fs/open.c
index c32c89d6d8db..8279c65d3bef 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -331,7 +331,9 @@ out:
331 331
332asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length) 332asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
333{ 333{
334 return do_sys_ftruncate(fd, length, 1); 334 long ret = do_sys_ftruncate(fd, length, 1);
335 prevent_tail_call(ret);
336 return ret;
335} 337}
336 338
337/* LFS versions of truncate are only needed on 32 bit machines */ 339/* LFS versions of truncate are only needed on 32 bit machines */
@@ -343,7 +345,9 @@ asmlinkage long sys_truncate64(const char __user * path, loff_t length)
343 345
344asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) 346asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
345{ 347{
346 return do_sys_ftruncate(fd, length, 0); 348 long ret = do_sys_ftruncate(fd, length, 0);
349 prevent_tail_call(ret);
350 return ret;
347} 351}
348#endif 352#endif
349 353