From owner-freebsd-bugs@FreeBSD.ORG Sat Jan 24 00:50:02 2009 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 366CC1065673 for ; Sat, 24 Jan 2009 00:50:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 1242C8FC1A for ; Sat, 24 Jan 2009 00:50:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id n0O0o12v061367 for ; Sat, 24 Jan 2009 00:50:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id n0O0o1wg061366; Sat, 24 Jan 2009 00:50:01 GMT (envelope-from gnats) Resent-Date: Sat, 24 Jan 2009 00:50:01 GMT Resent-Message-Id: <200901240050.n0O0o1wg061366@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Kurt Miller Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 62D291065670 for ; Sat, 24 Jan 2009 00:49:15 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 516CF8FC1A for ; Sat, 24 Jan 2009 00:49:15 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id n0O0nFeY050037 for ; Sat, 24 Jan 2009 00:49:15 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id n0O0nFZx050036; Sat, 24 Jan 2009 00:49:15 GMT (envelope-from nobody) Message-Id: <200901240049.n0O0nFZx050036@www.freebsd.org> Date: Sat, 24 Jan 2009 00:49:15 GMT From: Kurt Miller To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/130924: poll() system call overwrites complete pollfd struct instead of just revents X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 24 Jan 2009 00:50:02 -0000 >Number: 130924 >Category: kern >Synopsis: poll() system call overwrites complete pollfd struct instead of just revents >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Jan 24 00:50:01 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Kurt Miller >Release: 7.0-release >Organization: Intricate Software >Environment: FreeBSD fbsd-i386-70.intricatesoftware.com 7.0-RELEASE FreeBSD 7.0-RELEASE #0: Sun Feb 24 19:59:52 UTC 2008 root@logan.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386 >Description: poll() system call overwrites complete pollfd struct instead of just revents. This can cause threaded programs to 'loose' new events set while another thread is blocked and waiting in poll(). For example the JDK allows one thread to change the pollfd events field while a second thread is blocked in poll(). After waking up the blocked thread and returning to poll, the new event is lost by the poll system call overwriting the complete pollfd struct instead of just revents. >How-To-Repeat: #include #include #include #include #include struct pollfd fds[2]; int pipefds[2]; static void * thread(void *arg) { sleep(1); fds[1].events = POLLIN | POLLOUT; write(pipefds[0], "", 1); return NULL; } int main(int argc, char *argv[]) { pthread_t tid; if (pipe(pipefds) != 0) err(1, "pipe failed"); fds[0].fd = pipefds[0]; fds[0].events = POLLIN; fds[1].fd = pipefds[1]; fds[1].events = POLLIN; if (pthread_create(&tid, NULL, thread, NULL) != 0) err(1, "pthread_create failed"); poll(fds, 2, -1); if (fds[1].events != (POLLIN | POLLOUT)) { printf("events overwritten by kernel!\n"); return 1; } return 0; } >Fix: change the poll system call to copyout just the revents value instead of the full pollfd struct. >Release-Note: >Audit-Trail: >Unformatted: