Closed pcmoore closed 6 years ago
I still need to look at this a bit more, but I suspect the solution is going to require a second version of ipv6_renew_options() which can operate safely on kernel allocated option data. It is unclear if it is easier to provide a limited implementation specific to CALIPSO (we do something somewhat similar for CIPSO) or if we should provide a generic implementation that could live in net/ipv6/exthdrs.c.
@hdmdavies is the original author of this code, but he may not be actively monitoring this account. I'm including him on the off chance he wants to be involved in the fix.
Alternatively, another option might be to move the copy_from_user() call out of ipv6_renew_option() and up into do_ipv6_setsockopt() as that appears to be the only other user of the ipv6_renew_option() function.
Alternatively, another option might be to move the copy_from_user() call out of ipv6_renew_option() and up into do_ipv6_setsockopt() as that appears to be the only other user of the ipv6_renew_option() function.
It appears there is some precedence for calling copy_from_user() in do_ipv6_setsockopt().
I think I'm going to give up on moving the copy_from_user() call as that is always going to result in an extra copy in the common (non-CALIPSO) case. While it's far from the critical path, it's stuff like that which the netdev folks love to reject.
I'm currently investigating how ugly it would be to add a CALIPSO specific version of ipv6_renew_options().
It looks like that is going to be a poor option too; more investigation is needed.
Completely untested, but here is my first attempt at a fix: https://github.com/pcmoore/misc-linux_kernel/commit/489a9f72a156657a97efdf3dca050769a3bf0328.
I'm currently building a test kernel RPM via COPR in case anyone wants to try it out.
Initial testing is proving positive. The system is able to demonstrate basic functionality and both the selinux-testsuite and audit-testsuite pass with no kernel warnings/panics.
Patch posted to netdev upstream:
Follow on revision posted to netdev upstream:
... and a v2 of the follow on because the 0-day test robot found a mistake (a rather foolish mistake I might add):
Resolved with commit a9ba23d48dbc6ffd08426bb10f05720e0b9f5c14 that was included in v4.18.
While running tests with the selinux-testsuite, a kernel WARNING was uncovered with the following backtrace:
... the issue would appear that calipso_req_setattr() ends up calling a function which assumes the IPv6 option data is coming from userspace, and ends up calling _copy_from_user() to safely copy the data. Unfortunately in this particular case the IPv6 option is not coming from userspace which triggers the warning we see above.