Jakob Bohm wrote:
On 04-10-2010 21:10, Victor Duchovni wrote:
On Mon, Oct 04, 2010 at 10:37:55AM -0400, Jeff Saremi wrote:

Does BIO support 64 bit IO (large files)? If so would the rest of
OpenSSL (such as the ssl itself) support those BIOs?
I configured the build with 64bit support and didn't see any noticeable
changes.
Specifically, I'd like to know if BIO_tell() is able to return a 64bit
value?

No, BIO_tell() is a macro:

include/openssl/bio.h:
#define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)

The (int) cast means that the result is never larger than INT_MAX.

And the upstream function call performs bounds clipping ?

long long a = (int)(0x100000000UL);     // 1^33 cast to (int)
int b = (int)(0x100000000UL);           // 1^33 cast to (int)
a == 0;         // this statement is true now
a != INT_MAX;   // this statement is true now
b == 0;         // this statement is true now
b != INT_MAX;   // this statement is true now


Bounds clipping would be:

long long a = 0x100000000UL;
if(a > INT_MAX)
        return INT_MAX;
else
        return (int)a;


If the library is compiled on a machine with 64-bit longs, then
the underlying BIO_ctrl() will return the value from lseek() or
ftell() cast to a (long). This does not imply that 64-bit files
will not break in some other way.

That can't be true with the (int) cast you pasted at the top above. Since sizeof(int) can be smaller than sizeof(long). So the above paragraph would be true is you has said .... ftell() cast to a (int). ....



I would call this a bug! There is no reason in portable code to
assume sizeof(int) == sizeof(long).

And you presume sizeof(long)==8 ?  See Win64 info below.

Isn't the off_t or loff_t the type used with lseek/llseek. So if the goal is to preserve as much as possible of the underlying operating system then this should be used throughout the OpenSSL return path as well.

Some operating system's will return an error condition for an overflowed result, when an overflowed result would become truncated if passed back through an older API using 32bit types. On Linux -1/EOVERFLOW.

Having a BIO_tell64() might be useful in those 32bit systems that support a 64bit file system API and large files.



And thinking that 64 bit platforms always have 64 bit ints (or even 64
bit longs) is a wrong assumption too.

A 64bit platform always has a 64bit wide sizeof(void *) and sizeof(long long) if the type is supported.


All other combination of sizeof(int) and sizeof(long) exist in the world, ILP64, LP64, LLP64.

Although 64bit wide sizeof(int) is getting rarer (ILP64).

Linux64 has 32bit sizeof(int), 64bit sizeof(long) (LP64)

Win64 has 32bit sizeof(long) (LLP64) I guess to assist porting from the 32bit world.



The rules that you can trust are:

The ones mandated by the C language.

[From memory]
sizeof(char) == 1 (aka 8 bits)
sizeof(short) >= sizeof(char)
sizeof(int) >= sizeof(short)
sizeof(long) >= sizeof(int)

In practice the only platforms with shorter than 32bit sizeof(int) are less than 32bit CPUs. I'm not even sure is OpenSSL tries to support smaller than 32bit CPUs out of the box you really have to try hard to find one in the embedded world since 32bit is so cheap now.


"long long" (GNU and some others)

Many others these days.


"int64_t" (some OS and compiler headers)

This is a good choice if you are looking for specific bit width cross-platform, but that is not what BIO_tell should use (see off_t and loff_t above).


Oh, and stdint.h is not available with all compilers!

Isn't this an ANSI requirement, ah well, poor compiler users what standards do they conform to then ?


Darryl
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to