【问题标题】:Go, FreeBSD, iovec and syscallsGo、FreeBSD、iovec 和系统调用
【发布时间】:2020-12-09 02:54:17
【问题描述】:

我一直在尝试对 FreeBSD 的 jail_set 进行系统调用,但没有成功。

它在接收系统调用时使用 iovec 数组,但总是返回“错误地址”。

这是创建 IOVEC 的部分代码:

func (p Params) buildIovec() ([]unix.Iovec, error) {
    iovSize := len(p) * 2
    iovec := make([]unix.Iovec, iovSize)
    var itr int
    for paramKey, paramValue := range p {
        arrayParamKey := []byte(paramKey)
        // Adds a nullbyte
        // Jail parameters are passed as an array   
        // of name-value pairs in the array iov, containing niov
        // elements.    Parameter names are a null-terminated
        // string, and values may be strings, integers, 
        // or other arbitrary data.
        // Ref: https://www.freebsd.org/cgi/man.cgi?query=jail&sektion=3&manpath=FreeBSD+11.1-stable
        arrayParamKey = append(arrayParamKey, 0)
        size := len(arrayParamKey)

        iovec[itr] = unix.Iovec{
            Base: (*byte)(unsafe.Pointer(&arrayParamKey)),
            Len:  uint64(size),
        }
        itr++

        rv := reflect.ValueOf(paramValue)
        var arrayValueBytes []byte
        switch rv.Kind() {
        case reflect.String:
            arrayValueBytes = []byte(rv.String())
            arrayValueBytes = append(arrayValueBytes, 0)
            if err != nil {
                return nil, err
            }
        default:
            return nil, errors.New("invalid value passed in for key: " + paramKey)
        }

        arrayValueSize := len(arrayValueBytes)
        iovec[itr] = unix.Iovec{
            Base: (*byte)(unsafe.Pointer(&arrayValueBytes)),
            Len: uint64(arrayValueSize),
        }
        itr++
    }
    return iovec, nil
}

然后调用系统调用:

    _, _, e1 := unix.Syscall(uintptr(call), uintptr(unsafe.Pointer(&iov)), uintptr(len(iov)), flags)

其中 call 代表 jail_set int 507,flags 是 1 的 uintptr(代表 CREATE)。

另外,Params 是一个 map[string]interface{},其中键是 jail 配置的键,值是配置的值(这解释了 buildIovec 中的循环)。

这是基于https://github.com/briandowns/jail,但我一直在更改一些内容以查看它是否有效。

谢谢。

【问题讨论】:

    标签: go freebsd


    【解决方案1】:

    您的值是传递字节片的片头地址,而不是实际字节的开始地址。

    []byte(rv.String()) 将创建一个小切片头。

    unsafe.Pointer(C.CString(rv.String())) 可能会让您更接近工作代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 2016-03-26
      • 2016-05-31
      • 2020-05-03
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      相关资源
      最近更新 更多