重磅:SQLite数据库爆出漏洞,数以千计应用或受影响!
liebian365 2024-10-22 15:39 29 浏览 0 评论
腾讯Blade安全团队发现,SQLite允许攻击者在受害者的计算机上运行恶意代码,并在危险较小的情况下泄漏程序内存或导致程序崩溃。由于SQLite嵌入在数千个应用程序中,因此该漏洞会影响各种软件,包括物联网设备、桌面软件、Web浏览器、Android与iOS等应用。
如果底层浏览器支持SQLite和Web SQL API,那么将漏洞利用代码转换为常规SQL语法也可以通过访问网页等操作远程利用此漏洞。Chromium浏览器引擎支持此API,这意味着像Chrome、Vivaldi、Opera 和Brave等浏览器都会受到影响,而Firefox和Edge 由于不支持此API,因此不受影响。
想想OpenSSH,Intel CPU(Meltdow和Spectre问题),每个产品都是在不断发展中日趋完善,无论是开源还是闭源,软件还是硬件。针对SQLite出现的问题,通过升级浏览器和修补API漏洞来解决。作为SQLite的忠实使用者,无论从产品开发还是应用体验,SQLite都是不错的选择,尤其是轻量化关系数据库应用中。借此机会,下面给读者普及下SQLite基础知识。
SQLite是一个开源的、内嵌式的嵌入式关系型数据库。SQLite和Oracle和Access一样是文件型数据库,就是说,一个数据库就是一个文件,此数据库里可以建立很多的表,可以建立索引、触发器等等,但是它实际上得到的就是一个文件。SQLite数据库具有下面的特点:
- (1)首先SQLite数据库服务器就在你的数据库应用程序中,其好处是不需要网络配置和管理,也不需要通过设置数据源访问数据库服务器。
- (2)其次SQLite数据库的服务器和客户端运行在同一个进程中。这样可以减少网络访问的消耗,简化数据库管理,使你的程序部署起来更容易。
- (3)再次SQLite在处理数据类型时与其它的数据库不同。区别在于它所支持的类型以及这些类型是如何存储、比较、强化(enforc)和指派(assign)。
SQLite的域完整性被称为域亲和性(affinity)。为了理解类型亲和性,你必须先要理解存储类和弱类型(manifesttyping)。SQLite有Integer、Real、Text、Blob和Null五个原始的数据类型,被称为存储类。存储类这个词表明了一个值在磁盘上存储的格式,其实就是类型或数据类型的同义词。
数据库SQLite的数据库架构
SQLite在架构上采用了模块的设计,它由公共接口、编译器系统、虚拟机和后端四个子系统组成。
1、接口(Interface)。由SQLite C API组成,也就是说不管是程序、脚本语言还是库文件,最终都是通过它与SQLite交互的(我们通常用得较多的ODBC/JDBC最后也会转化为相应C API的调用)。
2、编译器(Compiler)。在编译器中,分词器(Tokenizer)和分析器(Parser)对SQL进行语法检查,然后把它转化为底层能更方便处理的分层的数据结构---语法树,然后把语法树传给代码生成器(code generator)进行处理。而代码生成器根据它生成一种针对SQLite的汇编代码,最后由虚拟机执行。
3、虚拟机(Virtual Machine)。架构中最核心的部分是虚拟机,或者叫做虚拟数据库引擎(Virtual Database Engine,VDBE)。它和Java虚拟机相似,解释执行字节代码。VDBE的字节代码由128个操作码(opcodes)构成,它们主要集中在数据库操作。它的每一条指令都用来完成特定的数据库操作(比如打开一个表的游标)或者为这些操作栈空间的准备(比如压入参数)。
4、后端(Back-End)。后端由B-树(B-tree),页缓存(page cache,pager)和操作系统接口(即系统调用)构成。B-tree和page cache共同对数据进行管理。B-tree的主要功能就是索引,它维护着各个页面之间的复杂的关系,便于快速找到所需数据。而pager的主要作用就是通过OS接口在B-tree和Disk之间传递页面。
嵌入式数据库SQLite的数据类型
在SQLite数据库中,不仅提供了储存基本数据的功能,而且提供了对二进制数据存储的能力,这样可以确保把采集到的农业图像信息存放到数据库中,由数据库统一操作和管理,在SQLite数据库中提供的基本数据类型不但可以进行转化,还可以进行大小比较。数据类型如下:
- (1)Integer整数值。有正负之分,它是由8个字节(Bytes)表示。SQLite数据库可以根据整数值的大小自动控制其所占字节的个数。
- (2)Real实数类型。在SQLite由8个字节来表示。
- (3)Text文本字符数据类型。用来保存文本信息。SQLite数据库支持多种字符编码类型,包括UTF-8和UTF-16。字符串的大小是没有限制的。
- (4)Blob二进制数据对象类型。保存二进制数据,大小没有限制。
- (5)Null空类型。一个具有NULL存储类型的值比所有其它类型值都小。SQLite数据库对Null完全支持。
SQLite 数据库本身一共有80多个API调用接口,功能简单的数据库程序用三个接口完成: sqlite3_open(),sqlite3_exec(), 和 sqlite3_close()。 要是想更好的控制数据库引擎,使用sqlite3_prepare()函数把SQL语句编译成字节码再通过sqlite3_step()函数来执行。在SQLite中,绝大多数接口提供了UTF-8和UTF-16两个版本,大多数接口成对出现。
此外,SQLite数据库中同时也提供了用户对API接口扩充的机制。SQLite的扩充API用来支持用户定义的函数、聚合和排序法。实现一个用户自定义的函数分为两步。首先,写句柄。句柄实现一些你想通过SQL完成的功能。然后,注册句柄。为它提供SQL名称、参数的数量和一个指向句柄的指针。
数据库控制和语句执行方式
从数据库打开开始,SQLite就要为sqlite3 *类型准备好内存,一直到数据库关闭整个过程。打开数据库时,这个类型的变量指向你将操作的数据库。SQLite数据库和大多数据库操作相同,其过程连接并打开数据库、处理事务和断开连接并关闭数据库构成:
1、连接并打开数据库。每个SQLite数据库都存储在单独的操作系统文件中,数据库与文件一一对应。连接并打开数据库的接口调用为sqlite3_open(),它用来打开一个数据库文件,该数据库文件中可以包含许多个关系表。该接口调用成功返回SQLITE_OK。
数据库打开成功。SQLite还可以创建内存数据库。如果你使用:memory:或一个空字符串做数据库名,数据库将在RAM中创建。内存数据库将只能被创建它的连接所存取,不能与其它连接共享。另外,内存数据库只能存活于连接期间,一旦连接关闭,数据库就将从内存中被删除。
2、处理事务。SQLite 是支持事务处理的。默认情况下,事务自动提交,也就是每一个SQL语句都在一个独立的事务下运行。任何SQL语句命令都在事务下执行。可以通过Begin、Commit和Rollback等命令手动提交事务。如开始、提交、回滚事务过程如下:
3、数据库SQL语句执行。在SQLite数据库中执行事务最常用的接口是sqlite3_exec(),在这个函数中有指向sqlite3_exec()的回调函数的指针参数。例如做 insert 操作或做 delete 操作时,就没有必要使用回调,该函数指针可设为NULL。而当你做 select 时,就要使用该回调函数,因为 sqlite3 把数据查出来,得通过回调告诉你查出了什么数据。
数据库对SQL语句的执行方式在下一节详述,回调函数的形式为:
typedef int (*sqlite3_callback)(void*,int,char**, char**)。
在SQLite数据库中执行事务的接口也可以是sqlite3_get_table(),它返回一个表格化的结果集。不需要提供回调函数。
4、执行SQL语句。SQL语句的执行过程由三个阶段完成,下面会详述。
5、格式化(动态构造)SQL语句,利用sqlite接口函数构造SQL语句,并调用相关接口执行语句。首先调用sqlite3_mprintf()或sqlite3_vprintf()格式化SQL语句,接着调用sqlite3_exec()执行语句,最后调用sqlite3_free()释放内存资源。也可以调用sqlite3_exec_printf()完成整个过程。
6、断开连接并关闭数据库。前面如果用 sqlite3_open 开启了一个数据库,结尾时不要忘了还要关闭所有附加的数据库文件。SQLite提供接口为SQLite3_close()。
SQL语句的执行在SQLite数据库中分两种情况,预编译查询和封装查询。
预处理查询是SQLite执行所有SQL命令的方式,每一个阶段都关联于语句句柄的一种状态(prepared、active和finalized)。Pepared表示所有资源都已分配,对应接口函数为sqlite3_prepare(),语句已经可以执行但还没有执行。现在还没有申请锁,一直到调用sqlite3_step()时才会申请锁。Active状态开始于对sqlite3_step()的调用,此时语句正在被执行并拥有某种锁。Finalized意味着语句已经被关闭且所有相关资源已经被释放。
封装查询是预处理查询的封装。在使用上比较简单,允许你在单一的函数调用中执行SQL命令。一个函数是sqlite3_exec(),特别适合执行不需要返回数据的查询。为了让查询结果数据返回,必须实现回调函数,传递给sqlite3_exec()函数作为参数。另一个是sqlite3_get_table(),返回一个表格化的结果集。封装查询也可以格式化SQL语句之后再执行。
二进制数据的数据库处理技术
在农业信息采集嵌入式系统中,为了满足对采集信息有效地在数据库中储存、管理、查询和传输的要求,必须要对数据库处理的关键技术进行研究。这些技术包括:记录和字符串处理、字段处理、错误控制、操作控制和线程处理。
1、记录和字符串的处理是数据库中最常用的处理方式。在前面也提到过sqlite3_exec()和sqlite3_get_table()函数是处理事务和执行SQL语句接口,区别在于sqlite3_exec()在处理记录,如执行SELECT时,要得到处理结果需提供回调函数。提供回调函数的作用就是当在执行完对记录的操作后,让回调函数按需要得到处理结果。字符串处理主要用在对SQL语句的格式化上,在SQLite数据库中常用接口为sqlite3_mprintf()或sqlite3_vprintf()。
2、字段处理是在记录操作的基础上进行的。在SQLite中提供了以对字段操作的函数接口,其特点是sqlite3_column_开头。这些接口可以获得字段名称、字段的存储类型和字段的值等信息。如获得一个字段的名称、储存类型和声明类型的函数调用如下:
3、SQLite数据库预定义了许多错误代码宏以方便程序设计错误处理的应用。很多API接口函数的返回类型是整形,这表示返回错误码,所以在接口调用中可以根据返回码进行错误处理,可以使用函数sqlite3_errmsg()获得附加的错误信息。
图像数据在sqlite数据库中是按照二进制形式存放的。 操作二进制数据需要用一个辅助的数据类型:sqlite3_stmt * 。它是一个已经把SQL语句进行了解析,并用sqlite自己标记记录的内部数据结构来表示的SQL语句。正因为这个结构已经被解析了,所以你可以往这个语句里插入二进制数据。
把二进制数据插到 sqlite3_stmt 结构的过程,必须用sqlite 提供的函数来插入。SQLite数据库提供了一种通配符机制用来表示SQL语句中不确定的字符值,这些通配符如?、aaa、nnn等。做这些通配符所代表的值在sqlite3_bind_开头的接口函数中被填充,在SQLite数据库中提供了很多以sqlite3_bind_开头的接口用来给SQL声明中的通配符赋值。
二进制数据的存储相对比较复杂一点,但从数据库对二进制数据的操作来看,主要分为数据写入和数据读出。
1、数据写入是指将二进制数据写到数据库中,让数据库统一管理保存。在SQLite中,二进制数据时保存在Blob数据类型中的。数据的写入步骤是:创建数据库关系表,构造含有通配符的插入二进制数据的SQL语句,然后把该语句解析到sqlite3_stmt 结构中。如:
调用接口函数sqlite3_bind_blob()给SQL申明的通配符赋值,该函数第二个参数为通配符的索引号,从1开始,有多个通配符时,要多次调用该函数。第三个参数为二进制数据开始指针,第四个参数为二进制数据长度。
sqlite3_bind_blob( stat, 1, pdata, (int)(length_data), NULL );
之后,二进制数据存放到了SQL语句。现在需要调用sqlite3_step()把sqlite3_stmt 结构表示的SQL语句就被写到了数据库里。最后调用sqlite3_finalize()释放sqlite3_stmt 结构的内存。
2、数据的读出是把二进制数据从数据库按照记录读出的过程。该过程在循环中完成,在农业信息采集系统中可以进行图像信息的显示和无线传输。准备sqlite3_stmt* 结构,然后把读数据库的SQL语句解析到sqlite3_stmt 结构中。
sqlite3_prepare( db, “select * from tab”, -1,&stat, 0 );
接着开始循环查询数据,sqlite3_step( )返回SQLITE_ROW表示记录没有结束,否则表示结束。在循环中可获取ID值、二进制数据、二进制数据长度和数据处理,之后释放sqlite3_stmt* 结构内存。
SQLite的特性还体现在它既是一个数据库,一个程序库,一个命令行工具,也是一个学习关系型数据库的很好的工具。确实有很多途径可以把它使用到内嵌环境、网站、操作系统服务、脚本语言和应用程序。对于程序员来说,SQLite就像一个数据传送带,提供了一种方便的将应用程序绑定的数据的方法。
相关推荐
- 精品博文嵌入式6410中蓝牙的使用
-
BluetoothUSB适配器拥有一个BluetoothCSR芯片组,并使用USB传输器来传输HCI数据分组。因此,LinuxUSB层、BlueZUSB传输器驱动程序以及B...
- win10跟这台计算机连接的前一个usb设备工作不正常怎么办?
-
前几天小编闲来无事就跑到网站底下查看粉丝朋友给小编我留言询问的问题,还真的就给小编看到一个问题,那就是win10跟这台计算机连接的一个usb设备运行不正常怎么办,其实这个问题的解决方法时十分简单的,接...
- 制作成本上千元的键盘,厉害在哪?
-
这是稚晖君亲自写的开源资料!下方超长超详细教程预警!!全文导航:项目简介、项目原理说明、硬件说明、软件说明项目简介瀚文智能键盘是一把我为自己设计的——多功能、模块化机械键盘。键盘使用模块化设计。左侧的...
- E-Marker芯片,USB数据线的“性能中枢”?
-
根据线缆行业的研究数据,在2019年搭载Type-C接口的设备出货量已达到20亿台,其中80%的笔记本电脑和台式电脑采用Type-C接口,50%的智能手机和平板电脑也使用Type-C接口。我们都知道,...
- ZQWL-USBCANFD二次开发通讯协议V1.04
-
修订历史:1.功能介绍1.1型号说明本文档适用以下型号: ZQWL-CAN(FD)系列产品,USB通讯采用CDC类实现,可以在PC机上虚拟出一个串口,串口参数N,8,1格式,波特率可以根据需要设置(...
- win10系统无法识别usb设备怎么办(win10不能识别usb)
-
从驱动入手,那么win10系统无法识别usb设备怎么办呢?今天就为大家分享win10系统无法识别usb设备的解决方法。1、右键选择设备管理器,如图: 2、点击更新驱动程序,如图: 3、选择浏览...
- 微软七月Win8.1可选补丁有内涵,含大量修复
-
IT之家(www.ithome.com):微软七月Win8.1可选补丁有内涵,含大量修复昨日,微软如期为Win7、Win8.1发布7月份安全更新,累计为6枚安全补丁,分别修复总计29枚安全漏洞,其中2...
- 如何从零开始做一个 USB 键盘?(怎么制作usb)
-
分两种情况:1、做一个真正的USB键盘,这种设计基本上不涉及大量的软件编码。2、做一个模拟的USB键盘,实际上可以没有按键功能,这种的需要考虑大量的软件编码,实际上是一个单片机。第一种设计:买现成的U...
- 电脑识别U盘失败?5个实用小技巧,让你轻松搞定USB识别难题
-
电脑识别U盘失败?5个实用小技巧,让你轻松搞定USB识别难题注意:有些方法会清除USB设备里的数据,请谨慎操作,如果不想丢失数据,可以先连接到其他电脑,看能否将数据复制出来,或者用一些数据恢复软件去扫...
- 未知usb设备设备描述符请求失败怎么解决
-
出现未知daousb设备设备描述符请求失du败解决办zhi法如下:1、按下Windows+R打开【运行】;2、在版本运行的权限输入框中输入:services.msc按下回车键打开【服务】;2、在服务...
- 读《飘》47章20(飘每章概括)
-
AndAhwouldn'tleaveMissEllen'sgrandchildrenfornotrashystep-patobringup,never.Here,Ah...
- 英翻中 消失的过去 37(消失的英文怎么说?)
-
翻译(三十七):消失的过去/茱迪o皮考特VanishingActs/JodiPicoult”我能做什么?“直到听到了狄利亚轻柔的声音,我才意识到她已经在厨房里站了好一会儿了。当她说话的时候,...
- RabbitMQ 延迟消息实战(rabbitmq如何保证消息不被重复消费)
-
现实生活中有一些场景需要延迟或在特定时间发送消息,例如智能热水器需要30分钟后打开,未支付的订单或发送短信、电子邮件和推送通知下午2:00开始的促销活动。RabbitMQ本身没有直接支持延迟...
- Java对象拷贝原理剖析及最佳实践(java对象拷贝方法)
-
作者:宁海翔1前言对象拷贝,是我们在开发过程中,绕不开的过程,既存在于Po、Dto、Do、Vo各个表现层数据的转换,也存在于系统交互如序列化、反序列化。Java对象拷贝分为深拷贝和浅拷贝,目前常用的...
- 如何将 Qt 3D 渲染与 Qt Quick 2D 元素结合创建太阳系行星元素?
-
Qt组件推荐:QtitanRibbon:遵循MicrosoftRibbonUIParadigmforQt技术的RibbonUI组件,致力于为Windows、Linux和MacOSX提...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)