Documentation Source Text

Check-in [1316d197a4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Increased detail on pointer types in the bindptr.html document.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 1316d197a4f339f3c431c184c0d90f20712910833b191c05638912cf402464b5
User & Date: drh 2017-08-03 13:02:41.320
Context
2017-08-03
14:18
Fix typo in the pointer-passing document. (check-in: 2de67f2a1a user: drh tags: trunk)
13:02
Increased detail on pointer types in the bindptr.html document. (check-in: 1316d197a4 user: drh tags: trunk)
2017-08-02
14:08
When searching the changelog only, leave hyperlinks and other markup in the result summary. (check-in: 12433ed2a3 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to pages/bindptr.in.
233
234
235
236
237
238
239

240
241
242
243
244
245
246
Hence, it is not possible for SQL to leak the value of pointers.

<p>
In this way the new pointer-passing interface seems to solve all of the
security problems associated with passing pointer values from one
extension to another in SQLite.


<h2>Pointer Types</h2>

<p>
The "pointer type" in the last parameter to [sqlite3_bind_pointer()],
[sqlite3_result_pointer()], and [sqlite3_value_pointer()] is used to prevent
pointers intended for one extension from being redirected to a different
extension.  For example, without the use of pointer types, an attacker 







>







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
Hence, it is not possible for SQL to leak the value of pointers.

<p>
In this way the new pointer-passing interface seems to solve all of the
security problems associated with passing pointer values from one
extension to another in SQLite.

<tcl>hd_fragment ptrtyp {pointer types}</tcl>
<h2>Pointer Types</h2>

<p>
The "pointer type" in the last parameter to [sqlite3_bind_pointer()],
[sqlite3_result_pointer()], and [sqlite3_value_pointer()] is used to prevent
pointers intended for one extension from being redirected to a different
extension.  For example, without the use of pointer types, an attacker 
265
266
267
268
269
270
271


272
273
274
275
276
277
278
279
280







281






282











283



284





285















286






287

288
289
290
291
292
293
294
The pointer generated by the MATCH operator has a type of "fts3cursor"
but the carray() function expects to receives a pointer of type "carray".
Because the pointer type on the [sqlite3_result_pointer()] does not match
the pointer type on the [sqlite3_value_pointer()] call, 
[sqlite3_value_pointer()] returns NULL in carray() and thus signals
the CARRAY extension that it has been passed an invalid pointer.



<p>
Pointer types are static strings, which ideally should be string literals
embedded directly in the SQLite API call, not parameters passed in from
other functions.  Consideration was given to using integer values as
the pointer type, but static strings provides a much larger name space
which reduces the chance of accidental type-name collisions between
unrelated extensions.

<p>







Because pointer types must be static strings, and because string values






in SQLite are dynamic strings, that means that SQL values cannot be used











as a pointer type.  This prevents misguided developers from creating a



new SQL function that can manufacture pointer values directly from SQL.  





Such a function, if possible to write, would undermine the security of















the pointer-passing APIs.  Thus, the requirement that pointer types be 






static strings helps to prevent misuse of the pointer-passing interfaces.


<h2>Destructor Functions</h2>

<p>
The last parameter to the [sqlite3_bind_pointer()] and
[sqlite3_result_pointer()] routines is a pointer to a procedure
used to dispose of the P pointer once SQLite has finished with it.







>
>









>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
The pointer generated by the MATCH operator has a type of "fts3cursor"
but the carray() function expects to receives a pointer of type "carray".
Because the pointer type on the [sqlite3_result_pointer()] does not match
the pointer type on the [sqlite3_value_pointer()] call, 
[sqlite3_value_pointer()] returns NULL in carray() and thus signals
the CARRAY extension that it has been passed an invalid pointer.

<h3>Pointer types are static strings</h3>

<p>
Pointer types are static strings, which ideally should be string literals
embedded directly in the SQLite API call, not parameters passed in from
other functions.  Consideration was given to using integer values as
the pointer type, but static strings provides a much larger name space
which reduces the chance of accidental type-name collisions between
unrelated extensions.

<p>
By "static string", we mean a zero-terminated array of bytes that is
fixed and unchanging for the life of the program.  In other words, the
pointer type string should be a string constant.
In constrast, a "dynamic string" is a zero-terminated array of bytes
that is held in memory allocated
from the heap, and which must be freed to avoid a memory leak.
Do not use dynamic strings as the pointer type string.

<p>
Multiple commentators have expressed a desire to use dynamic strings
for the pointer type, and to have SQLite take ownership of the type strings
and to automatically free the type string
when it has finished using it.  That design is rejected for the
following reasons:

<ol>
<li><p>
The pointer type is not intended to be flexible and dynamic.  The
pointer type is intended to be a design-time constant.  Applications
should not synthesize pointer type strings at run-time.  Providing
support for dynamic pointer type strings would lead developers
to misuse the pointer-passing interfaces by creating run-time
synthesized pointer type strings.  Requiring the pointer type strings
to be static encourages developers to do the right thing by choosing
fixed pointer type names at design-time and encoding those names
as constant strings.

<li><p>
All string values at the SQL level in SQLite are dynamic strings.  
Requiring type strings to be static makes it difficult to 
create an application-defined SQL function that
can synthesize a pointer of an arbitrary type.  We do not want users
to create such SQL functions, since such functions would compromise the
security of the system.  Thus, the requirement to use static strings
helps to defend that the integrity of the pointer-passing interfaces against
ill-designed SQL functions.

<li><p>
Having SQLite take ownership of the type strings would impose a performance
cost on all applications, even applications that do not use the 
pointer-passing interfaces.  SQLite passes values around as instances
of the [sqlite3_value] object.  That object has a destructor, which because
of the fact that sqlite3_value objects are used for nearly everything, is
invoked frequently.  If the destructor needs to check to see if there is
a pointer type string that needs to be freed, that is a few extra CPU
cycles that need to be burned on each call to the destructor.  Those
cycles add up.  We would be willing to bear the cost of the extra CPU
cycles if pointer-passing was a commonly used programming paradigm, but
pointer-passing is rare, and so it seems unwise to impose a run-time cost
on billions and billions of applications that do not use pointer passing
just for convenience of a few applications that do.
</ol>

<p>
If you feel that you need dynamic pointer type strings in your application,
that is a strong indicator that you are misusing the pointer-passing interface.
Your intended use may be unsafe.
Please rethink your design.  Determine if you really need to be passing
pointers through SQL in the first place.  Or perhaps find a different
mechanism other than the pointer-passing interfaces described by this
article.

<h2>Destructor Functions</h2>

<p>
The last parameter to the [sqlite3_bind_pointer()] and
[sqlite3_result_pointer()] routines is a pointer to a procedure
used to dispose of the P pointer once SQLite has finished with it.