In ng_getsockaddr() allocate memory prior to obtaining lock.

Reported & tested by:	Mykola Dzham <i levsha.me>
This commit is contained in:
Gleb Smirnoff 2012-02-16 14:44:52 +00:00
parent 262eab04a6
commit 8338a34a82
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=231823

View File

@ -490,33 +490,30 @@ ng_getsockaddr(struct socket *so, struct sockaddr **addr)
int sg_len;
int error = 0;
/* Why isn't sg_data a `char[1]' ? :-( */
sg_len = sizeof(struct sockaddr_ng) - sizeof(sg->sg_data) + 1;
pcbp = sotongpcb(so);
if ((pcbp == NULL) || (pcbp->sockdata == NULL))
/* XXXGL: can this still happen? */
return (EINVAL);
sg_len = sizeof(struct sockaddr_ng) + NG_NODESIZ -
sizeof(sg->sg_data);
sg = malloc(sg_len, M_SONAME, M_WAITOK | M_ZERO);
mtx_lock(&pcbp->sockdata->mtx);
if (pcbp->sockdata->node != NULL) {
node_p node = pcbp->sockdata->node;
int namelen = 0; /* silence compiler! */
if (NG_NODE_HAS_NAME(node))
sg_len += namelen = strlen(NG_NODE_NAME(node));
sg = malloc(sg_len, M_SONAME, M_WAITOK | M_ZERO);
if (NG_NODE_HAS_NAME(node))
bcopy(NG_NODE_NAME(node), sg->sg_data, namelen);
bcopy(NG_NODE_NAME(node), sg->sg_data,
strlen(NG_NODE_NAME(node)));
mtx_unlock(&pcbp->sockdata->mtx);
sg->sg_len = sg_len;
sg->sg_family = AF_NETGRAPH;
*addr = (struct sockaddr *)sg;
mtx_unlock(&pcbp->sockdata->mtx);
} else {
mtx_unlock(&pcbp->sockdata->mtx);
free(sg, M_SONAME);
error = EINVAL;
}