Bug 256283 - FreeBSD-SA-21:12.libradius breaks mpd5 when using MS-CHAPv2
Summary: FreeBSD-SA-21:12.libradius breaks mpd5 when using MS-CHAPv2
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 13.0-RELEASE
Hardware: Any Any
: --- Affects Many People
Assignee: Mark Johnston
URL:
Keywords: regression
Depends on:
Blocks:
 
Reported: 2021-05-31 07:18 UTC by topical
Modified: 2021-06-02 06:55 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description topical 2021-05-31 07:18:13 UTC
This SA breaks mpd5 with MS-CHAPv2. 

No workaround available but to replace libradius* with pre-SA version.

Setup: if there is a dial in server using

  * mpd5
  * external radius server in different jail (freeradius3)
  * MS-CHAPv2 for authentication (done by freeradius3)

authentication succeeds, but mpd5 disconnects immediately because of alleged missing MS-CHAP2-Success attributes.

Logging of mpd5 shows:

   mpd[10012]: [L_l2tp] RADIUS: Authenticating user 'username'
   mpd[10012]: [L_l2tp] RADIUS: Rec'd RAD_ACCESS_ACCEPT for user 'username'
   mpd[10012]: [L_l2tp]  RADIUS: PANIC no MS-CHAP2-Success received from server!

Checking this at freeradius3 server and packet capture show that the attribute indeed exists but seems to be ignored by mpd5/libradius.

Replacing libradius on log in server with pre-SA version makes mpd5 work again:

   mpd[96202]: [L_l2tp] RADIUS: Authenticating user 'user'
   mpd[96202]: [L_l2tp] RADIUS: Rec'd RAD_ACCESS_ACCEPT for user 'user'
   mpd[96202]: [L_l2tp] AUTH: RADIUS returned: authenticated
   mpd[96202]: [L_l2tp] CHAP: Auth return status: authenticated
   mpd[96202]: [L_l2tp] CHAP: Reply message: S=XXXXXXXX
   mpd[96202]: [L_l2tp] CHAP: sending SUCCESS #1 len: 46

I haven't found out which part of fix is to be blamed but this situation is rather unpleasant (especially since mpd5 is the main application of libradius).
Comment 1 topical 2021-05-31 09:06:59 UTC
The CVE fix broke the following function:

int
rad_get_attr(struct rad_handle *h, const void **value, size_t *lenp)
{
	int len, type;

	if (h->in_pos >= h->in_len)
		return 0;
	if (h->in_pos + 2 > h->in_len) {
		generr(h, "Malformed attribute in response");
		return -1;
	}
	type = h->in[h->in_pos++];
	len = h->in[h->in_pos++];
	if (len < 2 || h->in_pos + len > h->in_len) {
		generr(h, "Malformed attribute in response");
		return -1;
	}
	*lenp = len;
	*value = &h->in[h->in_pos];
	h->in_pos += len;
	return type;
}

The failure occurs after

  	len = h->in[h->in_pos++];

This len is the total length of the attribute, **including** the 2 byte header. All lines below assume that len excludes the header, so lenp is 2 byte too long and h->in_pos is shifted 2 bytes too far. 

When you call rad_get_attr() for the first time, the returned data is just 2 bytes to long (unless there is only 1 attribute, in which case you get a "Malformed attribute" error because of the "missing" 2 extra bytes). But: as h->in_pos is located 2 bytes within the second attribute on return, all subsequent calls to rad_get_attr() will return garbage.

A possible fix is:

int
rad_get_attr(struct rad_handle *h, const void **value, size_t *lenp)
{
	int len, type;

	if (h->in_pos >= h->in_len)
		return 0;
	if (h->in_pos + 2 > h->in_len) {
		generr(h, "Malformed attribute in response");
		return -1;
	}
	type = h->in[h->in_pos];
	len = h->in[h->in_pos + 1];
	if (len < 2 || h->in_pos + len > h->in_len) {
		generr(h, "Malformed attribute in response");
		return -1;
	}
	*lenp = len - 2;
	*value = &h->in[h->in_pos + 2];
	h->in_pos += len;
	return type;
}

The missing piece is: how to properly distribute this fix of the broken CVE fix?
Comment 2 Mark Johnston freebsd_committer freebsd_triage 2021-05-31 12:44:38 UTC
We've patched the tree to fix this already, see https://cgit.freebsd.org/src/commit/?id=6bb5699d2b59491097bc21ffa3c097cdd4853f89

We are working on releasing an EN to update affected hosts. I apologize for the breakage.
Comment 3 Mark Johnston freebsd_committer freebsd_triage 2021-06-01 20:38:39 UTC
A patch has been published as FreeBSD-EN-21:17.libradius.
Comment 4 topical 2021-06-02 06:55:21 UTC
Thank you very much for the quick response and the swift fix.

It's really nice to see how fast such problems are solved in this community.