diff options
author | glebius <glebius@FreeBSD.org> | 2012-02-16 14:44:52 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2012-02-16 14:44:52 +0000 |
commit | 90e0448c34f04c967f189eb2d7a9c7b2c319d4ba (patch) | |
tree | 8318bfd24395d8ec199f6f78fb704b5ad02cdbaf /sys/netgraph | |
parent | e0d1bce11dd08456301e7612d7d8350fdf3c158b (diff) | |
download | FreeBSD-src-90e0448c34f04c967f189eb2d7a9c7b2c319d4ba.zip FreeBSD-src-90e0448c34f04c967f189eb2d7a9c7b2c319d4ba.tar.gz |
In ng_getsockaddr() allocate memory prior to obtaining lock.
Reported & tested by: Mykola Dzham <i levsha.me>
Diffstat (limited to 'sys/netgraph')
-rw-r--r-- | sys/netgraph/ng_socket.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c index c9d9346..16ea7c5 100644 --- a/sys/netgraph/ng_socket.c +++ b/sys/netgraph/ng_socket.c @@ -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; } |