Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Jul 1998 19:57:05 +0900 (JST)
From:      okimoto@mrit.mei.co.jp
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   misc/7443: fclose() locks after over reading by using fread() in pthread
Message-ID:  <199807301057.TAA01164@sango.mrit.mei.co.jp>

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

>Number:         7443
>Category:       misc
>Synopsis:       fclose() locks after over reading by using fread() in pthread
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul 30 04:00:00 PDT 1998
>Last-Modified:
>Originator:     Yoshiyuki OKIMOTO
>Organization:
Matsushita Research Institute Tokyo, Inc.
>Release:        FreeBSD 2.2.7-RELEASE i386
>Environment:

FreeBSD 2.2.7-RELEASE #0: Mon Jul 27 09:45:20 JST 1998


>Description:

Using fread() in pthread (-lc_r), if fread() is passwd
too many "size" (bigger than the rest byte of file) in 
2nd, 3rd argument, then fclose() locks.

>How-To-Repeat:

Save below to a file, eg, check.c.
Then comile it like this,

    % cc check.c -lc_r -o check

And execute it.

    % ./check check.c

This will lock at point fclose().


  -- "check.c" -- CUT HERE --

#include <stdio.h>
#include <pthread.h>

void *output_text(void *fp)
{
    int  chk;
    char buff[128];

    while (chk = fread(buff, sizeof (char), 127, fp)) {
	buff[chk] = '\0';
	printf("%s", buff);
    }

}

int main(int argc, char **argv)
{
    FILE	    *fp;		
    pthread_attr_t  attr;		
    pthread_t	    th_num;

    /* open file  */
    if ((fp = fopen(argv[1], "r")) == NULL) {
	perror(argv[1]);
	exit(1);
    }

    /* create thread attribution */
    if (pthread_attr_init(&attr)) {
	fprintf(stderr, "Error in pthread_attr_init \n");
	exit(1);
    }

    /* create new thread */
    if (pthread_create(&th_num, &attr, output_text, (void *)fp)) {
	fprintf(stderr, "Write number thread can't execute. \n");
	exit(1);
    }

    /* wait for thread termination */
    if ( pthread_join(th_num, NULL) ) {
	fprintf(stderr, "Some threads have trouble \n");
	exit(1);
    }

    /*  destroy thread attribution */
    if (pthread_attr_destroy(&attr)) {
	fprintf(stderr, "Error in pthread_attr_destroy \n");
	exit(1);
    }

    fclose(fp);

    return (0);
}

  -- "check.c" -- CUT HERE --



>Fix:
	
This patch will fix the problem.

*** lib/libc/stdio/fread.c.orig	Thu Jul 30 14:35:00 1998
--- lib/libc/stdio/fread.c	Thu Jul 30 14:35:22 1998
***************
*** 83,88 ****
--- 83,91 ----
  		resid -= r;
  		if (__srefill(fp)) {
  			/* no more input: return partial result */
+ #ifdef _THREAD_SAFE
+ 			_thread_funlockfile(fp);
+ #endif
  			return ((total - resid) / size);
  		}
  	}

>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



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