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>
index | next in thread | raw e-mail
>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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199807301057.TAA01164>
