Page 17 - 《软件学报》2024年第6期
P. 17

陈金宝 等: DBI-Go: 动态插桩定位 Go 二进制的非法内存引用                                             2593


                            S = codeS (code(s l )),G 1 = codeG(code(s l ))  ∃G 2 , addr ∈ S∧addr dst ∈ G 2 .S∧G 1 , G 2
                                                                                                      (5)
                                                         illegal(s l )
                    由于   Go  的地址空间由    Go 堆、全局数据区, 以及所有          Goroutine  的栈组成, 因此, 一个对象若不在当前
                 Goroutine 栈中, 则要么在 Go 堆中, 要么在全局数据区, 要么在其他 Goroutine 栈中. 即:

                               
                                S = codeS (code(s l )),G 1 = codeG(code(s l ))
                               
                                                                                                     (6)
                               
                               
                                 addr dst < S ⇐⇒ addr dst ∈ GH∨addr dst ∈ GG∨(∃G 2 , addr dst ∈ G 2 .S∧G 1 , G 2 )
                    结合公式 (6), 可将公式 (3)、公式 (4)、公式 (5) 合为一个式子, 此时便得到判定违反逃逸不变式的第                      1  条规
                 则, 该规则揭示了栈对象地址被写入当前 Goroutine 栈之外的内存使用违例情况.
                    规则  1. 栈对象地址被写入当前        Goroutine 栈之外的违例判别.

                                                     s l : store addr dst , addr

                                           S = codeS (code(s l ))  addr ∈ S∧addr dst < S
                                                                             .
                                                         illegal(s l )
                    该规则表示将当前       Goroutine 栈的对象地址存入当前       Goroutine 栈外, 导致栈外对象引用栈内对象是不符合
                 Go  的逃逸不变式要求的, 如图       5(a) 所示.

                                   stack.hi           高地址     stack.hi          高地址
                                                                           l
                                                                         深栈帧
                                                       栈                 栈对象
                                                栈帧     增                         栈
                                                                           l
                                                       长                 浅栈帧     增
                                                       方                         长
                                    栈外对象       栈对象     向                 栈对象     方
                                                                           l     向
                                                                 rsp
                                      rsp
                                   stack.lo           低地址     stack.lo          低地址
                                                                         Goroutine
                                              Goroutine  illegal(s l )
                                                                           栈
                                                栈
                                         (a) 栈外对象指向栈对象       (b) 较深栈帧栈对象指向较浅栈帧栈对象
                                                  图 5 规则   1  及规则  2  示意

                    • 将栈对象地址写入当前 Goroutine 栈内的违例情况. 在同一个 Goroutine 栈中, 不同栈对象生命期亦有差距, 比
                 如作用域较浅的栈对象比作用域深的栈对象生命期长, 较深函数栈帧中的栈对象比较浅函数栈帧中的栈对象生命期
                 长. 由于在二进制中已经难以看到源代码层级的作用域, 此处只能通过栈对象所在函数栈帧的深浅来判断其生命期,
                 认为较深栈帧栈对象生命期更长, 如图           5(b) 所示. 由此可以引出判定违反逃逸不变式的第             2  条判定规则, 即规则   2.
                    规则  2. 栈对象地址被写入当前 Goroutine 栈内的违例判别.

                                                     s l : store addr dst , addr

                                  S = codeS (code(s l ))  addr ∈ S∧addr dst ∈ S∧ fd(addr) < fd(addr dst )
                                                                                      .

                 3   DBI-Go 的设计与实现

                    本节将介绍     DBI-Go, 一款用于识别    Go  二进制中写入指针的       store 指令并在运行时验证其是否违反          Go  逃逸
                 不变式的工具的具体设计与实现.

                 3.1   设计目标和设计思路
                    DBI-Go  的设计目标主要包括以下几点.
   12   13   14   15   16   17   18   19   20   21   22