From nobody@FreeBSD.org  Wed Jan 28 23:40:37 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 92E0E106566C
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 28 Jan 2009 23:40:37 +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 64B658FC1B
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 28 Jan 2009 23:40:37 +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 n0SNeaOA088522
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 28 Jan 2009 23:40:36 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id n0SNeaqi088521;
	Wed, 28 Jan 2009 23:40:36 GMT
	(envelope-from nobody)
Message-Id: <200901282340.n0SNeaqi088521@www.freebsd.org>
Date: Wed, 28 Jan 2009 23:40:36 GMT
From: Andreas Kies <andikies@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] readdir broken on Linux emulation.
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         131099
>Category:       kern
>Synopsis:       [linux] [patch] readdir broken on Linux emulation.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-emulation
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 28 23:50:01 UTC 2009
>Closed-Date:    Wed Mar 04 20:27:57 UTC 2009
>Last-Modified:  Wed Mar  4 20:30:04 UTC 2009
>Originator:     Andreas Kies
>Release:        7.1
>Organization:
>Environment:
FreeBSD andiunx.local 7.1-RELEASE FreeBSD 7.1-RELEASE #0: Thu Jan  1 14:37:25 UTC 2009     root@logan.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386

>Description:
The system call readdir does not return any data if a Linux binary is run.
The internally calculated space for returning an entry is
sizeof(struct dirent *), but it should be sizeof(struct dirent).
Please consider applying the attached patch.


>How-To-Repeat:
/*Compile the following program */

/* Compile with -fno-stack-protector if you want to run it as a Linux binary
 * on FreeBSD 7.1
 * Assembly part might be broken if optimization is used.
*/

#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>

int myreaddir( int fd, unsigned char *buf, int c)
{
 int res;
__asm__ __volatile__ ("\
 mov    $0x59,%%eax \n\
 int    $0x80 \n"
 : "=a" (res)  : "b" (fd), "c" (buf), "d" (c)
);
 return res;
}

int main()
{
        int fd;
        int i, j;
        unsigned char inparr[512];
        DIR *dipo;
        int respar;

        dipo=opendir(".");
        for (j=0; j < 10; j++) {
                memset( inparr, 0x55, sizeof(inparr));
                respar=myreaddir(dirfd(dipo),inparr, 1);
                if ( respar == 0 )
                        break;
                if ( respar != 1 )
                        printf("respar %d\n", respar);
                for (i=0; i < 25; i++)
                        printf( "%02x ", inparr[i]);
                printf( "\n");
        }
}

>Fix:
Apply attached patch.

Patch attached with submission follows:

--- linux_file.c.orig	2009-01-29 00:24:33.000000000 +0100
+++ linux_file.c	2009-01-29 00:24:55.000000000 +0100
@@ -438,7 +438,7 @@
 		/* readdir(2) case. Always struct dirent. */
 		if (is64bit)
 			return (EINVAL);
-		nbytes = sizeof(linux_dirent);
+		nbytes = sizeof(*linux_dirent);
 		justone = 1;
 	} else
 		justone = 0;


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-emulation 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Thu Jan 29 07:40:14 UTC 2009 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=131099 
State-Changed-From-To: open->patched 
State-Changed-By: netchild 
State-Changed-When: Fri Feb 13 11:55:34 UTC 2009 
State-Changed-Why:  
Patched in -current, MTS in about 2 weeks. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=131099 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/131099: commit references a PR
Date: Fri, 13 Feb 2009 11:55:34 +0000 (UTC)

 Author: netchild
 Date: Fri Feb 13 11:55:19 2009
 New Revision: 188572
 URL: http://svn.freebsd.org/changeset/base/188572
 
 Log:
   Fix an edge-case of the linux readdir: We need the size of a linux dirent
   structure, not the size of a pointer to it.
   
   PR:		131099
   Submitted by:	Andreas Kies <andikies@gmail.com>
   MFC after:	2 weeks
 
 Modified:
   head/sys/compat/linux/linux_file.c
 
 Modified: head/sys/compat/linux/linux_file.c
 ==============================================================================
 --- head/sys/compat/linux/linux_file.c	Fri Feb 13 11:36:32 2009	(r188571)
 +++ head/sys/compat/linux/linux_file.c	Fri Feb 13 11:55:19 2009	(r188572)
 @@ -345,7 +345,7 @@ getdents_common(struct thread *td, struc
  		/* readdir(2) case. Always struct dirent. */
  		if (is64bit)
  			return (EINVAL);
 -		nbytes = sizeof(linux_dirent);
 +		nbytes = sizeof(*linux_dirent);
  		justone = 1;
  	} else
  		justone = 0;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: netchild 
State-Changed-When: Wed Mar 4 20:27:45 UTC 2009 
State-Changed-Why:  
MFCed to RELENG_7. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=131099 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/131099: commit references a PR
Date: Wed,  4 Mar 2009 20:26:51 +0000 (UTC)

 Author: netchild
 Date: Wed Mar  4 20:26:39 2009
 New Revision: 189370
 URL: http://svn.freebsd.org/changeset/base/189370
 
 Log:
   MFC r188572:
     Fix an edge-case of the linux readdir: We need the size of a linux dirent
     structure, not the size of a pointer to it.
   
     PR:		131099
     Submitted by:	Andreas Kies <andikies@gmail.com>
 
 Modified:
   stable/7/sys/   (props changed)
   stable/7/sys/compat/linux/linux_file.c
   stable/7/sys/contrib/pf/   (props changed)
   stable/7/sys/dev/ath/ath_hal/   (props changed)
   stable/7/sys/dev/cxgb/   (props changed)
 
 Modified: stable/7/sys/compat/linux/linux_file.c
 ==============================================================================
 --- stable/7/sys/compat/linux/linux_file.c	Wed Mar  4 18:36:48 2009	(r189369)
 +++ stable/7/sys/compat/linux/linux_file.c	Wed Mar  4 20:26:39 2009	(r189370)
 @@ -438,7 +438,7 @@ getdents_common(struct thread *td, struc
  		/* readdir(2) case. Always struct dirent. */
  		if (is64bit)
  			return (EINVAL);
 -		nbytes = sizeof(linux_dirent);
 +		nbytes = sizeof(*linux_dirent);
  		justone = 1;
  	} else
  		justone = 0;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
