Abstract
LTL反置可行且可以给出数学证明,CTL反置就困难的多。为了探索反置,本次选取了AutoTap没考虑的Action Breaking进行探索。虽然反置在这类漏洞中不可行,但是提出了一种可行的修复方法并用例子进行了证实。
由于实际规则执行过程中的一些特性(1.5.3节 特性),Action Breaking会产生多方面的影响(1.5.3节 举的例子)。这些特性和影响使得在Action breaking中存在一个特别的时间区域。想要修复Action breking,达到正常运行的预期效果,就是要消除这块区域。提出了一种对应的修复方法,并在米家和状态机中进行试验,给出了修复的效果,说明了可行性,并分析了这种修复方式的特点。
一、AutoTap没考虑的Action Breaking案例分析
案例 When alarm siren,turn on fan for 15 minutes
1.1 Action Breaking对应的LTL safety property
G! (runinfan61.timer=2 & fan.switchCap.switch = off)
1.2 该safety property的3种自然语言描述:
The fan should’t be interrupted when working under the alarm state /
The fan shall have enough time to clear smoke under the alarm state /
The smoke was finally cleared by the fan
1.3 根据反例路径推导对应的场景
Action Breaking前的场景:
首先室内wet,触发fan on。在室内wet触发的fan on快要结束的时候,alarm siren并触发fan on,人听到alarm之后present并再次触发fan on。由于室内wet触发的fan on快要结束,fan off,没有吹够alarm siren对应的时间,室内烟雾情况无法彻底改善。
Action Breaking后的场景:
室内又wet了,然后又重复上述冲突过程,只是alarm siren的时间更晚了。
1.4 验证推导的场景是否实际存在:
由于设备条件有限,用门窗传感器打开和关闭这两个不同的trigger分别模拟If wet、If alarm siren。用插座开关一段时间模拟fan开关一段时间
Rule1:如果门窗传感器打开,则打开插座10s后关闭 (模拟If wet,then fan on一段时间后关闭)
Rule2:如果门窗传感器关闭,则打开插座10s后关闭 (模拟If alarm siren,then fan on一段时间后关闭)
Action breaking发生在第10s,第10s的Rule1关闭插座操作会提前结束Rule2在5-15s的预期执行,所以nusmv提供的反例实际存在。
实际执行效果:
|——————————————————|——————————————————|——————————————————|
0s 5s 10s 15s
门窗传感器:
开门(wet) 关门(siren)
插座:
开1 开2(没效果) 关1(发生break) 关2(没效果)
1.5 Action Breaking修复方法
1.5.1 第一种修复方法:推迟执行(待解决)
阻止不了event trigger的发生(所以不能改变之前的状态),但是可以推迟action的执行。本例中的alarm fan不能推迟,要立刻进行吹烟雾。
1.5.2 第二种修复方法:用于解决Devices dependent on past status(待解决)
Devices not dependent on past status: 如插座,即插座在当前工作中不会使用到上一次工作的信息。所以,如果插座被Action Breaking后立刻打开运行,不会造成影响。
1.5.3 第三种修复方法: 新建TAP规则来修复
在修复前要考虑的特性1:用TAP规则来修复的局限性
目前并没有查询设备还有多久执行完毕的TAP规则,只能设置固定的执行时间而不是一个根据具体场景变化的值。米家没有类似打开风扇直到烟雾clear这种直到类型的操作。
解决方法:比如HA中的模式,等待条件触发;其它平台的 If trigger和 When trigger
在修复前要考虑的特性2:只trigger一次,定期trigger 还是 一直trigger?
比如TAP规则: 如果温度大于20度,则打开插座10s后关闭。这条规则只会在温度由20度以下变为20度以上时才会触发,如果之后温度保持在20度以上,这条规则并不会再次执行,属于只trigger一次。
下面用两个例子说明该问题可能造成的影响。When alarm siren,turn on fan for 15 minutes。由于smoke的存在,这个规则的trigger可能会反复触发,即使被打断一次,后续依然可能执行成功。
但是比如室外监控探头的TAP规则是当室外夜间检测到入侵者,就将vedio上传至cloud。如果入侵则出现一次就跑了,那么这个规则的trigger只会触发一次,意味着如果vedio上传过程中被action break并且没有修复措施,那么就真的失败了。
在修复前要考虑的特性3: Rule有效期内意外关闭
回顾前面这个例子。如果在10-15s内打开插座,由于此时还在Rule2的有效期,那么在15s时会按照规则意外地关闭插座,这是个普遍的现象。不过经实验,现有smv中已经模拟了这种情况,比如fan on 后下一状态因为runinfan61.timer = 1,fan变为off。
实际执行效果:
|——————————————————|——————————————————|——————————————————|
0s 5s 10s 15s
门窗传感器:
开门(wet) 关门(siren)
插座:
开1 开2(没效果) 关1(发生break) 关2(没效果)
在修复前要考虑的特性4 : 更新间隔
比如小米温湿度计2约5min左右在米家更新数值。举一个例子说明更新间隔造成的直观影响,现有一条规则:如果温度大于20度,打开插座十秒后关闭。由于更新间隔的存在,即使当前温度为21度,也需要等到5min后更新了才会触发。A device’s state at a platform is updated by the device’s latest event。Inconsistency。设备的状态和平台对设备状态的观察结果不一致。
另一个影响例子是在之前例子中加入更新间隔。
假设规则只trigger一次。
在第10s发生action breaking后,由于规则只trigger一次,10s-15s内不会再trigger。在10s-15s原本应该fan on,但是由于第10s发生了Action breaking,10s-15s fan处于off状态。
实际执行效果:
|——————————————————|——————————————————|——————————————————|
0s 5s 10s 15s
门窗传感器:
开门(wet) 关门(siren)
插座:
开1 开2(没效果) 关1(发生break) 关2(没效果)
fan on的时间段:
|——————————————————|——————————————————|
fan off的时间段:
|———————————————————|
假设规则在更新间隔的时候定期trigger。
假设smoke探测器的更新间隔是8s,那么在5s更新smoke并触发规则后,下一次更新smoke是在13s并会再次触发规则,再下一次更新在21s并会再次触发规则。由于更新间隔的存在,本例中在第10s Action Breaking发生后,只有10s-13s是fan off,13s-15s是fan on的。
实际执行效果:
|——————————————————|——————————————————|————————————|——————|————————|————|——————————————|
0s 5s 10s 13s 15s 21s 23s 31s
trigger:
wet 第1次更新smoke并siren 第2次smoke 第3次smoke
fan:
on1 on2 off1(发生break) on3 off2 on4 off3 off4
fan on的时间段:
|——————————————————|——————————————————| |——————| |————|
fan off的时间段:
|————————————| |————————| |——————————————|
提出空白区的概念:
Action breaking开始(例子中是10s) 和 正常运行达到效果的时间(例子中是15s) 之间的未正常工作的时间片段。
这段区域的存在,使得在第10s的Action Breaking后,不能及时吹散烟雾。而且在fan off的时间段烟雾可能会加重,即使fan断断续续吹了足够长时间,也无济于事。
只trigger一次的空白区:
|————————————————————|
10s 15s
定期trigger的空白区:
|————————————|
10s 13s
基于以上分析,提出修复方法
想要修复,即达到正常运行的预期效果,就是要消除这一段空白区。
第一步:从反例路径中找到Action Breaking的原因
off上一状态是Action Breaking的原因,结合现有TAP规则runinfan27.timer = 1:=0可以得到原因。或者off向上找到最近的on,
结合现有TAP规则,on前一个状态是原因。根据找到导致Action Breaking的action,可以结合现有TAP规则分析预期效果。
第二步:新增TAP规则消除空白区
当fan被Action Breaking时,立刻重新打开fan让它继续吹烟雾。
trigger: fan = off & smoke大于某个阈值(如smoke大于执行后的效果clear的判定值) ,两个合一块说明发生了Action Breaking
action:fan on对应的alarm siren时间,发送一个notification提醒用户视情况做应对措施
如果是运行固定时间还不够好,可以选择运行充足时间加一条until的TAP rule,比如当smoke clear,turn off
第三步:用nusmv验证修复的正确性
方法局限
局限: 这种修复方式并没有解决G! (runinfan61.timer=2 & fan.switchCap.switch = off) ,状态机里仍会有该状态。
解决局限: 考虑在原LTL语句的基础上形成新的LTL属性进行验证,新属性在原模型为false,在修复后的模型为true即为修复成功。比如G ((runinfan61.timer = 2 & fan.switchCap.switch = off) -> F (runinfan61.timer = (4-2) & fan.switchCap.switch = on))
二、第三种Action Breaking解决方法的米家实验
2.1 实验目的:解决之前这个例子中的Action Breaking
实际执行效果:
|——————————————————|——————————————————|————————————|——————|————————|————|——————————————|
0s 5s 10s 13s 15s 21s 23s 31s
trigger:
wet 第1次更新smoke并siren 第2次smoke 第3次smoke
fan:
on1 on2 off1(发生break) on3 off2 on4 off3 off4
fan on的时间段:
|——————————————————|——————————————————| |——————| |————|
fan off的时间段:
|————————————| |————————| |——————————————|
空白区:
|————————————|
2.2 Experiment Setup——TAP规则设置
Rule1 模拟 If wet,then fan on一段时间
Rule2、Rule3 模拟 If alarm siren,then fan on一段时间
Rule4 是新建的修复规则。“当任一触发” 中写入关电源模拟fan off,“且满足全部状态中” 写入高于25度模拟smoke高于某个阈值。action中,首先发送notification,之后开电源10s后关闭模拟打开fan运行一段时间。
2.3 实验结果
第一次实验只开Rule1、Rule2、Rule3模拟修复前,如图里的预期执行
修复前执行效果:
|——————————————————|——————————————————|————————————|——————|————————|————|——————————————|
0s 5s 10s 13s 15s 21s 23s 31s
trigger:
wet 第1次更新smoke并siren 第2次smoke 第3次smoke
fan:
on1 on2 off1(发生break) on3 off2 on4 off3 off4
fan on的时间段:
|——————————————————|——————————————————| |——————| |————|
fan off的时间段:
|————————————| |————————| |——————————————|
空白区:
|————————————|
第二次实验打开修复规则Rule4模拟修复后
5s-15s正常运行,空白区消除了
修复后执行效果:
|——————————————————|——————————————————|————————————|——————|——————|——|————|——————————————|
0s 5s 10s 13s 15s 20s 21s 23s 31s
trigger:
wet 第1次更新smoke并siren 触发修复规则 第2次smoke 21s第3次smoke
20s修复规则结束
fan:
on1 on2 off1(发生break) on3 off2 on4 off3 off4
但由于修复规则
马上恢复on 20s由于修复规则off
fan on的时间段:
|——————————————————|——————————————————|————————————————————| ...
空白区:消除了
2.3 实验分析
这种修复方式不受再次被Action Breaking 或者 特性3的影响
如果在执行修复规则时再次被打断,不会受影响,因为只要off且有smoke就依然会触发修复规则继续执行,直到smoke clear。特性3导致的关闭插座会被修复规则立刻修正,所以不会影响修复。
后续修复规则结束问题
最好是把相关的属性都设置一个类似的TAP规则
三、第三种Action Breaking解决方法的smv实验
3.1 修复
G ((runinfan61.timer = 2 & fan.switchCap.switch = off) -> F (runinfan61.timer = 1 & fan.switchCap.switch = on))会判断所有包含(runinfan61.timer = 2 & fan.switchCap.switch = off)的路径(没有的会判定为True)最终能否正常运行fan,只要有一个不满足,整条属性就不满足。把不处理的,错误处理的,没有的情况都处理,只有当所有路径被修复,整个系统才安全
next(fan.switchCap.switch):=
case
--fix放在前模拟修复规则的“强制性”
--模拟当action break就on
runinfan61.timer=2 & fan.switchCap.switch = off:on;
--模拟执行空白期过程中任何打断都会被立刻恢复
runinfix.timer > (4-2) & (fan.switchCap.switch = off | next(runinfan61.timer)=1 | next(runinfan27.timer)=1 | next(runinfan12.timer)=1):on;
--模拟修复规则的关闭操作
runinfix.timer = 1 & fan.switchCap.switch = on:off;
其他实验属性(有bug)不用看:
G ((runinfan61.timer = 2 & fan.switchCap.switch = off) -> !( F (runinfan61.timer = 2 & fan.switchCap.switch = on)))
– specification G ((runinfan61.timer = 2 & fan.switchCap.switch = off) -> F ((runinfan61.timer = 2 & fan.switchCap.switch = on) | runinfan61.timer != 4)) is true
– specification G ((runinfan61.timer = 2 & fan.switchCap.switch = off) -> F runinfan61.timer != 4) is true
!( G ((runinfan61.timer = 2 & fan.switchCap.switch = off) -> F (runinfan61.timer = 1 & fan.switchCap.switch = on)))不会出现runinfan61.timer = 2 & fan.switchCap.switch = off,只会单独属性
!(( O (runinfan61.timer = 2 & fan.switchCap.switch = off)) U (runinfan61.timer = 1 & fan.switchCap.switch = on))
!( F ((runinfan61.timer = 1 & fan.switchCap.switch = on) S (runinfan61.timer = 2 & fan.switchCap.switch = off))),S的状态出的全
!( F (smoke = clear S (runinfan61.timer = 2 & fan.switchCap.switch = off)))
出现调换case顺序的 !( F ((runinfan61.timer = 1 & fan.switchCap.switch = on & delayfan27!=4) S (runinfan61.timer = 2 & fan.switchCap.switch = off)))
fix后,!( F ((runinfan61.timer = 1 & fan.switchCap.switch = on) S (runinfan61.timer = 2 & fan.switchCap.switch = off)))
再次fix后,!( F ((runinfan61.timer = 1 & fan.switchCap.switch = on & delayfan27!=4 & delayfan12!=4) S (runinfan61.timer = 2 & fan.switchCap.switch = off)))
3.2 实验结果
未修复前fan.smv为false
修复后的fix.smv为true