From owner-freebsd-bugs Mon Oct 12 02:10:10 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id CAA28952 for freebsd-bugs-outgoing; Mon, 12 Oct 1998 02:10:10 -0700 (PDT) (envelope-from owner-freebsd-bugs@FreeBSD.ORG) Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id CAA28894 for ; Mon, 12 Oct 1998 02:10:03 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.8.8/8.8.5) id CAA01531; Mon, 12 Oct 1998 02:10:01 -0700 (PDT) Received: from athena.nextech.co.jp (node163.nextech.co.jp [210.162.96.163]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id CAA28290 for ; Mon, 12 Oct 1998 02:04:45 -0700 (PDT) (envelope-from kobayasi@nextech.co.jp) Received: (from kobayasi@localhost) by athena.nextech.co.jp (8.8.8/3.6W) id SAA17994; Mon, 12 Oct 1998 18:04:22 +0900 (JST) Message-Id: <199810120904.SAA17994@athena.nextech.co.jp> Date: Mon, 12 Oct 1998 18:04:22 +0900 (JST) From: Satosi KOBAYASI Reply-To: kobayasi@north.ad.jp To: FreeBSD-gnats-submit@FreeBSD.ORG X-Send-Pr-Version: 3.2 Subject: bin/8281: writev() in libc_r causes loop Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 8281 >Category: bin >Synopsis: writev() in libc_r causes loop >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Oct 12 02:10:00 PDT 1998 >Last-Modified: >Originator: Satosi KOBAYASI >Organization: NORTH (Network Organization for Research and Technology in Hokkaido) >Release: FreeBSD 2.2.7-RELEASE i386 >Environment: FreeBSD athena 2.2.7-RELEASE FreeBSD 2.2.7-RELEASE #0: Sun Oct 4 17:27:30 JST 1998 kobayasi@athena:/usr/local/src/remote/sys/compile/ASIX i386 >Description: writev() in libc_r causes loop when it's called with the following arguments: * the iovcnt is more than 0 * at the last member of the iovec array, the iov_len set to 0 (Detail) writev() defined in /usr/src/lib/libc_r/uthread/uthread_writev.c, calls _thread_sys_writev() in itself. When _thread_sys_writev() returns 0, writev() does't increment the index of the iovec array. So if the index points to the last member of the array, writev() calls _thread_sys_writev() with the member whose iov_len set to 0. Because there is nothing to write, _thread_sys_writev() returns 0, and writev() doesn't increment the index... >How-To-Repeat: Compile the following code with -lc_r, and run it. #include #include #include #include #include #include #include static char b1[] = "test"; static char b2[] = "foo"; int main(int argc, char **argv) { int fd; struct iovec buf[2]; if (argc != 2) { fprintf(stderr, "Usage: %s \n", *argv); exit(1); } if ((fd = open(*(argv + 1), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) < 0) { perror("open"); exit(1); } buf[0].iov_base = b1; buf[0].iov_len = strlen(b1); buf[1].iov_base = b2; buf[1].iov_len = 0; if (writev(fd, buf, 2) < 0) { perror("writev"); exit(1); } close(fd); exit(0); } >Fix: Apply the following patch or something like this. --- uthread_writev.c.orig Mon Oct 12 17:38:58 1998 +++ uthread_writev.c Mon Oct 12 18:00:02 1998 @@ -83,6 +83,16 @@ /* Perform a non-blocking write syscall: */ n = _thread_sys_writev(fd, &p_iov[idx], iovcnt - idx); + /* To avoid loop */ + if (n == 0) { + while (idx < iovcnt && p_iov[idx].iov_len == 0) + idx++; + if (idx == iovcnt) { + ret = num; + break; + } + } + /* Check if one or more bytes were written: */ if (n > 0) { /* >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message