Page MenuHomeFreeBSD

devstat: Provide 32-bit compatibility
Needs ReviewPublic

Authored by des on Thu, Jan 8, 12:34 AM.
Tags
None
Referenced Files
F141921086: D54591.id169288.diff
Mon, Jan 12, 1:30 PM
Unknown Object (File)
Sat, Jan 10, 5:05 AM
Unknown Object (File)
Sat, Jan 10, 4:34 AM
Unknown Object (File)
Fri, Jan 9, 7:08 PM
Unknown Object (File)
Thu, Jan 8, 6:57 PM
Unknown Object (File)
Thu, Jan 8, 3:40 PM
Unknown Object (File)
Thu, Jan 8, 4:12 AM
Unknown Object (File)
Thu, Jan 8, 3:58 AM
Subscribers

Details

Reviewers
brooks
kib
imp
Summary

If a 32-bit process running on a 64-bit kernel requests kern.devstat.all,
translate each struct devstat to its 32-bit equivalent before copying it
out.

Also fix a bug where an early error would be ignored if there were no
devices to report.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 69746
Build 66629: arc lint + arc unit

Event Timeline

des requested review of this revision.Thu, Jan 8, 12:34 AM
sys/kern/subr_devstat.c
405
406

There should be a blank line after this one.

429
433

The comment is rather obvious, I do not see much sense in adding it.

435

A blank line is needed after this one.

446

This (and all other 64bit types) must account for BE/LE.

des marked 5 inline comments as done.Fri, Jan 9, 10:56 AM
des added inline comments.
sys/kern/subr_devstat.c
446

Why? We don't support running LE binaries on a BE kernel or vice versa.

sys/kern/subr_devstat.c
446

I was too terse/assumed something.

Problem is that it is not quite possible to use uint64_t for definitions of the 32bit ABI structures. The type has different alignment on 32bit vs 64bit ABI e.g. on x86, 4 bytes on i386 vs 8 bytes on amd64. Our man page states that this is true for all other arches except arm, but I just looked at the linux ABI for ppc, where it is 8 bytes for both, at least for Linux ABI.

So, we have to use pair of uint32_t's when passing 64bit int to 32bit ABI process. Look at all places in e.g. freebsd32_misc.c. And then, we have to handle the word order BE vs LE.

sys/kern/subr_devstat.c
446

We don't have to handle the word order. BT_CP() just used a cast to treat the pair of uint32_t as a single uint64_t, assuming that alignment doesn't matter. I changed struct bintime32 to __packed which removes the need for using a pair of uint32_t, and the need for a cast. Likewise, struct devstat32 is __packed and works fine. Of course, this would _not_ have worked if armv7 or i386 versions of struct devstat had included padding, but they don't; all their members have sizes divisible by four.

sys/kern/subr_devstat.c
446

Using __packed is not correct, since some arches align uint64_t to 8 bytes, for instance ppc.

And, accessing unaligned uint64_t is UB.

Please look how this stuff is handled for the whole freebsd32_misc.c.

sys/kern/subr_devstat.c
446

The original code was already doing unaligned accesses for struct bintime32.

sys/kern/subr_devstat.c
446

Where?

bintime32 by itself is fine, it is using two int32's.

I looked at freebsd32.h, and there is a problematic handling of ffclock_estimate32, but even this is not related to bintime32 as is. I will fix this eventually.

des marked 4 inline comments as done.Sun, Jan 11, 2:15 PM
des added inline comments.
sys/kern/subr_devstat.c
446

Look at the BT_CP() macro in <sys/abi_compat.h>.

des marked an inline comment as done.Sun, Jan 11, 2:15 PM
sys/kern/subr_devstat.c
446

So it is UB. D54663