Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: minimally align variables in memory when -d=checkptr is used #35128

Open
mdempsky opened this issue Oct 24, 2019 · 2 comments

Comments

@mdempsky
Copy link
Member

@mdempsky mdempsky commented Oct 24, 2019

-d=checkptr should report a warning for:

var x [4]byte
p := (*uint32)(unsafe.Pointer(&x[0]))

In general, this is unsafe because x only requires 1-byte alignment, but *uint32 requires 4-byte alignment.

Currently, this isn't reliably reported, because efficiently allocating variables often results in over alignment. But when -d=checkptr is in use, cmd/compile and the runtime could burn a few bytes of memory to intentionally minimally align things in the heap and on the stack (e.g., 1-byte-alignment variables always on an odd address).

Relatedly, when the runtime allocates a chunk of memory for a heap variable allocation, it could align the variable as close to the end of the allocation (rather than at the beginning), so that we can more easily detect pointer arithmetic overflows (at the expense of pointer arithmetic underflows, which seem less common).

These both would have helped catch issues that I've noticed in CLs to address errors reported by -d=checkptr.

(Prior art: I think OpenBSD's malloc used to prefer aligning allocations towards the end of an mmap'ed page so that buffer overflows were more likely to trigger a segmentation fault. Not sure if it still does that. I don't see it mentioned specifically in the man page.)

@mdempsky

This comment has been minimized.

Copy link
Member Author

@mdempsky mdempsky commented Oct 24, 2019

Hrm:

go/src/runtime/malloc.go

Lines 889 to 904 in 68981bf

// TODO(austin): This should be just
// align = uintptr(typ.align)
// but that's only 4 on 32-bit platforms,
// even if there's a uint64 field in typ (see #599).
// This causes 64-bit atomic accesses to panic.
// Hence, we use stricter alignment that matches
// the normal allocator better.
if size&7 == 0 {
align = 8
} else if size&3 == 0 {
align = 4
} else if size&1 == 0 {
align = 2
} else {
align = 1
}

@mdempsky mdempsky modified the milestones: Go1.14, Backlog Nov 12, 2019
@mdempsky

This comment has been minimized.

Copy link
Member Author

@mdempsky mdempsky commented Nov 12, 2019

Bumping to Backlog, since I don't think this is going to happen for Go 1.14.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.