您的位置:首页 > 编程语言 > Go语言

【go语言】wait,why not safe

2017-02-07 22:51 423 查看
slice?俺知道,不就是基于数组的一个视窗嘛!
出个题呗~
好~

package main

func main() {
var arr = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s := arr[2:6]

modify(s)
}

func modify(tmp []int) {
// 实现该函数,把arr[8]的值修改为200
}

你千万别告诉我是这样实现的:
var point = &tmp[3]
point += 3
*point = 200
这样做你真的可费瞎了心了 :)
因为golang指针不允许运算,像这样会抛invalid operation: point += 3 (mismatched types *int and int)错误~~~

算了吧,还是放着让哥来



浅蓝色的是slice当前的长度,整个蓝色(浅蓝色+深蓝色)是slice的容量
站在从slice的视窗来看当前能看到{2,3,4,5},但如果扩大slice的容量就可以看到{2,3,4,5,6,7,8,9},从slice的意义上来看,由slice可以修改数组的arr[8]。

(1)获取s[3]的地址,即arr[5]的地址
&s[3]
(2)把s[3]的地址转换为不安全的指针
unsafe.Pointer(&s[3])
(3)把s[3]不安全的指针转换为uint地址
uintptr(unsafe.Pointer(&s[3]))

(4)把指针向后移3个元素
var nextElement = uintptr(unsafe.Pointer(&s[3])) + 3 * 8 // 我怎么知道每个int占8个字节,可以用unsafe.Offsetof查看

(5)把目标元素的uint地址转换为不安全的指针
unsafe.Pointer(nextElement )
(6)把目标元素的不安全指针转换为地址
(*int)(unsafe.Pointer(nextElement ))

(7)修改目标元素的值
*(*int)(unsafe.Pointer(nextElement )) = 200

完整的程序如下:
package main

import "fmt"
import "unsafe"

func main() {
var arr = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s := arr[2:6]

modify(s)

fmt.Println(arr)
}

func modify(tmp []int) {
var src = uintptr(unsafe.Pointer(&tmp[3]))
var dest = (*int)(unsafe.Pointer(src + 3*8))
*dest = 200
}
执行一下结果为:
[0 1 2 3 4 5 6 7 200 9]

所以尽管只是slice了数组的一部分,并且没有扩容,攻击者只是通过对slice的操作,依旧可以攻到底层数组不可见的元素,从安全编码角度来看,这是一个安全隐患 :)

关于slice的一些知识,我想做一个动画,从视窗的维度再解释一下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unsafe slice golang