Bug 207911 - kiconv reference count integer overflow
Summary: kiconv reference count integer overflow
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: FreeBSD bugs mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-03-11 19:20 UTC by CTurt
Modified: 2016-10-14 19:14 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description CTurt 2016-03-11 19:20:05 UTC
The `kiconv` module doesn't perform checks on the reference count of its converter class before incrementing and decrementing it, sys/libkern/iconv.c:

static int
iconv_register_converter(struct iconv_converter_class *dcp)
{
	kobj_class_compile((struct kobj_class*)dcp);
	dcp->refs++;
	TAILQ_INSERT_TAIL(&iconv_converters, dcp, cc_link);
	return 0;
}

static int
iconv_unregister_converter(struct iconv_converter_class *dcp)
{
	dcp->refs--;
	if (dcp->refs > 1) {
		ICDEBUG("converter has %d references left\n", dcp->refs);
		return EBUSY;
	}
	TAILQ_REMOVE(&iconv_converters, dcp, cc_link);
	kobj_class_free((struct kobj_class*)dcp);
	return 0;
}

Since `refs` field is declared as `u_int`, if `iconv_register_converter` is called enough times it will overflow from `UINT_MAX` to `0` and then be incremented to `1`. Then when `iconv_unregister_converter` is called, the check against `dcp->refs` will be bypassed and its converter class will then be freed even though it still has references; leading to use after free behaviour.

This is mostly theoretical since it is unlikely to be possible to register this many converter classes without encountering other issues, such as running out of memory. In addition, the `iconv_register_converter` is only called on the `MOD_LOAD` event, which is root only, so is unlikely to present a security risk.