[Bug 25600] Skype crashes after login.

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Oct 19 17:34:24 CDT 2014


https://bugs.winehq.org/show_bug.cgi?id=25600

Michael Müller <michael at fds-team.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |michael at fds-team.de

--- Comment #13 from Michael Müller <michael at fds-team.de> ---
Hi,

today I spent some time to figure out why Skype causes a segmentation fault on
some systems. The root of this issue is not an invalid memory access but
instead Skype tries to execute a syscall using SYSENTER (I am on an intel
system).

The problem is now that the linux kernel does not understand the syscall and
returns with an error. The way how the return address is specified for such a
syscall differs between windows and linux  - and instead of going back to the
program code of Skype, the kernel returns to the __kernel_vsyscall function
inside of glibc. The next problem is that the Linux kernel changed the stack
pointer during the syscall, but did not reset it back to the one specified by
Skype, since this also works different between Windows and Linux. The stack
pointer is now invalid and the __kernel_vsyscall function tries to pop a value
from the stack causing a segmentation fault.

This segmentation fault is now handled by Wine. To do this wine calls the
function setup_exception_record() and checks the stack pointer. The invalid
stack is now detected, but the code only prints a warning and continues anyway:

---- snip ----
    if (stack - 1 > stack || /* check for overflow in subtraction */
        (char *)stack <= (char *)NtCurrentTeb()->DeallocationStack ||
        (char *)stack > (char *)NtCurrentTeb()->Tib.StackBase)
    {
        WARN( "exception outside of stack limits in thread %04x eip %08x esp
%08x stack %p-%p\n",
              GetCurrentThreadId(), (unsigned int) EIP_sig(sigcontext),
              (unsigned int) ESP_sig(sigcontext),
NtCurrentTeb()->Tib.StackLimit,
              NtCurrentTeb()->Tib.StackBase );
    }
---- snip ----

Wine is now going to deference the invalid pointer:

---- snip ----
stack->ret_addr     = (void *)0xdeadbabe;
---- snip ----

This results in a second segmentation fault inside the signal handler for the
original segmentation fault causing the kernel to kill the process.

However, we can not really fix this problem since it is impossible for us to
detect whether this is a regular linux syscall or a windows syscall. Moreover
some of the information which would be necessary to emulate such a syscall are
destroyed by the linux kernel. Setting the windows version to windows 2000
forces Skype to use interrupts instead, which would be much easier to emulate.

For those who are interested in which syscall Skype tries to execute, I decoded
the necessary information. The syscall number is 0xad which is
NtQuerySystemInformation on Windows XP and the parameters are: 0xb, 0x5ac0,
0x7c8, 0x2e5e848. The value 0xb specifies the information class
SystemModuleInformation. So what Skype is trying to execute using syscalls /
interrupts is:
NtQuerySystemInformation(SystemModuleInformation, 0x5ac0, 0x7c8, 0x2e5e848);
The Linux kernel btw. interprets the same syscall as sys_rt_sigreturn.

As I already mentioned above, there is not much we can do about this since we
can not catch such wrong syscalls before they reach the linux kernel and this
is most probably WON'T FIX - at least the code path for > Win2000, interrupt
emulation is easy compared to that.

Regards,
Michael

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.


More information about the wine-bugs mailing list