-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Racy libc calls #3784
Description
Original bug ID: 3784
Reporter: administrator
Status: acknowledged
Resolution: open
Priority: normal
Severity: feature
Category: otherlibs
Bug description
Full_Name: Yaron Minsky
Version: 3.08.4
OS: Linux
Submission from: user-0cdfhf3.cable.mindspring.com (24.215.197.227)
It looks like OCaml makes a bunch of race-y calls to glibc functions.
The following is a quick list of places where suspicious function
calls appear. Most if not all of these calls are unproblematic when
only caml threads are involved, due to the locking of the main thread.
But in cases where C threads are making calls to these functions
races can and will occur.
This list was compiled by going through the list of non-reentrant
functions given in Advanced Programming in the Unix environment, by
Stevens and Rago. Each of the included functions has an *_r version
that is reentrant, and should it appears be used instead. Some
functions that don't have alternatives (for example, dlload and
dbm_close) were not flagged.
We would be happy to submit a patch with these fixes to mainline, if
Inria is interested in some outside help.
getlogin
./otherlibs/u (BUG)nix/getlogin.c:/* $Id: getlogin.c,v 1.8.6.1
2005/01/17 18:10:36 doligez Exp $ */
./otherlibs/unix/getlogin.c:extern char * getlogin(void);
./otherlibs/unix/getlogin.c:CAMLprim value unix_getlogin(value unit)
./otherlibs/unix/getlogin.c: name = getlogin();
./otherlibs/unix/getlogin.c: if (name == NULL) unix_error(ENOENT,
"getlogin", Nothing);
gmtime
./otherlibs/unix/gmtime.c:/* $Id: gmtime.c,v 1.16.6.1 2004/08/23
11:31:44 doligez Exp $ */
./otherlibs/unix/gmtime.c:CAMLprim value unix_gmtime(value t)
./otherlibs/unix/gmtime.c: tm = gmtime(&clock);
./otherlibs/unix/gmtime.c: if (tm == NULL) unix_error(EINVAL,
"gmtime", Nothing);
ctime
./otherlibs/win32unix/stat.c: value atime = Val_unit, mtime =
Val_unit, ctime = Val_unit;
./otherlibs/win32unix/stat.c: Begin_roots3(atime,mtime,ctime)
./otherlibs/win32unix/stat.c: ctime = copy_double((double) buf->st_ctime);
./otherlibs/win32unix/stat.c: Field (v, 11) = ctime;
./otherlibs/unix/utimes.c: times.actime = Double_val(atime);
./otherlibs/unix/utimes.c: if (times.actime || times.modtime)
./otherlibs/unix/stat.c: CAMLlocal5(atime, mtime, ctime, offset, v);
./otherlibs/unix/stat.c: ctime = copy_double((double) buf->st_ctime);
./otherlibs/unix/stat.c: Field (v, 11) = ctime;
getprotobyname
./otherlibs/unix/getproto.c:CAMLprim value unix_getprotobyname(value name)
./otherlibs/unix/getproto.c: entry = getprotobyname(String_val(name));
./otherlibs/unix/getproto.c:CAMLprim value unix_getprotobyname(value name)
./otherlibs/unix/getproto.c:{ invalid_argument("getprotobyname not
implemented"); }
getprotobynumber
./otherlibs/unix/getproto.c:CAMLprim value unix_getprotobynumber(value proto)
./otherlibs/unix/getproto.c: entry = getprotobynumber(Int_val(proto));
./otherlibs/unix/getproto.c:CAMLprim value unix_getprotobynumber(value proto)
./otherlibs/unix/getproto.c:{ invalid_argument("getprotobynumber not
implemented"); }
getpwnam
./otherlibs/unix/getpw.c:CAMLprim value unix_getpwnam(value name)
./otherlibs/unix/getpw.c: entry = getpwnam(String_val(name));
getpwuid
./otherlibs/unix/getpw.c:CAMLprim value unix_getpwuid(value uid)
./otherlibs/unix/getpw.c: entry = getpwuid(Int_val(uid));
localtime
./otherlibs/unix/gmtime.c:CAMLprim value unix_localtime(value t)
./otherlibs/unix/gmtime.c: tm = localtime(&clock);
./otherlibs/unix/gmtime.c: if (tm == NULL) unix_error(EINVAL,
"localtime", Nothing);
strerror
./byterun/sys.c: return strerror(errno);
./otherlibs/win32unix/errmsg.c: return copy_string(strerror(errnum));
./otherlibs/systhreads/posix.c: err = strerror(retcode);
./otherlibs/unix/errmsg.c: return copy_string(strerror(errnum));
getservbyname
./otherlibs/unix/getserv.c:CAMLprim value unix_getservbyname(value
name, value proto)
./otherlibs/unix/getserv.c: entry = getservbyname(String_val(name),
String_val(proto));
./otherlibs/unix/getserv.c:CAMLprim value unix_getservbyname(value
name, value proto)
./otherlibs/unix/getserv.c:{ invalid_argument("getservbyname not
implemented"); }
getgrgid
./otherlibs/unix/getgr.c:CAMLprim value unix_getgrgid(value gid)
./otherlibs/unix/getgr.c: entry = getgrgid(Int_val(gid));
getservbyport
./otherlibs/unix/getserv.c:CAMLprim value unix_getservbyport(value
port, value proto)
./otherlibs/unix/getserv.c: entry =
getservbyport(htons(Int_val(port)), String_val(proto));
./otherlibs/unix/getserv.c:CAMLprim value unix_getservbyport(value
port, value proto)
./otherlibs/unix/getserv.c:{ invalid_argument("getservbyport not
implemented"); }
getgrnam
./otherlibs/unix/getgr.c:CAMLprim value unix_getgrnam(value name)
./otherlibs/unix/getgr.c: entry = getgrnam(String_val(name));
ReplyForward
Mail Delivery System
MAILER-DAEMON@brion.inria.fr to me
More options 10:53 pm (1 minute ago)
This is the Postfix program at host brion.inria.fr.
I'm sorry to have to inform you that your message could not be
be delivered to one or more recipients. It's attached below.
For further assistance, please send mail to
If you do so, please include this problem report. You can
delete your own text from the attached returned message.
The Postfix program
caml-bugs@brion.inria.fr (expanded from caml-bugs@caml.inria.fr): unknown
user: "caml-bugs"
Final-Recipient: rfc822; caml-bugs@brion.inria.fr
Original-Recipient: rfc822; caml-bugs@caml.inria.fr
Action: failed
Status: 5.0.0
Diagnostic-Code: X-Postfix; unknown user: "caml-bugs"
---------- Forwarded message ----------
From: Yaron Minsky yminsky@gmail.com
To: caml-bugs@caml.inria.fr
Date: Tue, 6 Sep 2005 22:53:10 -0400
Subject: Use of racy libc calls
It looks like OCaml makes a bunch of race-y calls to glibc functions.
The following is a quick list of places where suspicious function
calls appear. Most if not all of these calls are unproblematic when
only caml threads are involved, due to the locking of the main thread.
But in cases where C threads are making calls to these functions
races can and will occur.
This list was compiled by going through the list of non-reentrant
functions given in Advanced Programming in the Unix environment, by
Stevens and Rago. Each of the included functions has an *_r version
that is reentrant, and should it appears be used instead. Some
functions that don't have alternatives (for example, dlload and
dbm_close) were not flagged.
We would be happy to submit a patch with these fixes to mainline, if
Inria is interested in some outside help.
getlogin
./otherlibs/u (BUG)nix/getlogin.c:/* $Id: getlogin.c,v 1.8.6.1
2005/01/17 18:10:36 doligez Exp $ */
./otherlibs/unix/getlogin.c:extern char * getlogin(void);
./otherlibs/unix/getlogin.c:CAMLprim value unix_getlogin(value unit)
./otherlibs/unix/getlogin.c: name = getlogin();
./otherlibs/unix/getlogin.c: if (name == NULL) unix_error(ENOENT,
"getlogin", Nothing);
gmtime
./otherlibs/unix/gmtime.c:/* $Id: gmtime.c,v 1.16.6.1 2004/08/23
11:31:44 doligez Exp $ */
./otherlibs/unix/gmtime.c:CAMLprim value unix_gmtime(value t)
./otherlibs/unix/gmtime.c: tm = gmtime(&clock);
./otherlibs/unix/gmtime.c: if (tm == NULL) unix_error(EINVAL,
"gmtime", Nothing);
ctime
./otherlibs/win32unix/stat.c: value atime = Val_unit, mtime =
Val_unit, ctime = Val_unit;
./otherlibs/win32unix/stat.c: Begin_roots3(atime,mtime,ctime)
./otherlibs/win32unix/stat.c: ctime = copy_double((double) buf->st_ctime);
./otherlibs/win32unix/stat.c: Field (v, 11) = ctime;
./otherlibs/unix/utimes.c: times.actime = Double_val(atime);
./otherlibs/unix/utimes.c: if (times.actime || times.modtime)
./otherlibs/unix/stat.c: CAMLlocal5(atime, mtime, ctime, offset, v);
./otherlibs/unix/stat.c: ctime = copy_double((double) buf->st_ctime);
./otherlibs/unix/stat.c: Field (v, 11) = ctime;
getprotobyname
./otherlibs/unix/getproto.c:CAMLprim value unix_getprotobyname(value name)
./otherlibs/unix/getproto.c: entry = getprotobyname(String_val(name));
./otherlibs/unix/getproto.c:CAMLprim value unix_getprotobyname(value name)
./otherlibs/unix/getproto.c:{ invalid_argument("getprotobyname not
implemented"); }
getprotobynumber
./otherlibs/unix/getproto.c:CAMLprim value unix_getprotobynumber(value proto)
./otherlibs/unix/getproto.c: entry = getprotobynumber(Int_val(proto));
./otherlibs/unix/getproto.c:CAMLprim value unix_getprotobynumber(value proto)
./otherlibs/unix/getproto.c:{ invalid_argument("getprotobynumber not
implemented"); }
getpwnam
./otherlibs/unix/getpw.c:CAMLprim value unix_getpwnam(value name)
./otherlibs/unix/getpw.c: entry = getpwnam(String_val(name));
getpwuid
./otherlibs/unix/getpw.c:CAMLprim value unix_getpwuid(value uid)
./otherlibs/unix/getpw.c: entry = getpwuid(Int_val(uid));
localtime
./otherlibs/unix/gmtime.c:CAMLprim value unix_localtime(value t)
./otherlibs/unix/gmtime.c: tm = localtime(&clock);
./otherlibs/unix/gmtime.c: if (tm == NULL) unix_error(EINVAL,
"localtime", Nothing);
strerror
./byterun/sys.c: return strerror(errno);
./otherlibs/win32unix/errmsg.c: return copy_string(strerror(errnum));
./otherlibs/systhreads/posix.c: err = strerror(retcode);
./otherlibs/unix/errmsg.c: return copy_string(strerror(errnum));
getservbyname
./otherlibs/unix/getserv.c:CAMLprim value unix_getservbyname(value
name, value proto)
./otherlibs/unix/getserv.c: entry = getservbyname(String_val(name),
String_val(proto));
./otherlibs/unix/getserv.c:CAMLprim value unix_getservbyname(value
name, value proto)
./otherlibs/unix/getserv.c:{ invalid_argument("getservbyname not
implemented"); }
getgrgid
./otherlibs/unix/getgr.c:CAMLprim value unix_getgrgid(value gid)
./otherlibs/unix/getgr.c: entry = getgrgid(Int_val(gid));
getservbyport
./otherlibs/unix/getserv.c:CAMLprim value unix_getservbyport(value
port, value proto)
./otherlibs/unix/getserv.c: entry =
getservbyport(htons(Int_val(port)), String_val(proto));
./otherlibs/unix/getserv.c:CAMLprim value unix_getservbyport(value
port, value proto)
./otherlibs/unix/getserv.c:{ invalid_argument("getservbyport not
implemented"); }
getgrnam
./otherlibs/unix/getgr.c:CAMLprim value unix_getgrnam(value name)
./otherlibs/unix/getgr.c: entry = getgrnam(String_val(name));