Bug 131099 - [linux] [patch] readdir broken on Linux emulation.
Summary: [linux] [patch] readdir broken on Linux emulation.
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-emulation (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-01-28 23:50 UTC by Andreas Kies
Modified: 2009-03-04 20:30 UTC (History)
0 users

See Also:


Attachments
file.diff (325 bytes, patch)
2009-01-28 23:50 UTC, Andreas Kies
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Kies 2009-01-28 23:50:01 UTC
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.

Fix: Apply attached patch.

Patch attached with submission follows:
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");
        }
}
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2009-01-29 07:40:14 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-emulation

Over to maintainer(s).
Comment 2 Alexander Leidinger freebsd_committer freebsd_triage 2009-02-13 11:55:34 UTC
State Changed
From-To: open->patched

Patched in -current, MTS in about 2 weeks.
Comment 3 dfilter service freebsd_committer freebsd_triage 2009-02-13 11:55:34 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"
Comment 4 dfilter service freebsd_committer freebsd_triage 2009-03-04 20:26:51 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"
Comment 5 Alexander Leidinger freebsd_committer freebsd_triage 2009-03-04 20:27:45 UTC
State Changed
From-To: patched->closed

MFCed to RELENG_7.