Fix a LOR where copyout was called while holding a lock.

Reported by:    rwatson
This commit is contained in:
Brooks Davis 2004-09-15 04:41:56 +00:00
parent e8807f22f9
commit c859ef977e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=135256

View File

@ -235,9 +235,24 @@ if_clone_free(struct if_clone *ifc)
int
if_clone_list(struct if_clonereq *ifcr)
{
char outbuf[IFNAMSIZ], *dst;
char *buf, *dst, *outbuf = NULL;
struct if_clone *ifc;
int count, err = 0;
int buf_count, count, err = 0;
IF_CLONERS_LOCK();
/*
* Set our internal output buffer size. We could end up not
* reporting a cloner that is added between the unlock and lock
* below, but that's not a major problem. Not caping our
* allocation to the number of cloners actually in the system
* could be because that would let arbitrary users cause us to
* allocate abritrary amounts of kernel memory.
*/
buf_count = (if_cloners_count < ifcr->ifcr_count) ?
if_cloners_count : ifcr->ifcr_count;
IF_CLONERS_UNLOCK();
outbuf = malloc(IFNAMSIZ*buf_count, M_CLONE, M_WAITOK | M_ZERO);
IF_CLONERS_LOCK();
@ -252,19 +267,21 @@ if_clone_list(struct if_clonereq *ifcr)
goto done;
}
count = (if_cloners_count < ifcr->ifcr_count) ?
if_cloners_count : ifcr->ifcr_count;
count = (if_cloners_count < buf_count) ?
if_cloners_count : buf_count;
for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ);
err = copyout(outbuf, dst, IFNAMSIZ);
if (err)
break;
for (ifc = LIST_FIRST(&if_cloners), buf = outbuf;
ifc != NULL && count != 0;
ifc = LIST_NEXT(ifc, ifc_list), count--, buf += IFNAMSIZ) {
strlcpy(buf, ifc->ifc_name, IFNAMSIZ);
}
done:
IF_CLONERS_UNLOCK();
if (err == 0)
err = copyout(outbuf, dst, buf_count*IFNAMSIZ);
if (outbuf != NULL)
free(outbuf, M_CLONE);
return (err);
}