diff options
author | rwatson <rwatson@FreeBSD.org> | 2008-07-05 13:10:10 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2008-07-05 13:10:10 +0000 |
commit | 051819b84758e212ecd632e9bd6f47e70f37aa3a (patch) | |
tree | fcde383ade7af0060da3dd095039791d9e423bee /sys/kern/kern_xxx.c | |
parent | b754e07b66100e4e4d6ac8caa8f6302730552936 (diff) | |
download | FreeBSD-src-051819b84758e212ecd632e9bd6f47e70f37aa3a.zip FreeBSD-src-051819b84758e212ecd632e9bd6f47e70f37aa3a.tar.gz |
Introduce a new lock, hostname_mtx, and use it to synchronize access
to global hostname and domainname variables. Where necessary, copy
to or from a stack-local buffer before performing copyin() or
copyout(). A few uses, such as in cd9660 and daemon_saver, remain
under-synchronized and will require further updates.
Correct a bug in which a failed copyin() of domainname would leave
domainname potentially corrupted.
MFC after: 3 weeks
Diffstat (limited to 'sys/kern/kern_xxx.c')
-rw-r--r-- | sys/kern/kern_xxx.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c index ffb0729..0a4f42d 100644 --- a/sys/kern/kern_xxx.c +++ b/sys/kern/kern_xxx.c @@ -245,16 +245,17 @@ getdomainname(td, uap) struct thread *td; struct getdomainname_args *uap; { + char tmpdomainname[MAXHOSTNAMELEN]; int domainnamelen; - int error; - mtx_lock(&Giant); - domainnamelen = strlen(domainname) + 1; + mtx_lock(&hostname_mtx); + bcopy(domainname, tmpdomainname, sizeof(tmpdomainname)); + mtx_unlock(&hostname_mtx); + + domainnamelen = strlen(tmpdomainname) + 1; if ((u_int)uap->len > domainnamelen) uap->len = domainnamelen; - error = copyout(domainname, uap->domainname, uap->len); - mtx_unlock(&Giant); - return (error); + return (copyout(tmpdomainname, uap->domainname, uap->len)); } #ifndef _SYS_SYSPROTO_H_ @@ -269,20 +270,21 @@ setdomainname(td, uap) struct thread *td; struct setdomainname_args *uap; { + char tmpdomainname[MAXHOSTNAMELEN]; int error, domainnamelen; error = priv_check(td, PRIV_SETDOMAINNAME); if (error) return (error); - mtx_lock(&Giant); - if ((u_int)uap->len > sizeof (domainname) - 1) { - error = EINVAL; - goto done2; - } + if ((u_int)uap->len > sizeof(tmpdomainname) - 1) + return (EINVAL); domainnamelen = uap->len; - error = copyin(uap->domainname, domainname, uap->len); - domainname[domainnamelen] = 0; -done2: - mtx_unlock(&Giant); + error = copyin(uap->domainname, tmpdomainname, uap->len); + if (error == 0) { + tmpdomainname[domainnamelen] = 0; + mtx_lock(&hostname_mtx); + bcopy(tmpdomainname, domainname, sizeof(domainname)); + mtx_unlock(&hostname_mtx); + } return (error); } |