From f3a9a195cb5b2d1f5e0a7779c33cce89b9539695 Mon Sep 17 00:00:00 2001 From: ed Date: Mon, 29 Dec 2008 12:58:45 +0000 Subject: Push down Giant inside sysctl. Also add some more assertions to the code. In the existing code we didn't really enforce that callers hold Giant before calling userland_sysctl(), even though there is no guarantee it is safe. Fix this by just placing Giant locks around the call to the oid handler. This also means we only pick up Giant for a very short period of time. Maybe we should add MPSAFE flags to sysctl or phase it out all together. I've also added SYSCTL_LOCK_ASSERT(). We have to make sure sysctl_root() and name2oid() are called with the sysctl lock held. Reviewed by: Jille Timmermans --- sys/kern/kern_xxx.c | 50 ++++++++++++++++---------------------------------- 1 file changed, 16 insertions(+), 34 deletions(-) (limited to 'sys/kern/kern_xxx.c') diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c index b894ae6..131b16a 100644 --- a/sys/kern/kern_xxx.c +++ b/sys/kern/kern_xxx.c @@ -62,16 +62,12 @@ ogethostname(td, uap) struct gethostname_args *uap; { int name[2]; - int error; size_t len = uap->len; name[0] = CTL_KERN; name[1] = KERN_HOSTNAME; - mtx_lock(&Giant); - error = userland_sysctl(td, name, 2, uap->hostname, &len, - 1, 0, 0, 0, 0); - mtx_unlock(&Giant); - return(error); + return (userland_sysctl(td, name, 2, uap->hostname, &len, + 1, 0, 0, 0, 0)); } #ifndef _SYS_SYSPROTO_H_ @@ -91,11 +87,8 @@ osethostname(td, uap) name[0] = CTL_KERN; name[1] = KERN_HOSTNAME; - mtx_lock(&Giant); - error = userland_sysctl(td, name, 2, 0, 0, 0, uap->hostname, - uap->len, 0, 0); - mtx_unlock(&Giant); - return (error); + return (userland_sysctl(td, name, 2, 0, 0, 0, uap->hostname, + uap->len, 0, 0)); } #ifndef _SYS_SYSPROTO_H_ @@ -173,11 +166,10 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap) name[0] = CTL_KERN; name[1] = KERN_OSTYPE; len = sizeof (uap->name->sysname); - mtx_lock(&Giant); error = userland_sysctl(td, name, 2, uap->name->sysname, &len, 1, 0, 0, 0, 0); if (error) - goto done2; + return (error); subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0); name[1] = KERN_HOSTNAME; @@ -185,7 +177,7 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap) error = userland_sysctl(td, name, 2, uap->name->nodename, &len, 1, 0, 0, 0, 0); if (error) - goto done2; + return (error); subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0); name[1] = KERN_OSRELEASE; @@ -193,7 +185,7 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap) error = userland_sysctl(td, name, 2, uap->name->release, &len, 1, 0, 0, 0, 0); if (error) - goto done2; + return (error); subyte( uap->name->release + sizeof(uap->name->release) - 1, 0); /* @@ -202,7 +194,7 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap) error = userland_sysctl(td, name, 2, uap->name->version, &len, 1, 0, 0, 0, 0); if (error) - goto done2; + return (error); subyte( uap->name->version + sizeof(uap->name->version) - 1, 0); */ @@ -214,11 +206,11 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap) for(us = uap->name->version; *s && *s != ':'; s++) { error = subyte( us++, *s); if (error) - goto done2; + return (error); } error = subyte( us++, 0); if (error) - goto done2; + return (error); name[0] = CTL_HW; name[1] = HW_MACHINE; @@ -226,11 +218,9 @@ freebsd4_uname(struct thread *td, struct freebsd4_uname_args *uap) error = userland_sysctl(td, name, 2, uap->name->machine, &len, 1, 0, 0, 0, 0); if (error) - goto done2; + return (error); subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0); -done2: - mtx_unlock(&Giant); - return (error); + return (0); } #ifndef _SYS_SYSPROTO_H_ @@ -245,16 +235,12 @@ freebsd4_getdomainname(struct thread *td, struct freebsd4_getdomainname_args *uap) { int name[2]; - int error; size_t len = uap->len; name[0] = CTL_KERN; name[1] = KERN_NISDOMAINNAME; - mtx_lock(&Giant); - error = userland_sysctl(td, name, 2, uap->domainname, &len, - 1, 0, 0, 0, 0); - mtx_unlock(&Giant); - return(error); + return (userland_sysctl(td, name, 2, uap->domainname, &len, + 1, 0, 0, 0, 0)); } #ifndef _SYS_SYSPROTO_H_ @@ -269,14 +255,10 @@ freebsd4_setdomainname(struct thread *td, struct freebsd4_setdomainname_args *uap) { int name[2]; - int error; name[0] = CTL_KERN; name[1] = KERN_NISDOMAINNAME; - mtx_lock(&Giant); - error = userland_sysctl(td, name, 2, 0, 0, 0, uap->domainname, - uap->len, 0, 0); - mtx_unlock(&Giant); - return (error); + return (userland_sysctl(td, name, 2, 0, 0, 0, uap->domainname, + uap->len, 0, 0)); } #endif /* COMPAT_FREEBSD4 */ -- cgit v1.1