Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Racy libc calls #3784

Closed
vicuna opened this issue Sep 7, 2005 · 5 comments
Closed

Racy libc calls #3784

vicuna opened this issue Sep 7, 2005 · 5 comments

Comments

@vicuna
Copy link

vicuna commented Sep 7, 2005

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));

@vicuna
Copy link
Author

vicuna commented Oct 12, 2005

Comment author: administrator

The reentrant _r alternate libc functions are not always available ->
configuration problem. Keep this as feature wish.

@vicuna
Copy link
Author

vicuna commented Nov 24, 2005

Comment author: anonymous

I believe many C libraries automatically use thread-local storage for (all? most of?) these functions. This is certainly the case for GNU libc.

@vicuna
Copy link
Author

vicuna commented May 19, 2009

Comment author: @mshinwell

I've come across this issue again recently - just a reminder :) The configure script could check for the presence of the _r functions. I'm not sure whether there is a definitive reference for which of these might use TLS, but again, that will be very C library dependent.

@github-actions
Copy link

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@github-actions
Copy link

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants