[M3devel] unsafe functions that read/write raw memory, integer conversions, obligation of unsafe code?

Mika Nystrom mika at async.async.caltech.edu
Sat Apr 24 23:25:23 CEST 2010


Unsafe code that exports only an UNSAFE INTERFACE has no particular obligation.

Unsafe code that exports a non-UNSAFE INTERFACE has to guarantee the
absence of unchecked runtime errors regardless of input---this can be
weakened to "regardless of input as long as that input can possibly be
provided by a non-UNSAFE module", but the latter might be difficult to
verify as it is a global property.

     Mika

Jay K writes:
>
>What is the obligation of stuff like:?
>
>
>UNSAFE INTERFACE UnixIO=3B
>
>
>PROCEDURE read(file:int=3B buffer: ADDRESS=3B length: INTEGER)=3B
>PROCEDURE write(file: int=3B ADDRESS=3B length: INTEGER)=3B
>
>
>
>The reason I ask is kind of tangential.
>
>I'll explain it=2C but it again it doesn't necessarily matter:
>
>In m3core/src/unix/Usocket.c we have=2C my doing:
>
>
>/* assert that *plen fits in a 32 bit signed integer=2C no matter
>if it is unsigned or signed=2C or 32 bits or 64 bits */
>
>#define ASSERT_PLEN \
>=A0=A0=A0 assert((plen =3D=3D NULL) || (((*plen)>=3D 0) && ((*plen) < (m3_s=
>ocklen_t)(1UL << 30))))=3B
>
>
>
>Sometimes *plen is signed=2C sometimes unsigned.
>I'm going to make it consistent from platform to platform.
>I used to try to match the underlying platform and avoid copying.
>
>
>
>The VMS C compiler is reasonably warning about *plen>=3D 0 always being tru=
>e=2C given unsigned *plen.
>So I'm wondering again what m3_socklen_t should be anyway.
>There are at least four candidates:
>=A0=A0 32bit signed int
>=A0=A0 32bit unsigned int=20
>=A0=A0 pointer sized int (INTEGER)
>=A0=A0 pointer sized unsigned integer (Word.T=2C which is INTEGER but with =
>a different interpretation)
>
>
>The numbers involves are always small and positive.
>=A0 It isn't a "buffer" size=2C but the size of a small struct.
>Most 64bit C environments use a 32bit unsigned int. Though=2C again=2C we d=
>on't have to match them.
>The comments I left say: Cygwin is 32bit int=2C HP-UX is size_t (32 or 64)=
>=2C the rest are unsigned int.
>VMS is usually size_t=2C or int under old setting. An size_t is surprisingl=
>y always 32 bits.
>But again the C settings aren't super relevant.
>
>
>I'm thinking I should definitely make it unsigned.
>That matches most platforms (which=2C again=2C doesn't matter)=2C lets the =
>assertion be cut in half=2C and thereby removing the warning.
>
>
>But again=2C what is my "safety obligation"?
>If some Modula-3 code passes in a "negative" number=2C am I doing a legitim=
>ate favor in failing an assertion?
>Or they might just as well have passed in an incorrectly very large integer=
> and overflowed their buffer just as well?
>=A0 Making negative numbers invalid seems useful at first glance=2C but the=
>n when you realize that pretty darn large numbers
>=A0=A0 will still get through=2C it seems less useful.
>
>
>Now=2C thinking about this more=2C it is not just about avoiding buffer ove=
>rflow.
>There is also the matter of truncating integers.
>If some Modula-3 code passes me the value 4GB + 1 and I in turm truncate th=
>at to just 1=2C I have done something wrong.
>Integer conversions have to be checked.
>Therefore=2C for one thing=2C I think these wrappers do need to know with c=
>ertainty what the underlying socken_t is.
>=A0 Even on platforms that don't declare it. :) Cygwin and VMS.
>
>
>Asserting that they fit in a half range 32 bit integer is a way to avoid be=
>ing completely precise.
>It is acceptable here -- it not the size of a "buffer"=2C but the size of a=
> fairly small struct=2C a struct addr.
>
>
>=A0- Jay
>
> 		 	   		  =



More information about the M3devel mailing list