Subject: Re: 1.5.24-2: zero-length write() and ioctl() on fd -1 cause crashes
From: "Elliott Hughes" <[email-masked]>
To: [email-masked]
Cc: "Elliott Hughes" <[email-masked]>
Date: Thu, 4 Oct 2007 15:38:30 -0700 (PDT)
List-Id: <cygwin.cygwin.com>

On Wed, September 19, 2007 02:09, Corinna Vinschen wrote:
> On Sep 18 11:54, Elliott Hughes wrote:
>
>> http://software.jessies.org/terminator/ uses Cygwin to provide
>> Windows support, and it's been most useful. i just thought i'd
>> mention a couple of things that caused crashes in cygwin1.dll 1.5.24-2
>> where that might not have been Cygwin's intent (in both cases the
>> application's skating on thin ice anyway).
>>
>> first, if i do a zero-byte write(2) to a pty, i get a crash. POSIX says
>> the behavior in that situation is undefined. i haven't tested with a
>> regular file (where POSIX explicitly says that "write() will return 0
>> and have no other results").
>>
>> second, if i try to set the window size on fd -1, i get a crash:
>>
>> int fd = -1; struct winsize size; // set size.ws_col, size.ws_row,
>> size.ws_xpixel, and size.ws_ypixel... if (ioctl(fd, TIOCSWINSZ, &size) <
>> 0) {
>>
>>
>> my interpretation of POSIX is that i should get return value -1 and
>> errno set to EBADF in that case. i haven't tested with other invalid
>> file descriptors or other requests.
>>
>> i haven't tested earlier versions of cygwin1.dll.
>>
>> strangely, a quick look at the Cygwin source suggests that these cases
>> should be taken care of. "ioctl.cc"'s ioctl starts with a cygheap_fdget,
>> and check_iovec would appear to take care of the 0- byte write case for
>> write(2).
>
> I've investigated both problems using small testcases and GDB and I
> can't reproduce your observations.  In both cases Cygwin works fine,
> returning 0 from write(2) when writing 0 bytes to anything (including
> ptys), or, returning -1 from ioctl(2) when trying to set the window size
> on an invalid fd.
>
> These spurious crashes might hint to a problem in the application
> itself.  For instance, they could be the result of a stack corruption at
> some earlier point in the code.  Note that just because Cygwin crashes
> but, say, Linux doesn't, that doesn't mean the application is right and
> Cygwin is wrong.  The outcome of the application problem just shows
> different results on different systems.
>
> If, after investigation, you still think there's a Cygwin problem, we
> would need some tiny testcase in plain C, which allows to reproduce the
> problem with as little code as possible.

(sorry it took so long to get back to you, especially after you went to
such trouble, but i haven't had access to a Windows machine for a couple
of weeks.)

okay, i've tried to reproduce the two problems described above, and it
turns out that the problem was me assuming too much from a JVM stack trace
like this:

Stack: [0x1cb00000,0x1cd00000),  sp=0x1ccfc330,  free space=2032k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native
code)
C  [cygwin1.dll+0xb48b6]
C  [cygwin1.dll+0x92d88]
C  [cygwin1.dll+0xb5657]
C  [cygwin1.dll+0x92d88]
C  [pty.dll+0x8e27]
C  [pty.dll+0x425f]
C  [pty.dll+0x2140]
j 
terminator.terminal.PtyProcess.sendResizeNotification(Ljava/awt/Dimension;Ljava/awt/Dimension;)V+0

we were/are indeed getting reasonable errors back from Cygwin; the problem
is that we're trying to throw a (C++) exception, and that's causing a
crash.

it looks easily repeatable:

$ cat ex.cpp
#include <stdexcept>
int main() {
 try {
  throw new std::exception();
 } catch (const std::exception& ex) {
  return 1;
 }
 return 0;
}

$ g++ -Wno-long-long -fno-omit-frame-pointer -fno-strict-aliasing 
-gdwarf-2 -W -Wall -Wshadow -Werror  -pedantic ex.cpp -o ex

$ ./ex.exe
Hangup

$ cat ex.exe.stackdump
Stack trace:
Frame     Function  Args
0022C8A8  7C802532  (00000F50, 0000EA60, 000000A4, 0022C8F0)
0022C9C8  6109773C  (00000000, 7C8025F0, 7C802532, 000000A4)
0022CAB8  610952BB  (00000000, 003B0023, 00230000, 00000000)
0022CB18  6109579B  (0022CB30, 00000000, 00000094, 610A0EAA)
0022CBD8  61095952  (00000EEC, 00000006, 0022CC08, 61095B52)
0022CBE8  6109597C  (00000006, 600301DC, 0022CC58, 00403D73)
0022CC08  61095B52  (0022CC38, 004052F0, 0022CCA4, 00000001)
0022CC58  00403D87  (0022CAE0, 00000000, 0022CCE8, 004010FB)
0022CC68  004038C6  (00670250, 004072F8, 00000000, 00401078)
0022CCE8  004010FB  (00000001, 61169200, 00670090, 0022CC70)
0022CD98  61006198  (00000000, 0022CDD0, 61005510, 0022CDD0)
61005510  61004416  (0000009C, A02404C7, E8611001, FFFFFF48)
     17 [sig] ex 3820 c:\src\software.jessies.org\terminator\ex.exe: ***
fatal error - called with threadlist_ix -1

$

strangely, i can't find any mention of this on the web, or in the Cygwin
user guide/FAQ. are C++ exceptions unsupported, or do i need some extra
flags? (removing the flags shown above doesn't seem to make a difference.)
i'll happily RTFM, if someone could point me at the right M...

(apologies again for the earlier wild goose chase.)

> Thanks,
> Corinna
>
>
> --
> Corinna Vinschen                  Please, send mails regarding Cygwin to
> Cygwin Project Co-Leader          cygwin AT cygwin DOT com
> Red Hat
>
>

-- 
Elliott Hughes, http://www.jessies.org/~enh/
--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/