SQLancer,用于自动测试DBMS以查找逻辑错误的工具

2020-06-07 15:21:05

SQLancer(合成查询Lenger)是一个自动测试数据库管理系统(DBMS)以查找其实现中的逻辑错误的工具。我们将逻辑错误称为那些导致DBMS获取错误结果集(例如,通过省略记录)的错误。

数据库生成:此阶段的目标是创建已填充的数据库,并向DBMS施加压力,以增加导致可随后检测到的不一致数据库状态的可能性。首先,创建随机表。然后,随机选择SQL语句来生成、修改和删除数据。其他语句,例如用于创建索引和视图以及设置特定于DBMS的选项的语句,也会发送到DBMS。

测试:此阶段的目标是基于生成的数据库检测逻辑错误。请参阅下面的测试方法。

要测试的DBMS(SQLite是嵌入式DBMS,包含在内)。

以下命令克隆SQLizer,创建一个JAR,并启动SQLancer以使用三元逻辑查询分区(TLP)对SQLite进行模糊处理:

Git克隆https://github.com/sqlancer/sqlancercd sqlancermvn包目标java-jar SQLancer-0.0.1-SNAPSHOT.jar--num_threads16--num_tries 5--max_expression_深度3--num_query 100000--max_num_insert 30 sqlite3--oracle查询分区。

如果执行每五秒打印一次进度信息,则该工具将按预期工作。请注意,SQLancer可能会在SQLite中发现错误。在报告这些内容之前,请确保在使用最新开发版本时仍然可以复制它们。

由于我们收到了极大的兴趣,我们正在考虑将我们的缺陷查找工作商业化。如果您代表一家公司并对漏洞查找服务感兴趣,请与我们(Manuel Rigger和苏振东)联系,告知您对此类服务的期望和要求。

在这个阶段,这个项目仍然应该被视为一个研究原型。我们认为该工具还没有准备好投入使用。然而,我们收到了公司、组织和个人开发人员的许多请求,这就是为什么我们决定过早发布该工具的原因。预计会出现错误、不兼容、缺少文档和代码质量不足。也就是说,我们正在努力解决这些问题,并将SQLancer提升为生产质量的软件。我们欢迎任何问题报告、扩展请求和代码贡献。

PQS是我们设计和实现的第一个技术。它随机选择一个称为透视表行的行,为该行生成一个保证提取该行的查询。如果该行未包含在结果集中,则已检测到错误。这里有详细的描述。PQS是最强大的技术,但也比其他两种技术需要更多的实现工作。它目前没有得到维护。

NoREC的目标是找到优化错误。这里有描述。它将DBMS可能优化的查询转换为几乎不适用任何优化的查询,并比较两个结果集。结果集之间的不匹配表示DBMS中存在错误。

TLP将一个查询划分为三个分区查询,它们的结果被组合起来,并与原始查询的结果集进行比较。结果集中的不匹配表示DBMS中存在错误。与NoREC和PQS相比,它可以检测聚合函数等高级功能中的错误。

此实现目前受到仍需调查的重大性能回归的影响。

这个DBMS的实现是非常初步的,因为除了我们的一个错误报告之外,我们在所有的错误报告都被解决之后停止了扩展。运行它可能会发现更多未报告的错误。

实现不同的表引擎并不方便,这就是为什么只有非常初步的实现存在的原因。

我们删除了TDEngine实现,因为除了一个错误报告之外,所有的错误报告在我们报告五个月后仍然没有得到解决。

Eclipse代码格式化程序,以确保一致的格式化(运行MVN Formatter:Format以格式化所有文件)。

我们计划很快添加配置项以自动检查PR。随后,我们还计划为每个DBMS添加冒烟测试,以测试各自的测试实现没有明显损坏,请参见此处。

SQLancer目前没有测试套件。我们发现,在测试DBMS时,SQLancer中的错误可以快速发现,并且易于调试。PQS实现有一个测试套件,该测试套件在提交36ede0c0c68b3856e03ef5ba802a7c2575bb3f12中被删除。

SQLancer将日志存储在target/logs子目录中。默认情况下,选项--log-each-select处于启用状态,这会导致记录发送到DBMS的每条SQL语句。相应的文件名以-cur.log作为后缀。此外,如果SQLancer检测到逻辑错误,它会创建一个扩展名为.log的文件,其中记录了再现错误的语句。

在发现错误之后,在报告错误之前生成一个最小的测试用例是很有用的,这样可以节省DBMS开发人员的时间和精力。对于许多测试用例,C-Reduce做得很好。此外,我们一直在开发一个特定于SQL的缩减器,我们计划很快发布该缩减器。

如果您在报告SQLancer发现的错误时提到它,我们将不胜感激。我们也很想知道您是否正在使用SQLancer来查找bug,或者您是否已经将其扩展到测试另一个DBMS(如果您不打算将其贡献给这个项目)。SQLancer在广泛使用的DBMS中发现了400多个错误,此处列出了这些错误。

DuckDB实现为新实现提供了一个很好的模板。DuckDBProvider类是管理数据库创建和执行所选测试Oracle的中心类。尝试为您想要实现的新DBMS复制它的结构,并从生成数据库开始(不实现测试Oracle)。作为这项工作的一部分,您还需要实现等效的DuckDBSchema,它表示生成的数据库的数据库模式。成功生成数据库后,下一步是生成其中一个测试Oracle。例如,您可能希望实现NoREC(请参见DuckDBNoRECOracle或DuckDBQueryPartitioningWhere Tester for TLP)。作为其中的一部分,您还必须实现一个随机表达式生成器(参见DuckDBExpressionGenerator)和一个访问器来派生表达式的文本表示(参见DuckDBToStringVisitor)。

使用Eclipse开发SQLancer预计会工作得很好。您只需一步即可导入SQLancer:

File->;Import->;Existing Maven Projects->;选择SQLizer目录作为根目录->;Finish。

如果您没有找到导入Maven项目的选项,您可能需要安装M2Eclipse插件。

我们已经创建了一个松弛工作区来讨论SQLancer和一般的DBMS测试。SQLancer的官方Twitter账号是@sqlancer_dbms。

有关我们的DBMS测试工作和我们发现的错误的更多信息,请单击此处。