Don't indirect user pointers directly in two 802.11s ioctls.

IEEE80211_MESH_RTCMD_ADD was invoking memcmp() to validate the
supplied address directly on the user pointer rather than first doing
a copyin() and validating the copied value.

IEEE80211_MESH_RTCMD_DELETE was passing the user pointer directly to
ieee80211_mesh_rt_del() rather than copying the user buffer into a
temporary kernel buffer.

Reviewed by:	brooks, kib
Obtained from:	CheriBSD
MFC after:	2 weeks
Sponsored by:	DARPA
Differential Revision:	https://reviews.freebsd.org/D24562
This commit is contained in:
John Baldwin 2020-04-24 22:10:02 +00:00
parent 5dcf0083fc
commit 88901af835

View File

@ -3575,16 +3575,21 @@ mesh_ioctl_set80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
ieee80211_mesh_rt_flush(vap);
break;
case IEEE80211_MESH_RTCMD_ADD:
if (IEEE80211_ADDR_EQ(vap->iv_myaddr, ireq->i_data) ||
IEEE80211_ADDR_EQ(broadcastaddr, ireq->i_data))
return EINVAL;
error = copyin(ireq->i_data, &tmpaddr,
error = copyin(ireq->i_data, tmpaddr,
IEEE80211_ADDR_LEN);
if (error == 0)
ieee80211_mesh_discover(vap, tmpaddr, NULL);
if (error != 0)
break;
if (IEEE80211_ADDR_EQ(vap->iv_myaddr, tmpaddr) ||
IEEE80211_ADDR_EQ(broadcastaddr, tmpaddr))
return EINVAL;
ieee80211_mesh_discover(vap, tmpaddr, NULL);
break;
case IEEE80211_MESH_RTCMD_DELETE:
ieee80211_mesh_rt_del(vap, ireq->i_data);
error = copyin(ireq->i_data, tmpaddr,
IEEE80211_ADDR_LEN);
if (error != 0)
break;
ieee80211_mesh_rt_del(vap, tmpaddr);
break;
default:
return ENOSYS;