Do not allocate memory while holding a mutex.

I introduce a very small race here (some file system can be mounted or
unmounted between 'count' calculation and file systems list creation),
but it is harmless.

Found by:	FreeBSD Kernel Stress Test Suite: http://www.holm.cc/stress/
Reported by:	Peter Holm <peter@holm.cc>
This commit is contained in:
pjd 2005-06-12 07:03:23 +00:00
parent 2a4fb1caf1
commit d2fe610c90
2 changed files with 8 additions and 4 deletions

View File

@ -409,23 +409,25 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
int error;
maxcount = bufsize / sizeof(struct statfs);
mtx_lock(&Giant);
mtx_lock(&mountlist_mtx);
if (bufsize == 0)
sfsp = NULL;
else if (bufseg == UIO_USERSPACE)
sfsp = *buf;
else /* if (bufseg == UIO_SYSSPACE) */ {
count = 0;
mtx_lock(&mountlist_mtx);
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
count++;
}
mtx_unlock(&mountlist_mtx);
if (maxcount > count)
maxcount = count;
sfsp = *buf = malloc(maxcount * sizeof(struct statfs), M_TEMP,
M_WAITOK);
}
count = 0;
mtx_lock(&Giant);
mtx_lock(&mountlist_mtx);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
if (prison_canseemount(td->td_ucred, mp) != 0) {
nmp = TAILQ_NEXT(mp, mnt_list);

View File

@ -409,23 +409,25 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
int error;
maxcount = bufsize / sizeof(struct statfs);
mtx_lock(&Giant);
mtx_lock(&mountlist_mtx);
if (bufsize == 0)
sfsp = NULL;
else if (bufseg == UIO_USERSPACE)
sfsp = *buf;
else /* if (bufseg == UIO_SYSSPACE) */ {
count = 0;
mtx_lock(&mountlist_mtx);
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
count++;
}
mtx_unlock(&mountlist_mtx);
if (maxcount > count)
maxcount = count;
sfsp = *buf = malloc(maxcount * sizeof(struct statfs), M_TEMP,
M_WAITOK);
}
count = 0;
mtx_lock(&Giant);
mtx_lock(&mountlist_mtx);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
if (prison_canseemount(td->td_ucred, mp) != 0) {
nmp = TAILQ_NEXT(mp, mnt_list);