SQLite User Forum

Errors with -fsanitize=strict-bounds
Login

Errors with -fsanitize=strict-bounds

(1) By Kirill Müller (krlmlr) on 2025-03-13 15:50:54 [source]

The RSQLite R package contains a copy of SQLite. Checks for that package with -fsanitize=strict-bounds report errors for accessing ExprList.a, which is a dynamically sized array declared as ExprList_Item[1].

Logs that show the error are here: https://www.stats.ox.ac.uk/pub/bdr/memtests/gcc-UBSAN/RSQLite/RSQLite-Ex.Rout .

The suggestion is to replace a[1] with the newer a[]. Doing this naively breaks sizeof() calculations.

This pattern seems to be repeated in many places. Is there a chance that this can be fixed, to comply with recent C standards?

(2) By Richard Hipp (drh) on 2025-03-13 16:33:38 in reply to 1 [link] [source]

Is there a chance that this can be fixed, to comply with recent C standards?

No, probably not.

  1. SQLite is used by countless systems, many of which use older compilers. Changing SQLite to appease the "recent standards" would cause untold and needless pain for many users.

  2. It's a lot of work that serves no useful propose. ("Standards compliant" is not a useful purpose. "Usefulness" is a useful propose.)

  3. There are no real errors discovered by -fsanitize=strict-bounds, only faux-errors; constructs that strict-bounds does not understand. On the other hand, making changes to appease strict-bounds has a high risk of introducing new, actual errors. So changes like this would end up increasing the number of errors in the code, not decreasing them.

(3) By Jan Nijtmans (jan.nijtmans) on 2025-03-14 10:47:23 in reply to 2 [link] [source]

This is how Tcl handles this:

#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # define TCLFLEXARRAY #elif defined(__GNUC__) && (__GNUC__ > 2) # define TCLFLEXARRAY 0 #else # define TCLFLEXARRAY 1 #endif

(4) By Richard Hipp (drh) on 2025-03-14 12:40:10 in reply to 3 [link] [source]

That is certainly a useful start. However, recognize that we also have to redo many sizeof() computations, depending on the value of TCLFLEXARRAY.

(5) By Jan Nijtmans (jan.nijtmans) on 2025-03-14 13:05:58 in reply to 4 [link] [source]

Instead of sizeof(...), use offsetof(..., lastfieldname)

(6) By Jan Nijtmans (jan.nijtmans) on 2025-03-14 13:14:13 in reply to 4 [link] [source]

Also note that sizeof() can give misleading bad results. For example: ` struct { int size; char str1; } s ` In this case, sizeof(s) will give the value 8, not 5 as might be expected, due to the structure alingment. So you cannot simply substract 1 and then expect to end up at the str field.

In SQLite this - most likely - leads to over-allocation of memory. Since memory-allocation is normally aligned at 8 or 16 bytes, no-one would notice that. But still ... it's wrong. That's why Tcl switched to use offsetof() in this case in stead of sizeof().

(7) By Bo Lindbergh (_blgl_) on 2025-03-14 13:50:07 in reply to 6 [link] [source]

Note that you have to use offsetof even in C99. For example, these two structs have the same size because of alignment padding:

typedef struct buf1 {
    size_t size;
    unsigned short flags;
    unsigned char data[1];
} buf1;

typedef struct buf0 {
    size_t size;
    unsigned short flags;
    unsigned char data[];
} buf0;

The real solution is to make -fsanitize=strict-bounds treat a 1-element array at the end of a struct as having dynamic size. File bugs against any and all compilers! :-)

(8) By Richard Hipp (drh) on 2025-03-14 13:57:46 in reply to 7 [link] [source]

The real solution is to make -fsanitize=strict-bounds treat a 1-element array at the end of a struct as having dynamic size.

Yeah, verily!

Nevertheless, my experience is that the standards people hate the C programming language and will do everything they can to destroy it by standardizing nonsense, so I don't think such a proposal will gain much traction. Hence, I'm working now to implement changes along the lines of what Jan suggested.

These "enhancements" would certainly lead to a huge number of memory errors, where it not for our excellent test suite....

(9) By Richard Hipp (drh) on 2025-03-15 19:58:34 in reply to 1 [link] [source]

Check-in 20250315195519 and following make use of the C99 flexible array feature, on systems that support that, using techniques outlined earlier in this thread. No warnings given with -fsanitize=bounds-strict, at least not when we use that option here.

(10) By Kirill Müller (krlmlr) on 2025-03-15 21:01:51 in reply to 9 [link] [source]

Thank you, this is wonderful! Looking forward to adding this to the RSQLite R package when released.

(11) By Richard Hipp (drh) on 2025-03-16 23:15:45 in reply to 10 [link] [source]

Please consider adding the package, or at least testing it, using the latest trunk code, which is well tested, as the next official release will likely be months and months away.

(12) By Kirill Müller (krlmlr) on 2025-03-17 04:26:43 in reply to 11 [link] [source]

(13) By Richard Hipp (drh) on 2025-03-17 14:43:43 in reply to 12 [link] [source]

I don't know how to operator your CI system. Can you give me an error message of some kind to work with?

(14) By Kirill Müller (krlmlr) on 2025-03-17 14:53:33 in reply to 13 [link] [source]

No error message, the check that failed previously is now successful. 🎉