summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2005-06-12 07:03:23 +0000
committerpjd <pjd@FreeBSD.org>2005-06-12 07:03:23 +0000
commitd2fe610c90770fc475b5be2d6ca70974207754e9 (patch)
treebc73e5222c4446ea10124d21f9a11454010699c4 /sys
parent2a4fb1caf123f1a11d6912437c7d7ee3473f44f3 (diff)
downloadFreeBSD-src-d2fe610c90770fc475b5be2d6ca70974207754e9.zip
FreeBSD-src-d2fe610c90770fc475b5be2d6ca70974207754e9.tar.gz
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>
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_extattr.c6
-rw-r--r--sys/kern/vfs_syscalls.c6
2 files changed, 8 insertions, 4 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 242473f..b3bb0b2 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -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);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 242473f..b3bb0b2 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -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);
OpenPOWER on IntegriCloud