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

Calling an ioctl_none! with unflushed stdout leads to uninitialized memory access. #2159

Open
rvvvr opened this issue Oct 5, 2023 · 3 comments

Comments

@rvvvr
Copy link

rvvvr commented Oct 5, 2023

Calling an ioctl defined by ioctl_none! has a chance to access some memory it shouldn't when preparations have been made to push a buffer to stdout (specifically the length of the buffer) without flushing. For example:

// example from kvm bindings I've been writing. vcpu,run() is a pure wrapper around the KVM_RUN ioctl, with that very ioctl being the first function it calls.
print!("abcdefghijklmnop");
vcpu.run().unwrap();

strace output from the above example:

ioctl(5, KVM_RUN, 0x10) = -1 EINVAL (Invalid Argument) //same length as that string above...

but, when explicitly flushing the buffer...

print!("abcdefghijklmnop");
std::io::stdout().flush().unwrap();
vcpu.run().unwrap();

strace output now:

write(1, "abcdefghijklmnop", 16abcdefghijklmnop) = 16
ioctl(5, KVM_RUN, 0) = 0

this is explicitly a problem when emulating, for example, uart serial communication with KVM, as it's pretty common practice to throw out characters 1 by 1 as you receive them. this should be (in theory) as simple to fix as explicitly passing 0 to ioctl calls in ioctl_none*! macros.

@asomers
Copy link
Member

asomers commented Oct 5, 2023

"passing 0 to ioctl calls" for what argument? Have you done cargo expand to look at the generated code?

@rvvvr
Copy link
Author

rvvvr commented Oct 5, 2023

I have! The macro right now expands out to a call to ioctl leaving the first vararg unspecified. This (as I understand it) is incorrect, given that glibc will look for one vararg whether or not it should, and leads to grabbing some arbitrary value off of the stack as that third argument.

@asomers
Copy link
Member

asomers commented Oct 5, 2023

The docs say that KVM_RUN has no arguments. But the only example I can find with its use provides an argument of zero. Maybe you need to define it with ioctl_write_int_bad! and provide that argument when you call it.
https://github.com/rminnich/vmtool/blob/31cf14e56896aee4546a63e3bc7b911174362430/kvm-cpu.c#L34

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants