summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2008-07-05 13:10:10 +0000
committerrwatson <rwatson@FreeBSD.org>2008-07-05 13:10:10 +0000
commit051819b84758e212ecd632e9bd6f47e70f37aa3a (patch)
treefcde383ade7af0060da3dd095039791d9e423bee
parentb754e07b66100e4e4d6ac8caa8f6302730552936 (diff)
downloadFreeBSD-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
-rw-r--r--sys/compat/linux/linux_misc.c2
-rw-r--r--sys/compat/svr4/svr4_stat.c1
-rw-r--r--sys/dev/syscons/daemon/daemon_saver.c2
-rw-r--r--sys/fs/cd9660/cd9660_rrip.c2
-rw-r--r--sys/geom/vinum/geom_vinum_drive.c2
-rw-r--r--sys/i386/ibcs2/ibcs2_socksys.c8
-rw-r--r--sys/kern/kern_jail.c5
-rw-r--r--sys/kern/kern_mib.c48
-rw-r--r--sys/kern/kern_xxx.c32
-rw-r--r--sys/netinet6/icmp6.c6
-rw-r--r--sys/netinet6/in6.c5
-rw-r--r--sys/netinet6/in6_ifattach.c5
-rw-r--r--sys/nfsclient/bootp_subr.c2
-rw-r--r--sys/nfsclient/nfs_vfsops.c2
-rw-r--r--sys/nlm/nlm_advlock.c4
-rw-r--r--sys/rpc/authunix_prot.c4
-rw-r--r--sys/sys/kernel.h1
17 files changed, 106 insertions, 25 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 9989948..e9fdccc 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -761,7 +761,9 @@ linux_newuname(struct thread *td, struct linux_newuname_args *args)
#else /* something other than i386 or amd64 - assume we and Linux agree */
strlcpy(utsname.machine, machine, LINUX_MAX_UTSNAME);
#endif /* __i386__ */
+ mtx_lock(&hostname_mtx);
strlcpy(utsname.domainname, domainname, LINUX_MAX_UTSNAME);
+ mtx_unlock(&hostname_mtx);
return (copyout(&utsname, args->buf, sizeof(utsname)));
}
diff --git a/sys/compat/svr4/svr4_stat.c b/sys/compat/svr4/svr4_stat.c
index 915175a..7b6f200 100644
--- a/sys/compat/svr4/svr4_stat.c
+++ b/sys/compat/svr4/svr4_stat.c
@@ -454,6 +454,7 @@ svr4_sys_systeminfo(td, uap)
break;
case SVR4_SI_SRPC_DOMAIN:
+ /* XXXRW: locking? */
str = domainname;
break;
diff --git a/sys/dev/syscons/daemon/daemon_saver.c b/sys/dev/syscons/daemon/daemon_saver.c
index b15e04c..2afc4c0 100644
--- a/sys/dev/syscons/daemon/daemon_saver.c
+++ b/sys/dev/syscons/daemon/daemon_saver.c
@@ -350,6 +350,8 @@ daemon_saver(video_adapter_t *adp, int blank)
static int
daemon_init(video_adapter_t *adp)
{
+
+ /* XXXRW: Locking -- these can change! */
messagelen = strlen(hostname) + 3 + strlen(ostype) + 1 +
strlen(osrelease);
message = malloc(messagelen + 1, M_DEVBUF, M_WAITOK);
diff --git a/sys/fs/cd9660/cd9660_rrip.c b/sys/fs/cd9660/cd9660_rrip.c
index c3c8027..fd28218 100644
--- a/sys/fs/cd9660/cd9660_rrip.c
+++ b/sys/fs/cd9660/cd9660_rrip.c
@@ -170,6 +170,7 @@ cd9660_rrip_slink(p,ana)
break;
case ISO_SUSP_CFLAG_HOST:
+ /* XXXRW: locking. */
/* Inserting hostname i.e. "kurt.tools.de" */
inbuf = hostname;
wlen = strlen(hostname);
@@ -242,6 +243,7 @@ cd9660_rrip_altname(p,ana)
break;
case ISO_SUSP_CFLAG_HOST:
+ /* XXXRW: locking. */
/* Inserting hostname i.e. "kurt.tools.de" */
inbuf = hostname;
wlen = strlen(hostname);
diff --git a/sys/geom/vinum/geom_vinum_drive.c b/sys/geom/vinum/geom_vinum_drive.c
index 237d55e..a72937c 100644
--- a/sys/geom/vinum/geom_vinum_drive.c
+++ b/sys/geom/vinum/geom_vinum_drive.c
@@ -62,7 +62,9 @@ gv_config_new_drive(struct gv_drive *d)
vhdr->magic = GV_MAGIC;
vhdr->config_length = GV_CFG_LEN;
+ mtx_lock(&hostname_mtx);
bcopy(hostname, vhdr->label.sysname, GV_HOSTNAME_LEN);
+ mtx_unlock(&hostname_mtx);
strncpy(vhdr->label.name, d->name, GV_MAXDRIVENAME);
microtime(&vhdr->label.date_of_birth);
diff --git a/sys/i386/ibcs2/ibcs2_socksys.c b/sys/i386/ibcs2/ibcs2_socksys.c
index f4939cf..62d300f 100644
--- a/sys/i386/ibcs2/ibcs2_socksys.c
+++ b/sys/i386/ibcs2/ibcs2_socksys.c
@@ -31,6 +31,8 @@ __FBSDID("$FreeBSD$");
#include <sys/sysproto.h>
#include <sys/jail.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/sysctl.h>
#include <i386/ibcs2/ibcs2_socksys.h>
@@ -175,11 +177,15 @@ ibcs2_setipdomainname(td, uap)
int error, sctl[2], hlen;
/* W/out a hostname a domain-name is nonsense */
- if ( strlen(hostname) == 0 )
+ mtx_lock(&hostname_mtx);
+ if ( strlen(hostname) == 0 ) {
+ mtx_unlock(&hostname_mtx);
return EINVAL;
+ }
/* Get the host's unqualified name (strip off the domain) */
snprintf(hname, sizeof(hname), "%s", hostname);
+ mtx_unlock(&hostname_mtx);
ptr = index(hname, '.');
if ( ptr != NULL ) {
ptr++;
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index fe34616..869551f 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -475,8 +475,11 @@ getcredhostname(struct ucred *cred, char *buf, size_t size)
mtx_lock(&cred->cr_prison->pr_mtx);
strlcpy(buf, cred->cr_prison->pr_host, size);
mtx_unlock(&cred->cr_prison->pr_mtx);
- } else
+ } else {
+ mtx_lock(&hostname_mtx);
strlcpy(buf, hostname, size);
+ mtx_unlock(&hostname_mtx);
+ }
}
/*
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
index b8ce527..e178ce6 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -208,6 +208,13 @@ SYSCTL_STRING(_hw, HW_MACHINE_ARCH, machine_arch, CTLFLAG_RD,
char hostname[MAXHOSTNAMELEN];
+/*
+ * This mutex is used to protect the hostname and domainname variables, and
+ * perhaps in the future should also protect hostid, hostuid, and others.
+ */
+struct mtx hostname_mtx;
+MTX_SYSINIT(hostname_mtx, &hostname_mtx, "hostname", MTX_DEF);
+
static int
sysctl_hostname(SYSCTL_HANDLER_ARGS)
{
@@ -240,9 +247,18 @@ sysctl_hostname(SYSCTL_HANDLER_ARGS)
bcopy(tmphostname, pr->pr_host, MAXHOSTNAMELEN);
mtx_unlock(&pr->pr_mtx);
}
- } else
- error = sysctl_handle_string(oidp,
- hostname, sizeof hostname, req);
+ } else {
+ mtx_lock(&hostname_mtx);
+ bcopy(hostname, tmphostname, MAXHOSTNAMELEN);
+ mtx_unlock(&hostname_mtx);
+ error = sysctl_handle_string(oidp, tmphostname,
+ sizeof tmphostname, req);
+ if (req->newptr != NULL && error == 0) {
+ mtx_lock(&hostname_mtx);
+ bcopy(tmphostname, hostname, MAXHOSTNAMELEN);
+ mtx_unlock(&hostname_mtx);
+ }
+ }
return (error);
}
@@ -328,9 +344,29 @@ SYSCTL_PROC(_kern, OID_AUTO, conftxt, CTLTYPE_STRING|CTLFLAG_RW,
0, 0, sysctl_kern_config, "", "Kernel configuration file");
#endif
-char domainname[MAXHOSTNAMELEN];
-SYSCTL_STRING(_kern, KERN_NISDOMAINNAME, domainname, CTLFLAG_RW,
- &domainname, sizeof(domainname), "Name of the current YP/NIS domain");
+char domainname[MAXHOSTNAMELEN]; /* Protected by hostname_mtx. */
+
+static int
+sysctl_domainname(SYSCTL_HANDLER_ARGS)
+{
+ char tmpdomainname[MAXHOSTNAMELEN];
+ int error;
+
+ mtx_lock(&hostname_mtx);
+ bcopy(domainname, tmpdomainname, MAXHOSTNAMELEN);
+ mtx_unlock(&hostname_mtx);
+ error = sysctl_handle_string(oidp, tmpdomainname,
+ sizeof tmpdomainname, req);
+ if (req->newptr != NULL && error == 0) {
+ mtx_lock(&hostname_mtx);
+ bcopy(tmpdomainname, domainname, MAXHOSTNAMELEN);
+ mtx_unlock(&hostname_mtx);
+ }
+ return (error);
+}
+
+SYSCTL_PROC(_kern, KERN_NISDOMAINNAME, domainname, CTLTYPE_STRING|CTLFLAG_RW,
+ 0, 0, sysctl_domainname, "A", "NAme of the current YP/NIS domain");
u_long hostid;
SYSCTL_ULONG(_kern, KERN_HOSTID, hostid, CTLFLAG_RW, &hostid, 0, "Host ID");
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);
}
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index d3c8315..e926c49 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -696,6 +696,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
n->m_pkthdr.rcvif = NULL;
n->m_len = 0;
maxhlen = M_TRAILINGSPACE(n) - maxlen;
+ mtx_lock(&hostname_mtx);
if (maxhlen > hostnamelen)
maxhlen = hostnamelen;
/*
@@ -708,6 +709,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
p = (u_char *)(nicmp6 + 1);
bzero(p, 4);
bcopy(hostname, p + 4, maxhlen); /* meaningless TTL */
+ mtx_unlock(&hostname_mtx);
noff = sizeof(struct ip6_hdr);
n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) +
sizeof(struct icmp6_hdr) + 4 + maxhlen;
@@ -1296,7 +1298,9 @@ ni6_input(struct mbuf *m, int off)
* wildcard match, if gethostname(3) side has
* truncated hostname.
*/
+ mtx_lock(&hostname_mtx);
n = ni6_nametodns(hostname, hostnamelen, 0);
+ mtx_unlock(&hostname_mtx);
if (!n || n->m_next || n->m_len == 0)
goto bad;
IP6_EXTHDR_GET(subj, char *, m,
@@ -1420,7 +1424,9 @@ ni6_input(struct mbuf *m, int off)
/*
* XXX do we really have FQDN in variable "hostname"?
*/
+ mtx_lock(&hostname_mtx);
n->m_next = ni6_nametodns(hostname, hostnamelen, oldfqdn);
+ mtx_unlock(&hostname_mtx);
if (n->m_next == NULL)
goto bad;
/* XXX we assume that n->m_next is not a chain */
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index c24ca20..bc9dcc9 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1159,8 +1159,10 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
delay = arc4random() %
(MAX_RTR_SOLICITATION_DELAY * hz);
}
+ mtx_lock(&hostname_mtx);
if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr.sin6_addr)
== 0) {
+ mtx_unlock(&hostname_mtx);
imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error,
delay); /* XXX jinmei */
if (!imm) {
@@ -1174,7 +1176,8 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
LIST_INSERT_HEAD(&ia->ia6_memberships,
imm, i6mm_chain);
}
- }
+ } else
+ mtx_unlock(&hostname_mtx);
#undef hostnamelen
/*
diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
index 29dca4f..8714377 100644
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -105,8 +105,10 @@ get_rand_ifid(struct ifnet *ifp, struct in6_addr *in6)
{
MD5_CTX ctxt;
u_int8_t digest[16];
- int hostnamelen = strlen(hostname);
+ int hostnamelen;
+ mtx_lock(&hostname_mtx);
+ hostnamelen = strlen(hostname);
#if 0
/* we need at least several letters as seed for ifid */
if (hostnamelen < 3)
@@ -117,6 +119,7 @@ get_rand_ifid(struct ifnet *ifp, struct in6_addr *in6)
bzero(&ctxt, sizeof(ctxt));
MD5Init(&ctxt);
MD5Update(&ctxt, hostname, hostnamelen);
+ mtx_unlock(&hostname_mtx);
MD5Final(digest, &ctxt);
/* assumes sizeof(digest) > sizeof(ifid) */
diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c
index 77c7739..7f65fe2 100644
--- a/sys/nfsclient/bootp_subr.c
+++ b/sys/nfsclient/bootp_subr.c
@@ -1569,8 +1569,10 @@ bootpc_decode_reply(struct nfsv3_diskless *nd, struct bootpc_ifcontext *ifctx,
printf("hostname %s (ignored) ", p);
} else {
strcpy(nd->my_hostnam, p);
+ mtx_lock(&hostname_mtx);
strcpy(hostname, p);
printf("hostname %s ", hostname);
+ mtx_unlock(&hostname_mtx);
gctx->sethostname = ifctx;
}
}
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index 17536491..c21b48e 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -506,11 +506,13 @@ nfs_mountroot(struct mount *mp, struct thread *td)
* set hostname here and then let the "/etc/rc.xxx" files
* mount the right /var based upon its preset value.
*/
+ mtx_lock(&hostname_mtx);
bcopy(nd->my_hostnam, hostname, MAXHOSTNAMELEN);
hostname[MAXHOSTNAMELEN - 1] = '\0';
for (i = 0; i < MAXHOSTNAMELEN; i++)
if (hostname[i] == '\0')
break;
+ mtx_unlock(&hostname_mtx);
inittodr(ntohl(nd->root_time));
return (0);
}
diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c
index fb8b5a7..5d1cc83 100644
--- a/sys/nlm/nlm_advlock.c
+++ b/sys/nlm/nlm_advlock.c
@@ -230,7 +230,9 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
sa = nmp->nm_nam;
memcpy(&ss, sa, sa->sa_len);
sa = (struct sockaddr *) &ss;
+ mtx_lock(&hostname_mtx);
strcpy(servername, nmp->nm_hostname);
+ mtx_unlock(&hostname_mtx);
fhlen = np->n_fhsize;
memcpy(&fh.fh_bytes, np->n_fhp, fhlen);
timo.tv_sec = nmp->nm_timeo / NFS_HZ;
@@ -1218,7 +1220,9 @@ nlm_init_lock(struct flock *fl, int flags, int svid,
return (EOVERFLOW);
}
+ mtx_lock(&hostname_mtx);
snprintf(oh_space, 32, "%d@%s", svid, hostname);
+ mtx_unlock(&hostname_mtx);
oh_len = strlen(oh_space);
memset(lock, 0, sizeof(*lock));
diff --git a/sys/rpc/authunix_prot.c b/sys/rpc/authunix_prot.c
index 141f594..b229fb3 100644
--- a/sys/rpc/authunix_prot.c
+++ b/sys/rpc/authunix_prot.c
@@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/systm.h>
#include <sys/ucred.h>
@@ -67,6 +69,7 @@ xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred *cred)
uint32_t ngroups, i;
uint32_t junk;
+ mtx_lock(&hostname_mtx);
if (xdrs->x_op == XDR_ENCODE) {
/*
* Restrict name length to 255 according to RFC 1057.
@@ -92,6 +95,7 @@ xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred *cred)
} else {
xdr_setpos(xdrs, xdr_getpos(xdrs) + RNDUP(namelen));
}
+ mtx_unlock(&hostname_mtx);
if (!xdr_uint32_t(xdrs, &cred->cr_uid))
return (FALSE);
diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h
index de57a6f..951d6bc 100644
--- a/sys/sys/kernel.h
+++ b/sys/sys/kernel.h
@@ -55,6 +55,7 @@
/* Global variables for the kernel. */
/* 1.1 */
+extern struct mtx hostname_mtx;
extern unsigned long hostid;
extern char hostuuid[64];
extern char hostname[MAXHOSTNAMELEN];
OpenPOWER on IntegriCloud