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: |
1316d197a4f339f3c431c184c0d90f20 |
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
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 | 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> | > > > > > > > > > | > > > > > > | > > > > > > > > > > > | > > > | > > > > > | > > > > > > > > > > > > > > > | > > > > > > | > | 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. |
︙ | ︙ |