Skip to content

Syscall in getTermSize() corrupts package variable of a different library #38

@VoIdemar

Description

@VoIdemar

Hi.

I am developing a CLI application which uses uilive v0.0.4 to output execution statistics to the console at runtime. Everything was fine until I decided to use sniper as a key-value storage for my app. It turned out that one of the sniper package variables got corrupted (changes it's value from 12 to 0) after calling uilive.New(). Without calling uilive.New() sniper works perfectly fine.

I traced the issue down to the IOCTL syscall in getTermSize() function in terminal_size.go:

//...
var sz windowSize

func getTermSize() (int, int) {
       //...
       // `sniper` package variable is fine here
	_, _, _ = syscall.Syscall(syscall.SYS_IOCTL,
		out.Fd(), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sz)))
        // `sniper` package variable is reset to 0 
	return int(sz.cols), int(sz.rows)
}Ubuntu 20.04 LTS x64

I am not sure what goes wrong exactly, but it looks like using an unsafe.Pointer to the sz package variable somehow messes up the memory contents. I can't say if any other package variables are affected.

I managed to fix the issue by simply moving package variables from terminal_size.go into the getTermSize() function body, making them local (and they kinda should be local, there are no usages of them outside of terminal_size.go):

// +build !windows

package uilive

import (
	"os"
	"runtime"
	"syscall"
	"unsafe"
)

type windowSize struct {
	rows    uint16
	cols    uint16
}

func getTermSize() (int, int) {
	var (
		out *os.File
		err error
		sz  windowSize
	)
	if runtime.GOOS == "openbsd" {
		out, err = os.OpenFile("/dev/tty", os.O_RDWR, 0)
		if err != nil {
			return 0, 0
		}
	} else {
		out, err = os.OpenFile("/dev/tty", os.O_WRONLY, 0)
		if err != nil {
			return 0, 0
		}
	}
	_, _, _ = syscall.Syscall(syscall.SYS_IOCTL,
		out.Fd(), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sz)))
	return int(sz.cols), int(sz.rows)
}

What do you think? Please help me out.

Env specs:

OS Ubuntu 20.04 LTS x64
Kernel 5.7.7-050707-generic
Go 1.15.7

PR: #39

P.S.: big thanks for the library, it's awesome :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions