Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0006075OCamlruntime system and C interfacepublic2013-07-14 21:112015-12-11 19:26
Assigned Toxleroy 
Platformamd64OSOpenBSDOS Version5.3
Product Version4.00.1 
Target Version4.01.1+devFixed in Version4.02.0+dev 
Summary0006075: Compile warnings on OpenBSD
DescriptionOpenBSD prints warnings when unsafe library functions like strcpy are used. These functions are used internally in ocaml, so linking any native code program will cause warnings like

/usr/local/lib/ocaml/libasmrun.a(sys.o)(.text+0x7f7): In function `caml_sys_open':
: warning: strcpy() is almost always misused, please use strlcpy()
/usr/local/lib/ocaml/libasmrun.a(unix.o)(.text+0x265): In function `caml_search_in_path':
: warning: strcat() is almost always misused, please use strlcat()
/usr/local/lib/ocaml/libasmrun.a(ints.o)(.text+0x622): In function `caml_nativeint_format':
: warning: sprintf() is often misused, please use snprintf()

The functions are used safely, but the linker has no way to know they are used safely.

Fixing this for modern Unix systems is simple. However, Windows does not have snprintf and strlcpy. The strcpy and strcat warnings can be portably avoided by using strlen+memcpy. Avoiding the warning for sprintf would require #ifdef to test which C runtime library is available.
Attached Filesc file icon bsd-snprintf.c [^] (20,195 bytes) 2013-07-16 00:35 [Show Content]
c file icon sprintf.c [^] (1,309 bytes) 2013-07-29 17:31 [Show Content]
? file icon sprintf-diff [^] (442 bytes) 2013-08-01 23:29 [Show Content]
c file icon sprintf-2.c [^] (1,489 bytes) 2014-02-05 15:56 [Show Content]

- Relationships

-  Notes
xleroy (administrator)
2013-07-15 16:01

There is something unpleasant in having to rewrite working code (I think) just to silence linker warnings. Moreover, strlcpy and strlcat are BSD-only functions: they are not part of any standard (C, POSIX, SUS, etc) that I know of, and are not even available in GlibC. This adds insult to injury.

In more details: I agree the uses of strcpy and strcat mentioned in the PR can easily be rewritten without. I also agree that snprintf would make the number formatting functions in ints.c and floats.c not only safer, but also simpler. (We could let snprintf tell us how many bytes of output are really needed, instead of guessing beforehand.)

So, Windows is, as usual, the limiting factor. Note that recent (how recent?) MS CRT libraries have _snprintf, which is close except that it doesn't compute the number of characters to be written...
avsm (developer)
2013-07-16 00:34

One option is to bundle a copy of bsd-snprintf.c from the openssh-portable distribution, and use the local copy if the function isn't detected in a configure script. Is this even an option for OCaml, or is the licensing a problem?

Without that, all portability paths seem to require keeping the format length calculation code around behind an #ifdef, thanks to Windows' remarkable choice of behaviour if the buffer is too small in _sprintf.

Incidentally, the linker warning was introduced after sweeping most of the OpenBSD source tree clean of strcpy/strcat use. The recommendation to use strlcpy is a local one only -- we obviously can't control whether glibc chooses to adopt those interfaces or not. A quick glance around the uses in OCaml do look like they always know the string length just before the strcpy, and can be easily rewritten using a more explicit memmove.

I can introduce a local patch to the OpenBSD port for snprintf very easily (or even use asprintf as a slower but simpler change), but would prefer that the strcpy/strcat use is fixed upstream before adding a port-patch.
xleroy (administrator)
2013-07-29 17:31

More investigation suggests that MS CRT provides not just non-C99-compliant _snprintf and _vsnprintf functions, but also a _vscprintf function that computes the length of the output without generating it. Stitching the two together, we may have a solution.

Attached is a proof-of-concept C implementation of a caml_alloc_sprintf() function that works just like sprintf(), but allocates its result in the Caml heap and returns it. Untested yet; code review and comments most welcome. This new function would be a very welcome replacement to the hacks we currently do around sprintf for formatting numbers.
jfc (reporter)
2013-08-01 23:35

It is necessary to call va_end and va_start before calling vsnprintf a second time. Diff uploaded.

I may be away from my OpenBSD system for a few weeks. I will do more testing when I return.
doligez (administrator)
2014-01-17 16:05

> It is necessary to call va_end and va_start before calling vsnprintf a second time. Diff uploaded.

I don't know anything about varargs, but this is probably also the case for the _vscprintf and second _vsnprintf in the Windows branch.
oandrieu (reporter)
2014-02-05 15:55

FYI, mingw does provide C99-compliant snprintf & vsnprintf. So both versions should work for mingw.

I attached a sprintf.c version with va_start/va_end wrapping all *vprintf calls. calls added.
xleroy (administrator)
2014-02-05 17:09

Thanks, Olivier, for the info. I have a first cut of a patch that replaces strcpy, sprintf et al with safer code. Just need to clean it and have it reviewed. But after seeing [^] I agree this is worth fixing by the next major release :-)
xleroy (administrator)
2014-04-15 19:16

Tentative fix in commit 14607 on trunk. Works fine under Linux and BSD but needs testing under Windows. Should normally go in OCaml 4.02.

- Issue History
Date Modified Username Field Change
2013-07-14 21:11 jfc New Issue
2013-07-15 16:01 xleroy Note Added: 0009778
2013-07-15 16:01 xleroy Status new => acknowledged
2013-07-16 00:34 avsm Note Added: 0009780
2013-07-16 00:35 avsm File Added: bsd-snprintf.c
2013-07-29 17:31 xleroy File Added: sprintf.c
2013-07-29 17:31 xleroy Note Added: 0009990
2013-08-01 23:29 jfc File Added: sprintf-diff
2013-08-01 23:35 jfc Note Added: 0010073
2013-08-19 16:56 doligez Target Version => 4.01.1+dev
2014-01-17 16:05 doligez Note Added: 0010806
2014-01-17 16:06 doligez Tag Attached: patch
2014-02-05 15:55 oandrieu Note Added: 0010883
2014-02-05 15:56 oandrieu File Added: sprintf-2.c
2014-02-05 17:09 xleroy Note Added: 0010884
2014-04-15 19:16 xleroy Note Added: 0011285
2014-04-15 19:16 xleroy Assigned To => xleroy
2014-04-15 19:16 xleroy Status acknowledged => resolved
2014-04-15 19:16 xleroy Fixed in Version => 4.02.0+dev
2015-12-11 19:26 xleroy Status resolved => closed
2017-02-23 16:43 doligez Category OCaml runtime system => runtime system
2017-03-03 17:45 doligez Category runtime system => runtime system and C interface

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker