Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Jan 2009 23:40:36 GMT
From:      Andreas Kies <andikies@gmail.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/131099: [patch] readdir broken on Linux emulation.
Message-ID:  <200901282340.n0SNeaqi088521@www.freebsd.org>
Resent-Message-ID: <200901282350.n0SNo1IN050165@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         131099
>Category:       misc
>Synopsis:       [patch] readdir broken on Linux emulation.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 28 23:50:01 UTC 2009
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901282340.n0SNeaqi088521>