[gnutls-devel] Waiting for input data

Jouko Orava jouko.orava at helsinki.fi
Fri Feb 8 20:38:54 CET 2013


On Fri, 8 Feb 2013, Jaak Ristioja wrote:
> Well I have used (void *)(intptr_t) sockfd, but it doesn't solve the
> real issue here, it just silences the compiler. When converted back
> using (int)(intptr_t), it might not compare equal to the original.

There are no architectures that support C99 where that happens.

Furthermore, you can always do this:

	gnutls_transport_ptr_t sockptr = (void *)(intptr_t)sockfd;
	if ((int)(intptr_t)(void *)sockptr != sockfd) {
		/* UNSUPPORTED ARCHITECTURE ERROR, ABORT! */
	}
	gnutls_transport_set_ptr(session, sockptr);

or, if you use separate send/receive descriptors,

	gnutls_transport_ptr_t recvptr = (void *)(intptr_t)recvfd;
	gnutls_transport_ptr_t sendptr = (void *)(intptr_t)sendfd;
	if ((int)(intptr_t)(void *)recvptr != recvfd ||
	    (int)(intptr_t)(void *)sendptr != sendfd) {
		/* UNSUPPORTED ARCHITECTURE ERROR, ABORT! */
	}
	gnutls_transport_set_ptr2(session, recvptr, sendptr);

The idea here is that you can always *verify* the conversions
retain the required value, and catch the case you fear might
someday happen.

There are a few reasons why the error will never happen,
even if you replace 'intptr_t' with 'long' (which is what most C code
with similar operations do).

One is that the Linux kernel, which runs on basically every imaginable
architecture you might wish to compile GnuTLS for, makes that assumption
internally very extensively.

The most practical reason is that valid descriptors are always small
positive integers. Even if theoretically they do not have to be, the C
function interfaces (select et al.) make it a practical necessity.

The hardest to prove, but still true, is that there are no
architectures even theoretically capable of compiling GnuTLS, where
	sizeof (int) > sizeof (void *)
or
	sizeof (void *) > sizeof (long)
They all have either
	sizeof (int) == sizeof (void *)
or
	sizeof (long) == sizeof (void *)
and have no "padding bits" (as the C standard calls them) in int or long.

For example, you can compile to a 8-bit AVR microcontroller,
but still have sizeof (int) == sizeof (void *) == sizeof (long) == 2,
or even ... == 4, depending on compiler options. The C compiler will
simply generate the necessary "emulation" or extra code, even
when native integer types are smaller.

Regards,
  Jouko Orava



More information about the Gnutls-devel mailing list