aboutsummaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2012-11-04 02:52:03 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2012-11-04 02:52:03 +0000
commit23090366f729c56cab62de74c7a51792357e98a9 (patch)
treec511c885796e28ec571b5267e8f11f3b103d35e9 /libexec
parent7750ad47a9a7dbc83f87158464170c8640723293 (diff)
parent22ff74b2f44234d31540b1f7fd6c91489c37cad3 (diff)
Notes
Diffstat (limited to 'libexec')
-rw-r--r--libexec/Makefile7
-rw-r--r--libexec/atf/Makefile30
-rw-r--r--libexec/atf/Makefile.inc32
-rw-r--r--libexec/atf/atf-check/Makefile45
-rw-r--r--libexec/atrun/atrun.c21
-rw-r--r--libexec/atrun/atrun.man4
-rw-r--r--libexec/comsat/comsat.82
-rw-r--r--libexec/ftpd/ftpd.82
-rw-r--r--libexec/rbootd/rbootd.c7
-rw-r--r--libexec/rbootd/rmpproto.c2
-rw-r--r--libexec/revnetgroup/revnetgroup.84
-rw-r--r--libexec/rpc.rstatd/rstat_proc.c7
-rw-r--r--libexec/rpc.rusersd/Makefile2
-rw-r--r--libexec/rpc.rusersd/extern.h38
-rw-r--r--libexec/rpc.rusersd/rusers_proc.c6
-rw-r--r--libexec/rpc.rusersd/rusersd.c2
-rw-r--r--libexec/rshd/rshd.81
-rw-r--r--libexec/rtld-aout/shlib.c2
-rw-r--r--libexec/rtld-elf/arm/reloc.c15
-rw-r--r--libexec/rtld-elf/arm/rtld_start.S6
-rw-r--r--libexec/rtld-elf/map_object.c132
-rw-r--r--libexec/rtld-elf/rtld.153
-rw-r--r--libexec/rtld-elf/rtld.c442
-rw-r--r--libexec/rtld-elf/rtld.h10
-rwxr-xr-xlibexec/save-entropy/save-entropy.sh54
-rw-r--r--libexec/talkd/announce.c2
-rw-r--r--libexec/talkd/extern.h3
-rw-r--r--libexec/talkd/process.c2
-rw-r--r--libexec/talkd/table.c5
-rw-r--r--libexec/talkd/talkd.c10
-rw-r--r--libexec/tftpd/tftp-io.c4
-rw-r--r--libexec/tftpd/tftp-utils.c2
-rw-r--r--libexec/tftpd/tftpd.c9
33 files changed, 710 insertions, 253 deletions
diff --git a/libexec/Makefile b/libexec/Makefile
index 78953b4e26a08..0b9c9618a1b79 100644
--- a/libexec/Makefile
+++ b/libexec/Makefile
@@ -3,7 +3,8 @@
.include <bsd.own.mk>
-SUBDIR= ${_atrun} \
+SUBDIR= ${_atf} \
+ ${_atrun} \
bootpd \
${_comsat} \
fingerd \
@@ -32,6 +33,10 @@ SUBDIR= ${_atrun} \
ulog-helper \
${_ypxfr}
+.if ${MK_ATF} != "no"
+_atf= atf
+.endif
+
.if ${MK_AT} != "no"
_atrun= atrun
.endif
diff --git a/libexec/atf/Makefile b/libexec/atf/Makefile
new file mode 100644
index 0000000000000..dc222c3933292
--- /dev/null
+++ b/libexec/atf/Makefile
@@ -0,0 +1,30 @@
+#-
+# Copyright (c) 2011 Google, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+SUBDIR= atf-check
+
+.include <bsd.subdir.mk>
diff --git a/libexec/atf/Makefile.inc b/libexec/atf/Makefile.inc
new file mode 100644
index 0000000000000..a28f54645572c
--- /dev/null
+++ b/libexec/atf/Makefile.inc
@@ -0,0 +1,32 @@
+#-
+# Copyright (c) 2011 Google, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+ATF = ${.CURDIR}/../../../contrib/atf
+
+CFLAGS+= -DHAVE_CONFIG_H
+
+WARNS?= 3
diff --git a/libexec/atf/atf-check/Makefile b/libexec/atf/atf-check/Makefile
new file mode 100644
index 0000000000000..fafb1e40d6536
--- /dev/null
+++ b/libexec/atf/atf-check/Makefile
@@ -0,0 +1,45 @@
+#-
+# Copyright (c) 2011 Google, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+.include <bsd.init.mk>
+
+.PATH: ${ATF}/atf-sh
+
+BINDIR= /usr/libexec
+PROG_CXX= atf-check
+SRCS= atf-check.cpp
+MAN= atf-check.1
+
+CFLAGS+= -I${ATF}
+
+DPADD+= ${LIBATF_CXX} ${LIBATF_C}
+
+LDFLAGS+= -L${.OBJDIR}/../../../lib/atf/libatf-c++
+LDFLAGS+= -L${.OBJDIR}/../../../lib/atf/libatf-c
+LDADD+= -latf-c++ -latf-c
+
+.include <bsd.prog.mk>
diff --git a/libexec/atrun/atrun.c b/libexec/atrun/atrun.c
index e4fc625fe3eef..8b0315e94451b 100644
--- a/libexec/atrun/atrun.c
+++ b/libexec/atrun/atrun.c
@@ -33,6 +33,9 @@ static const char rcsid[] =
#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#ifdef __FreeBSD__
+#include <sys/sysctl.h>
+#endif
#include <sys/wait.h>
#include <sys/param.h>
#include <ctype.h>
@@ -123,7 +126,7 @@ run_file(const char *filename, uid_t uid, gid_t gid)
pid_t pid;
int fd_out, fd_in;
int queue;
- char mailbuf[MAXLOGNAME], fmt[49];
+ char mailbuf[MAXLOGNAME], fmt[64];
char *mailname = NULL;
FILE *stream;
int send_mail = 0;
@@ -454,7 +457,12 @@ main(int argc, char *argv[])
gid_t batch_gid;
int c;
int run_batch;
+#ifdef __FreeBSD__
+ size_t ncpu, ncpusz;
+ double load_avg = -1;
+#else
double load_avg = LOADAVG_MX;
+#endif
/* We don't need root privileges all the time; running under uid and gid daemon
* is fine.
@@ -472,8 +480,10 @@ main(int argc, char *argv[])
case 'l':
if (sscanf(optarg, "%lf", &load_avg) != 1)
perr("garbled option -l");
+#ifndef __FreeBSD__
if (load_avg <= 0.)
load_avg = LOADAVG_MX;
+#endif
break;
case 'd':
@@ -489,6 +499,15 @@ main(int argc, char *argv[])
if (chdir(ATJOB_DIR) != 0)
perr("cannot change to %s", ATJOB_DIR);
+#ifdef __FreeBSD__
+ if (load_avg <= 0.) {
+ ncpusz = sizeof(size_t);
+ if (sysctlbyname("hw.ncpu", &ncpu, &ncpusz, NULL, 0) < 0)
+ ncpu = 1;
+ load_avg = LOADAVG_MX * ncpu;
+ }
+#endif
+
/* Main loop. Open spool directory for reading and look over all the
* files in there. If the filename indicates that the job should be run
* and the x bit is set, fork off a child which sets its user and group
diff --git a/libexec/atrun/atrun.man b/libexec/atrun/atrun.man
index ec373b3420bcc..cea322f6d1e21 100644
--- a/libexec/atrun/atrun.man
+++ b/libexec/atrun/atrun.man
@@ -1,5 +1,5 @@
.\" $FreeBSD$
-.Dd June 17, 2007
+.Dd October 30, 2012
.Dt ATRUN 8
.Os
.Sh NAME
@@ -45,7 +45,7 @@ e.g., locked out or expired.
.Bl -tag -width indent
.It Fl l Ar load_avg
Specify a limiting load factor, over which batch jobs should
-not be run, instead of the compiled in default of 1.5.
+not be run, instead of the default of 1.5 * number of active CPUs.
.It Fl d
Debug; print error messages to standard error instead of using
.Xr syslog 3 .
diff --git a/libexec/comsat/comsat.8 b/libexec/comsat/comsat.8
index 1f35cff9a0c68..55976025b6ad9 100644
--- a/libexec/comsat/comsat.8
+++ b/libexec/comsat/comsat.8
@@ -32,7 +32,7 @@
.\" @(#)comsat.8 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd July 9, 2002
+.Dd January 21, 2010
.Dt COMSAT 8
.Os
.Sh NAME
diff --git a/libexec/ftpd/ftpd.8 b/libexec/ftpd/ftpd.8
index 543e1c0a50333..f7dbc88af48ed 100644
--- a/libexec/ftpd/ftpd.8
+++ b/libexec/ftpd/ftpd.8
@@ -32,7 +32,7 @@
.\" @(#)ftpd.8 8.2 (Berkeley) 4/19/94
.\" $FreeBSD$
.\"
-.Dd April 20, 2007
+.Dd January 21, 2010
.Dt FTPD 8
.Os
.Sh NAME
diff --git a/libexec/rbootd/rbootd.c b/libexec/rbootd/rbootd.c
index e56a3e77a428f..1d35bd1e2eeba 100644
--- a/libexec/rbootd/rbootd.c
+++ b/libexec/rbootd/rbootd.c
@@ -310,16 +310,15 @@ void
DoTimeout(void)
{
RMPCONN *rtmp;
- struct timeval now;
-
- (void) gettimeofday(&now, (struct timezone *)0);
+ time_t now;
/*
* For each active connection, if RMP_TIMEOUT seconds have passed
* since the last packet was sent, delete the connection.
*/
+ now = time(NULL);
for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next)
- if ((rtmp->tstamp.tv_sec + RMP_TIMEOUT) < now.tv_sec) {
+ if ((rtmp->tstamp.tv_sec + RMP_TIMEOUT) < now) {
syslog(LOG_WARNING, "%s: connection timed out (%u)",
EnetStr(rtmp), rtmp->rmp.r_type);
RemoveConn(rtmp);
diff --git a/libexec/rbootd/rmpproto.c b/libexec/rbootd/rmpproto.c
index 8d51445165ade..d37ef852415ae 100644
--- a/libexec/rbootd/rmpproto.c
+++ b/libexec/rbootd/rmpproto.c
@@ -575,7 +575,7 @@ SendPacket(RMPCONN *rconn)
/*
* Last time this connection was active.
*/
- (void) gettimeofday(&rconn->tstamp, (struct timezone *)0);
+ (void)gettimeofday(&rconn->tstamp, NULL);
if (DbgFp != NULL) /* display packet */
DispPkt(rconn,DIR_SENT);
diff --git a/libexec/revnetgroup/revnetgroup.8 b/libexec/revnetgroup/revnetgroup.8
index 84cf9f91b007c..f48c327508d8d 100644
--- a/libexec/revnetgroup/revnetgroup.8
+++ b/libexec/revnetgroup/revnetgroup.8
@@ -55,7 +55,7 @@ with a particular member.
This information is used to generate the
.Pa netgroup.byuser
and
-.Pa netgroup.byhosts
+.Pa netgroup.byhost
.Tn NIS
maps.
These reverse netgroup maps are used to help speed up
@@ -72,7 +72,7 @@ netgroup is considered the
and the member names are the
.Em data .
By contrast, the reverse
-.Pa netgroup.byusers
+.Pa netgroup.byuser
database lists each unique
member as the key and the netgroups to which the members belong become
the data.
diff --git a/libexec/rpc.rstatd/rstat_proc.c b/libexec/rpc.rstatd/rstat_proc.c
index 76911c8bd370f..1b66c644623f6 100644
--- a/libexec/rpc.rstatd/rstat_proc.c
+++ b/libexec/rpc.rstatd/rstat_proc.c
@@ -244,7 +244,7 @@ updatestat(void)
FETCH_CNT(stats_all.s1.v_pswpout, vm.v_swappgsout);
FETCH_CNT(stats_all.s1.v_intr, sys.v_intr);
FETCH_CNT(stats_all.s2.v_swtch, sys.v_swtch);
- gettimeofday(&tm, (struct timezone *) 0);
+ (void)gettimeofday(&tm, NULL);
stats_all.s1.v_intr -= hz*(tm.tv_sec - btm.tv_sec) +
hz*(tm.tv_usec - btm.tv_usec)/1000000;
@@ -287,8 +287,9 @@ updatestat(void)
stats_all.s1.if_oerrors += ifmd.ifmd_data.ifi_oerrors;
stats_all.s1.if_collisions += ifmd.ifmd_data.ifi_collisions;
}
- gettimeofday((struct timeval *)&stats_all.s3.curtime,
- (struct timezone *) 0);
+ (void)gettimeofday(&tm, NULL);
+ stats_all.s3.curtime.tv_sec = tm.tv_sec;
+ stats_all.s3.curtime.tv_usec = tm.tv_usec;
alarm(1);
}
diff --git a/libexec/rpc.rusersd/Makefile b/libexec/rpc.rusersd/Makefile
index 6305343ff9f9b..df2be379d0865 100644
--- a/libexec/rpc.rusersd/Makefile
+++ b/libexec/rpc.rusersd/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
PROG = rpc.rusersd
-SRCS = rusersd.c rusers_proc.c
+SRCS = rusersd.c rusers_proc.c extern.h
MAN = rpc.rusersd.8
DPADD= ${LIBRPCSVC} ${LIBUTIL}
diff --git a/libexec/rpc.rusersd/extern.h b/libexec/rpc.rusersd/extern.h
new file mode 100644
index 0000000000000..b1a8309bf85f9
--- /dev/null
+++ b/libexec/rpc.rusersd/extern.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 1993, John Brezak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+extern int from_inetd;
+
+void rusers_service(struct svc_req *, SVCXPRT *);
diff --git a/libexec/rpc.rusersd/rusers_proc.c b/libexec/rpc.rusersd/rusers_proc.c
index 6b34fa72cd286..ff2ebc4c63ed1 100644
--- a/libexec/rpc.rusersd/rusers_proc.c
+++ b/libexec/rpc.rusersd/rusers_proc.c
@@ -53,6 +53,8 @@ static const char rcsid[] =
#endif
#include <rpcsvc/rnusers.h>
+#include "extern.h"
+
#ifndef _PATH_DEV
#define _PATH_DEV "/dev"
#endif
@@ -61,10 +63,6 @@ static utmpidle utmp_idle[MAXUSERS];
static utmp old_utmp[MAXUSERS];
static struct utmpx utmp_list[MAXUSERS];
-extern int from_inetd;
-
-void rusers_service(struct svc_req *, SVCXPRT *);
-
#ifdef XIDLE
static Display *dpy;
diff --git a/libexec/rpc.rusersd/rusersd.c b/libexec/rpc.rusersd/rusersd.c
index 009bbfde85e4b..0ad468650a9f5 100644
--- a/libexec/rpc.rusersd/rusersd.c
+++ b/libexec/rpc.rusersd/rusersd.c
@@ -43,7 +43,7 @@ static const char rcsid[] =
#include <syslog.h>
#include <rpcsvc/rnusers.h>
-extern void rusers_service(struct svc_req *, SVCXPRT *);
+#include "extern.h"
int from_inetd = 1;
diff --git a/libexec/rshd/rshd.8 b/libexec/rshd/rshd.8
index cd4021a8104ef..27f39db078e19 100644
--- a/libexec/rshd/rshd.8
+++ b/libexec/rshd/rshd.8
@@ -237,7 +237,6 @@ and is not preceded by a flag byte.
.Xr gethostbyaddr 3 ,
.Xr rcmd 3 ,
.Xr ruserok 3 ,
-.Xr auth.conf 5 ,
.Xr hosts 5 ,
.Xr hosts.equiv 5 ,
.Xr login.conf 5 ,
diff --git a/libexec/rtld-aout/shlib.c b/libexec/rtld-aout/shlib.c
index 5cfa3f3f128ab..70c5313224822 100644
--- a/libexec/rtld-aout/shlib.c
+++ b/libexec/rtld-aout/shlib.c
@@ -62,7 +62,7 @@
char **search_dirs;
int n_search_dirs;
-const char *standard_search_dirs[] = {
+static const char *standard_search_dirs[] = {
STANDARD_SEARCH_DIRS
};
diff --git a/libexec/rtld-elf/arm/reloc.c b/libexec/rtld-elf/arm/reloc.c
index 005c468af74c6..715cb7e8e7ed4 100644
--- a/libexec/rtld-elf/arm/reloc.c
+++ b/libexec/rtld-elf/arm/reloc.c
@@ -433,7 +433,9 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *defobj,
void
allocate_initial_tls(Obj_Entry *objs)
{
+#ifdef ARM_TP_ADDRESS
void **_tp = (void **)ARM_TP_ADDRESS;
+#endif
/*
* Fix the size of the static TLS block by using the maximum
@@ -443,16 +445,27 @@ allocate_initial_tls(Obj_Entry *objs)
tls_static_space = tls_last_offset + tls_last_size + RTLD_STATIC_TLS_EXTRA;
+#ifdef ARM_TP_ADDRESS
(*_tp) = (void *) allocate_tls(objs, NULL, TLS_TCB_SIZE, 8);
+#else
+ sysarch(ARM_SET_TP, allocate_tls(objs, NULL, TLS_TCB_SIZE, 8));
+#endif
}
void *
__tls_get_addr(tls_index* ti)
{
- void **_tp = (void **)ARM_TP_ADDRESS;
char *p;
+#ifdef ARM_TP_ADDRESS
+ void **_tp = (void **)ARM_TP_ADDRESS;
p = tls_get_addr_common((Elf_Addr **)(*_tp), ti->ti_module, ti->ti_offset);
+#else
+ void *_tp;
+ __asm __volatile("mrc p15, 0, %0, c13, c0, 3" \
+ : "=r" (_tp));
+ p = tls_get_addr_common((Elf_Addr **)(_tp), ti->ti_module, ti->ti_offset);
+#endif
return (p);
}
diff --git a/libexec/rtld-elf/arm/rtld_start.S b/libexec/rtld-elf/arm/rtld_start.S
index b9de767d362e4..7a4fae4f0172e 100644
--- a/libexec/rtld-elf/arm/rtld_start.S
+++ b/libexec/rtld-elf/arm/rtld_start.S
@@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$");
.globl .rtld_start
.type .rtld_start,%function
.rtld_start:
+ mov r6, sp /* save the stack pointer */
+ bic sp, sp, #7 /* align the stack pointer */
sub sp, sp, #8 /* make room for obj_main & exit proc */
mov r4, r0 /* save ps_strings */
ldr sl, .L2
@@ -52,13 +54,13 @@ __FBSDID("$FreeBSD$");
bl _rtld_relocate_nonplt_self
mov r1, sp
add r2, sp, #4
- add r0, sp, #8
+ mov r0, r6 /* load the sp the kernel gave us */
bl _rtld /* call the shared loader */
mov r3, r0 /* save entry point */
ldr r2, [sp, #0] /* r2 = cleanup */
ldr r1, [sp, #4] /* r1 = obj_main */
- add sp, sp, #8 /* restore stack */
+ mov sp, r6 /* restore stack */
mov r0, r4 /* restore ps_strings */
mov pc, r3 /* jump to the entry point */
.L2:
diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c
index d74ef15544998..79e4132298be6 100644
--- a/libexec/rtld-elf/map_object.c
+++ b/libexec/rtld-elf/map_object.c
@@ -38,7 +38,7 @@
#include "debug.h"
#include "rtld.h"
-static Elf_Ehdr *get_elf_header (int, const char *);
+static Elf_Ehdr *get_elf_header(int, const char *);
static int convert_prot(int); /* Elf flags -> mmap protection */
static int convert_flags(int); /* Elf flags -> mmap flags */
@@ -121,7 +121,7 @@ map_object(int fd, const char *path, const struct stat *sb)
if ((segs[nsegs]->p_align & (PAGE_SIZE - 1)) != 0) {
_rtld_error("%s: PT_LOAD segment %d not page-aligned",
path, nsegs);
- return NULL;
+ goto error;
}
break;
@@ -153,7 +153,6 @@ map_object(int fd, const char *path, const struct stat *sb)
break;
note_start = (Elf_Addr)(char *)hdr + phdr->p_offset;
note_end = note_start + phdr->p_filesz;
- digest_notes(obj, note_start, note_end);
break;
}
@@ -161,12 +160,12 @@ map_object(int fd, const char *path, const struct stat *sb)
}
if (phdyn == NULL) {
_rtld_error("%s: object is not dynamically-linked", path);
- return NULL;
+ goto error;
}
if (nsegs < 0) {
_rtld_error("%s: too few PT_LOAD segments", path);
- return NULL;
+ goto error;
}
/*
@@ -183,13 +182,12 @@ map_object(int fd, const char *path, const struct stat *sb)
if (mapbase == (caddr_t) -1) {
_rtld_error("%s: mmap of entire address space failed: %s",
path, rtld_strerror(errno));
- return NULL;
+ goto error;
}
if (base_addr != NULL && mapbase != base_addr) {
_rtld_error("%s: mmap returned wrong address: wanted %p, got %p",
path, base_addr, mapbase);
- munmap(mapbase, mapsize);
- return NULL;
+ goto error1;
}
for (i = 0; i <= nsegs; i++) {
@@ -201,10 +199,10 @@ map_object(int fd, const char *path, const struct stat *sb)
data_prot = convert_prot(segs[i]->p_flags);
data_flags = convert_flags(segs[i]->p_flags) | MAP_FIXED;
if (mmap(data_addr, data_vlimit - data_vaddr, data_prot,
- data_flags, fd, data_offset) == (caddr_t) -1) {
+ data_flags | MAP_PREFAULT_READ, fd, data_offset) == (caddr_t) -1) {
_rtld_error("%s: mmap of data failed: %s", path,
rtld_strerror(errno));
- return NULL;
+ goto error1;
}
/* Do BSS setup */
@@ -221,7 +219,7 @@ map_object(int fd, const char *path, const struct stat *sb)
mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE)) {
_rtld_error("%s: mprotect failed: %s", path,
rtld_strerror(errno));
- return NULL;
+ goto error1;
}
memset(clear_addr, 0, nclear);
@@ -240,7 +238,7 @@ map_object(int fd, const char *path, const struct stat *sb)
data_flags | MAP_ANON, -1, 0) == (caddr_t)-1) {
_rtld_error("%s: mmap of bss failed: %s", path,
rtld_strerror(errno));
- return NULL;
+ goto error1;
}
}
}
@@ -273,7 +271,7 @@ map_object(int fd, const char *path, const struct stat *sb)
if (obj->phdr == NULL) {
obj_free(obj);
_rtld_error("%s: cannot allocate program header", path);
- return NULL;
+ goto error1;
}
memcpy((char *)obj->phdr, (char *)hdr + hdr->e_phoff, phsize);
obj->phdr_alloc = true;
@@ -292,64 +290,74 @@ map_object(int fd, const char *path, const struct stat *sb)
obj->stack_flags = stack_flags;
obj->relro_page = obj->relocbase + trunc_page(relro_page);
obj->relro_size = round_page(relro_size);
+ if (note_start < note_end)
+ digest_notes(obj, note_start, note_end);
+ munmap(hdr, PAGE_SIZE);
+ return (obj);
- return obj;
+error1:
+ munmap(mapbase, mapsize);
+error:
+ munmap(hdr, PAGE_SIZE);
+ return (NULL);
}
static Elf_Ehdr *
-get_elf_header (int fd, const char *path)
+get_elf_header(int fd, const char *path)
{
- static union {
- Elf_Ehdr hdr;
- char buf[PAGE_SIZE];
- } u;
- ssize_t nbytes;
+ Elf_Ehdr *hdr;
- if ((nbytes = pread(fd, u.buf, PAGE_SIZE, 0)) == -1) {
- _rtld_error("%s: read error: %s", path, rtld_strerror(errno));
- return NULL;
- }
+ hdr = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE | MAP_PREFAULT_READ,
+ fd, 0);
+ if (hdr == (Elf_Ehdr *)MAP_FAILED) {
+ _rtld_error("%s: read error: %s", path, rtld_strerror(errno));
+ return (NULL);
+ }
- /* Make sure the file is valid */
- if (nbytes < (ssize_t)sizeof(Elf_Ehdr) || !IS_ELF(u.hdr)) {
- _rtld_error("%s: invalid file format", path);
- return NULL;
- }
- if (u.hdr.e_ident[EI_CLASS] != ELF_TARG_CLASS
- || u.hdr.e_ident[EI_DATA] != ELF_TARG_DATA) {
- _rtld_error("%s: unsupported file layout", path);
- return NULL;
- }
- if (u.hdr.e_ident[EI_VERSION] != EV_CURRENT
- || u.hdr.e_version != EV_CURRENT) {
- _rtld_error("%s: unsupported file version", path);
- return NULL;
- }
- if (u.hdr.e_type != ET_EXEC && u.hdr.e_type != ET_DYN) {
- _rtld_error("%s: unsupported file type", path);
- return NULL;
- }
- if (u.hdr.e_machine != ELF_TARG_MACH) {
- _rtld_error("%s: unsupported machine", path);
- return NULL;
- }
+ /* Make sure the file is valid */
+ if (!IS_ELF(*hdr)) {
+ _rtld_error("%s: invalid file format", path);
+ goto error;
+ }
+ if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
+ hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
+ _rtld_error("%s: unsupported file layout", path);
+ goto error;
+ }
+ if (hdr->e_ident[EI_VERSION] != EV_CURRENT ||
+ hdr->e_version != EV_CURRENT) {
+ _rtld_error("%s: unsupported file version", path);
+ goto error;
+ }
+ if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) {
+ _rtld_error("%s: unsupported file type", path);
+ goto error;
+ }
+ if (hdr->e_machine != ELF_TARG_MACH) {
+ _rtld_error("%s: unsupported machine", path);
+ goto error;
+ }
- /*
- * We rely on the program header being in the first page. This is
- * not strictly required by the ABI specification, but it seems to
- * always true in practice. And, it simplifies things considerably.
- */
- if (u.hdr.e_phentsize != sizeof(Elf_Phdr)) {
- _rtld_error(
- "%s: invalid shared object: e_phentsize != sizeof(Elf_Phdr)", path);
- return NULL;
- }
- if (u.hdr.e_phoff + u.hdr.e_phnum * sizeof(Elf_Phdr) > (size_t)nbytes) {
- _rtld_error("%s: program header too large", path);
- return NULL;
- }
+ /*
+ * We rely on the program header being in the first page. This is
+ * not strictly required by the ABI specification, but it seems to
+ * always true in practice. And, it simplifies things considerably.
+ */
+ if (hdr->e_phentsize != sizeof(Elf_Phdr)) {
+ _rtld_error(
+ "%s: invalid shared object: e_phentsize != sizeof(Elf_Phdr)", path);
+ goto error;
+ }
+ if (hdr->e_phoff + hdr->e_phnum * sizeof(Elf_Phdr) >
+ (size_t)PAGE_SIZE) {
+ _rtld_error("%s: program header too large", path);
+ goto error;
+ }
+ return (hdr);
- return (&u.hdr);
+error:
+ munmap(hdr, PAGE_SIZE);
+ return (NULL);
}
void
diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1
index f77b150dbaccf..703a462e8d600 100644
--- a/libexec/rtld-elf/rtld.1
+++ b/libexec/rtld-elf/rtld.1
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 1, 2009
+.Dd June 28, 2012
.Dt RTLD 1
.Os
.Sh NAME
@@ -86,14 +86,39 @@ dynamic linker.
After the dynamic linker has finished loading,
relocating, and initializing the program and its required shared
objects, it transfers control to the entry point of the program.
+The following search order is used to locate required shared objects:
.Pp
-To locate the required shared objects in the file system,
-.Nm
-may use a
-.Dq hints
-file prepared by the
+.Bl -enum -offset indent -compact
+.It
+.Dv DT_RPATH
+of the referencing object unless that object also contains a
+.Dv DT_RUNPATH
+tag
+.It
+.Dv DT_RPATH
+of the program unless the referencing object contains a
+.Dv DT_RUNPATH
+tag
+.It
+Path indicated by
+.Ev LD_LIBRARY_PATH
+environment variable
+.It
+.Dv DT_RUNPATH
+of the referencing object
+.It
+Hints file produced by the
.Xr ldconfig 8
-utility.
+utility
+.It
+The
+.Pa /lib
+and
+.Pa /usr/lib
+directories, unless the referencing object was linked using the
+.Dq Fl z Ar nodefaultlib
+option
+.El
.Pp
The
.Nm
@@ -143,6 +168,20 @@ This variable is unset for set-user-ID and set-group-ID programs.
A colon separated list of directories, overriding the default search path
for shared libraries.
This variable is unset for set-user-ID and set-group-ID programs.
+.It Ev LD_LIBRARY_PATH_RPATH
+If the variable is specified and has a value starting with
+any of \'y\', \'Y\' or \'1\' symbols, the path specified by
+.Ev LD_LIBRARY_PATH
+variable is allowed to override the path from
+.Dv DT_RPATH
+for binaries which does not contain
+.Dv DT_RUNPATH
+tag.
+For such binaries, when the variable
+.Ev LD_LIBRARY_PATH_RPATH
+is set,
+.Dq Fl z Ar nodefaultlib
+link-time option is ignored as well.
.It Ev LD_PRELOAD
A list of shared libraries, separated by colons and/or white space,
to be linked in before any
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 621d084b0ed87..1a7010e81e90f 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -80,8 +80,9 @@ typedef void * (*path_enum_proc) (const char *path, size_t len, void *arg);
static const char *basename(const char *);
static void die(void) __dead2;
static void digest_dynamic1(Obj_Entry *, int, const Elf_Dyn **,
- const Elf_Dyn **);
-static void digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *);
+ const Elf_Dyn **, const Elf_Dyn **);
+static void digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *,
+ const Elf_Dyn *);
static void digest_dynamic(Obj_Entry *, int);
static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *);
static Obj_Entry *dlcheck(void *);
@@ -94,7 +95,7 @@ static void errmsg_restore(char *);
static char *errmsg_save(void);
static void *fill_search_info(const char *, size_t, void *);
static char *find_library(const char *, const Obj_Entry *);
-static const char *gethints(void);
+static const char *gethints(bool);
static void init_dag(Obj_Entry *);
static void init_rtld(caddr_t, Elf_Auxinfo **);
static void initlist_add_neededs(Needed_Entry *, Objlist *);
@@ -117,6 +118,10 @@ static void objlist_push_head(Objlist *, Obj_Entry *);
static void objlist_push_tail(Objlist *, Obj_Entry *);
static void objlist_remove(Objlist *, Obj_Entry *);
static void *path_enumerate(const char *, path_enum_proc, void *);
+static int relocate_object_dag(Obj_Entry *root, bool bind_now,
+ Obj_Entry *rtldobj, int flags, RtldLockState *lockstate);
+static int relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
+ int flags, RtldLockState *lockstate);
static int relocate_objects(Obj_Entry *, bool, Obj_Entry *, int,
RtldLockState *);
static int resolve_objects_ifunc(Obj_Entry *first, bool bind_now,
@@ -229,6 +234,8 @@ size_t tls_static_space; /* Static TLS space allocated */
int tls_dtv_generation = 1; /* Used to detect when dtv size changes */
int tls_max_index = 1; /* Largest module index allocated */
+bool ld_library_path_rpath = false;
+
/*
* Fill in a DoneList with an allocation large enough to hold all of
* the currently-loaded objects. Keep this as a macro since it calls
@@ -319,6 +326,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
Obj_Entry **preload_tail;
Objlist initlist;
RtldLockState lockstate;
+ char *library_path_rpath;
int mib[2];
size_t len;
@@ -390,7 +398,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
if (unsetenv(LD_ "PRELOAD") || unsetenv(LD_ "LIBMAP") ||
unsetenv(LD_ "LIBRARY_PATH") || unsetenv(LD_ "LIBMAP_DISABLE") ||
unsetenv(LD_ "DEBUG") || unsetenv(LD_ "ELF_HINTS_PATH") ||
- unsetenv(LD_ "LOADFLTR")) {
+ unsetenv(LD_ "LOADFLTR") || unsetenv(LD_ "LIBRARY_PATH_RPATH")) {
_rtld_error("environment corrupt; aborting");
die();
}
@@ -402,6 +410,15 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
ld_preload = getenv(LD_ "PRELOAD");
ld_elf_hints_path = getenv(LD_ "ELF_HINTS_PATH");
ld_loadfltr = getenv(LD_ "LOADFLTR") != NULL;
+ library_path_rpath = getenv(LD_ "LIBRARY_PATH_RPATH");
+ if (library_path_rpath != NULL) {
+ if (library_path_rpath[0] == 'y' ||
+ library_path_rpath[0] == 'Y' ||
+ library_path_rpath[0] == '1')
+ ld_library_path_rpath = true;
+ else
+ ld_library_path_rpath = false;
+ }
dangerous_ld_env = libmap_disable || (libmap_override != NULL) ||
(ld_library_path != NULL) || (ld_preload != NULL) ||
(ld_elf_hints_path != NULL) || ld_loadfltr;
@@ -824,7 +841,7 @@ die(void)
*/
static void
digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
- const Elf_Dyn **dyn_soname)
+ const Elf_Dyn **dyn_soname, const Elf_Dyn **dyn_runpath)
{
const Elf_Dyn *dynp;
Needed_Entry **needed_tail = &obj->needed;
@@ -839,6 +856,7 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
*dyn_rpath = NULL;
*dyn_soname = NULL;
+ *dyn_runpath = NULL;
obj->bind_now = false;
for (dynp = obj->dynamic; dynp->d_tag != DT_NULL; dynp++) {
@@ -1005,7 +1023,6 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
break;
case DT_RPATH:
- case DT_RUNPATH: /* XXX: process separately */
/*
* We have to wait until later to process this, because we
* might not have gotten the address of the string table yet.
@@ -1017,6 +1034,10 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
*dyn_soname = dynp;
break;
+ case DT_RUNPATH:
+ *dyn_runpath = dynp;
+ break;
+
case DT_INIT:
obj->init = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
break;
@@ -1110,6 +1131,8 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
obj->z_nodelete = true;
if (dynp->d_un.d_val & DF_1_LOADFLTR)
obj->z_loadfltr = true;
+ if (dynp->d_un.d_val & DF_1_NODEFLIB)
+ obj->z_nodeflib = true;
break;
default:
@@ -1149,7 +1172,7 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
static void
digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath,
- const Elf_Dyn *dyn_soname)
+ const Elf_Dyn *dyn_soname, const Elf_Dyn *dyn_runpath)
{
if (obj->z_origin && obj->origin_path == NULL) {
@@ -1158,7 +1181,12 @@ digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath,
die();
}
- if (dyn_rpath != NULL) {
+ if (dyn_runpath != NULL) {
+ obj->runpath = (char *)obj->strtab + dyn_runpath->d_un.d_val;
+ if (obj->z_origin)
+ obj->runpath = origin_subst(obj->runpath, obj->origin_path);
+ }
+ else if (dyn_rpath != NULL) {
obj->rpath = (char *)obj->strtab + dyn_rpath->d_un.d_val;
if (obj->z_origin)
obj->rpath = origin_subst(obj->rpath, obj->origin_path);
@@ -1173,9 +1201,10 @@ digest_dynamic(Obj_Entry *obj, int early)
{
const Elf_Dyn *dyn_rpath;
const Elf_Dyn *dyn_soname;
+ const Elf_Dyn *dyn_runpath;
- digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname);
- digest_dynamic2(obj, dyn_rpath, dyn_soname);
+ digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname, &dyn_runpath);
+ digest_dynamic2(obj, dyn_rpath, dyn_soname, dyn_runpath);
}
/*
@@ -1385,43 +1414,71 @@ gnu_hash(const char *s)
* loaded shared object, whose library search path will be searched.
*
* The search order is:
+ * DT_RPATH in the referencing file _unless_ DT_RUNPATH is present (1)
+ * DT_RPATH of the main object if DSO without defined DT_RUNPATH (1)
* LD_LIBRARY_PATH
- * rpath in the referencing file
- * ldconfig hints
- * /lib:/usr/lib
+ * DT_RUNPATH in the referencing file
+ * ldconfig hints (if -z nodefaultlib, filter out default library directories
+ * from list)
+ * /lib:/usr/lib _unless_ the referencing file is linked with -z nodefaultlib
+ *
+ * (1) Handled in digest_dynamic2 - rpath left NULL if runpath defined.
*/
static char *
find_library(const char *xname, const Obj_Entry *refobj)
{
char *pathname;
char *name;
+ bool nodeflib, objgiven;
+ objgiven = refobj != NULL;
if (strchr(xname, '/') != NULL) { /* Hard coded pathname */
if (xname[0] != '/' && !trust) {
_rtld_error("Absolute pathname required for shared object \"%s\"",
xname);
return NULL;
}
- if (refobj != NULL && refobj->z_origin)
+ if (objgiven && refobj->z_origin)
return origin_subst(xname, refobj->origin_path);
else
return xstrdup(xname);
}
- if (libmap_disable || (refobj == NULL) ||
+ if (libmap_disable || !objgiven ||
(name = lm_find(refobj->path, xname)) == NULL)
name = (char *)xname;
dbg(" Searching for \"%s\"", name);
- if ((pathname = search_library_path(name, ld_library_path)) != NULL ||
- (refobj != NULL &&
- (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
- (pathname = search_library_path(name, gethints())) != NULL ||
- (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)
- return pathname;
+ /*
+ * If refobj->rpath != NULL, then refobj->runpath is NULL. Fall
+ * back to pre-conforming behaviour if user requested so with
+ * LD_LIBRARY_PATH_RPATH environment variable and ignore -z
+ * nodeflib.
+ */
+ if (objgiven && refobj->rpath != NULL && ld_library_path_rpath) {
+ if ((pathname = search_library_path(name, ld_library_path)) != NULL ||
+ (refobj != NULL &&
+ (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
+ (pathname = search_library_path(name, gethints(false))) != NULL ||
+ (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)
+ return (pathname);
+ } else {
+ nodeflib = objgiven ? refobj->z_nodeflib : false;
+ if ((objgiven &&
+ (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
+ (objgiven && refobj->runpath == NULL && refobj != obj_main &&
+ (pathname = search_library_path(name, obj_main->rpath)) != NULL) ||
+ (pathname = search_library_path(name, ld_library_path)) != NULL ||
+ (objgiven &&
+ (pathname = search_library_path(name, refobj->runpath)) != NULL) ||
+ (pathname = search_library_path(name, gethints(nodeflib))) != NULL ||
+ (objgiven && !nodeflib &&
+ (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL))
+ return (pathname);
+ }
- if(refobj != NULL && refobj->path != NULL) {
+ if (objgiven && refobj->path != NULL) {
_rtld_error("Shared object \"%s\" not found, required by \"%s\"",
name, basename(refobj->path));
} else {
@@ -1516,41 +1573,142 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj,
/*
* Return the search path from the ldconfig hints file, reading it if
- * necessary. Returns NULL if there are problems with the hints file,
+ * necessary. If nostdlib is true, then the default search paths are
+ * not added to result.
+ *
+ * Returns NULL if there are problems with the hints file,
* or if the search path there is empty.
*/
static const char *
-gethints(void)
+gethints(bool nostdlib)
{
- static char *hints;
-
- if (hints == NULL) {
- int fd;
+ static char *hints, *filtered_path;
struct elfhints_hdr hdr;
+ struct fill_search_info_args sargs, hargs;
+ struct dl_serinfo smeta, hmeta, *SLPinfo, *hintinfo;
+ struct dl_serpath *SLPpath, *hintpath;
char *p;
+ unsigned int SLPndx, hintndx, fndx, fcount;
+ int fd;
+ size_t flen;
+ bool skip;
- /* Keep from trying again in case the hints file is bad. */
- hints = "";
+ /* First call, read the hints file */
+ if (hints == NULL) {
+ /* Keep from trying again in case the hints file is bad. */
+ hints = "";
- if ((fd = open(ld_elf_hints_path, O_RDONLY)) == -1)
- return NULL;
- if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
- hdr.magic != ELFHINTS_MAGIC ||
- hdr.version != 1) {
- close(fd);
- return NULL;
+ if ((fd = open(ld_elf_hints_path, O_RDONLY)) == -1)
+ return (NULL);
+ if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
+ hdr.magic != ELFHINTS_MAGIC ||
+ hdr.version != 1) {
+ close(fd);
+ return (NULL);
+ }
+ p = xmalloc(hdr.dirlistlen + 1);
+ if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 ||
+ read(fd, p, hdr.dirlistlen + 1) !=
+ (ssize_t)hdr.dirlistlen + 1) {
+ free(p);
+ close(fd);
+ return (NULL);
+ }
+ hints = p;
+ close(fd);
}
- p = xmalloc(hdr.dirlistlen + 1);
- if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 ||
- read(fd, p, hdr.dirlistlen + 1) != (ssize_t)hdr.dirlistlen + 1) {
- free(p);
- close(fd);
- return NULL;
+
+ /*
+ * If caller agreed to receive list which includes the default
+ * paths, we are done. Otherwise, if we still did not
+ * calculated filtered result, do it now.
+ */
+ if (!nostdlib)
+ return (hints[0] != '\0' ? hints : NULL);
+ if (filtered_path != NULL)
+ goto filt_ret;
+
+ /*
+ * Obtain the list of all configured search paths, and the
+ * list of the default paths.
+ *
+ * First estimate the size of the results.
+ */
+ smeta.dls_size = __offsetof(struct dl_serinfo, dls_serpath);
+ smeta.dls_cnt = 0;
+ hmeta.dls_size = __offsetof(struct dl_serinfo, dls_serpath);
+ hmeta.dls_cnt = 0;
+
+ sargs.request = RTLD_DI_SERINFOSIZE;
+ sargs.serinfo = &smeta;
+ hargs.request = RTLD_DI_SERINFOSIZE;
+ hargs.serinfo = &hmeta;
+
+ path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &sargs);
+ path_enumerate(p, fill_search_info, &hargs);
+
+ SLPinfo = xmalloc(smeta.dls_size);
+ hintinfo = xmalloc(hmeta.dls_size);
+
+ /*
+ * Next fetch both sets of paths.
+ */
+ sargs.request = RTLD_DI_SERINFO;
+ sargs.serinfo = SLPinfo;
+ sargs.serpath = &SLPinfo->dls_serpath[0];
+ sargs.strspace = (char *)&SLPinfo->dls_serpath[smeta.dls_cnt];
+
+ hargs.request = RTLD_DI_SERINFO;
+ hargs.serinfo = hintinfo;
+ hargs.serpath = &hintinfo->dls_serpath[0];
+ hargs.strspace = (char *)&hintinfo->dls_serpath[hmeta.dls_cnt];
+
+ path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &sargs);
+ path_enumerate(p, fill_search_info, &hargs);
+
+ /*
+ * Now calculate the difference between two sets, by excluding
+ * standard paths from the full set.
+ */
+ fndx = 0;
+ fcount = 0;
+ filtered_path = xmalloc(hdr.dirlistlen + 1);
+ hintpath = &hintinfo->dls_serpath[0];
+ for (hintndx = 0; hintndx < hmeta.dls_cnt; hintndx++, hintpath++) {
+ skip = false;
+ SLPpath = &SLPinfo->dls_serpath[0];
+ /*
+ * Check each standard path against current.
+ */
+ for (SLPndx = 0; SLPndx < smeta.dls_cnt; SLPndx++, SLPpath++) {
+ /* matched, skip the path */
+ if (!strcmp(hintpath->dls_name, SLPpath->dls_name)) {
+ skip = true;
+ break;
+ }
+ }
+ if (skip)
+ continue;
+ /*
+ * Not matched against any standard path, add the path
+ * to result. Separate consequtive paths with ':'.
+ */
+ if (fcount > 0) {
+ filtered_path[fndx] = ':';
+ fndx++;
+ }
+ fcount++;
+ flen = strlen(hintpath->dls_name);
+ strncpy((filtered_path + fndx), hintpath->dls_name, flen);
+ fndx += flen;
}
- hints = p;
- close(fd);
- }
- return hints[0] != '\0' ? hints : NULL;
+ filtered_path[fndx] = '\0';
+
+ free(SLPinfo);
+ free(hintinfo);
+
+filt_ret:
+ return (filtered_path[0] != '\0' ? filtered_path : NULL);
}
static void
@@ -1585,6 +1743,26 @@ init_dag(Obj_Entry *root)
root->dag_inited = true;
}
+static void
+process_nodelete(Obj_Entry *root)
+{
+ const Objlist_Entry *elm;
+
+ /*
+ * Walk over object DAG and process every dependent object that
+ * is marked as DF_1_NODELETE. They need to grow their own DAG,
+ * which then should have its reference upped separately.
+ */
+ STAILQ_FOREACH(elm, &root->dagmembers, link) {
+ if (elm->obj != NULL && elm->obj->z_nodelete &&
+ !elm->obj->ref_nodel) {
+ dbg("obj %s nodelete", elm->obj->path);
+ init_dag(elm->obj);
+ ref_dag(elm->obj);
+ elm->obj->ref_nodel = true;
+ }
+ }
+}
/*
* Initialize the dynamic linker. The argument is the address at which
* the dynamic linker has been mapped into memory. The primary task of
@@ -1596,6 +1774,7 @@ init_rtld(caddr_t mapbase, Elf_Auxinfo **aux_info)
Obj_Entry objtmp; /* Temporary rtld object */
const Elf_Dyn *dyn_rpath;
const Elf_Dyn *dyn_soname;
+ const Elf_Dyn *dyn_runpath;
/*
* Conjure up an Obj_Entry structure for the dynamic linker.
@@ -1612,7 +1791,7 @@ init_rtld(caddr_t mapbase, Elf_Auxinfo **aux_info)
#endif
if (RTLD_IS_DYNAMIC()) {
objtmp.dynamic = rtld_dynamic(&objtmp);
- digest_dynamic1(&objtmp, 1, &dyn_rpath, &dyn_soname);
+ digest_dynamic1(&objtmp, 1, &dyn_rpath, &dyn_soname, &dyn_runpath);
assert(objtmp.needed == NULL);
#if !defined(__mips__)
/* MIPS has a bogus DT_TEXTREL. */
@@ -1638,7 +1817,7 @@ init_rtld(caddr_t mapbase, Elf_Auxinfo **aux_info)
if (aux_info[AT_OSRELDATE] != NULL)
osreldate = aux_info[AT_OSRELDATE]->a_un.a_val;
- digest_dynamic2(&obj_rtld, dyn_rpath, dyn_soname);
+ digest_dynamic2(&obj_rtld, dyn_rpath, dyn_soname, dyn_runpath);
/* Replace the path with a dynamically allocated copy. */
obj_rtld.path = xstrdup(PATH_RTLD);
@@ -1773,12 +1952,6 @@ process_needed(Obj_Entry *obj, Needed_Entry *needed, int flags)
flags & ~RTLD_LO_NOLOAD);
if (obj1 == NULL && !ld_tracing && (flags & RTLD_LO_FILTEES) == 0)
return (-1);
- if (obj1 != NULL && obj1->z_nodelete && !obj1->ref_nodel) {
- dbg("obj %s nodelete", obj1->path);
- init_dag(obj1);
- ref_dag(obj1);
- obj1->ref_nodel = true;
- }
}
return (0);
}
@@ -2217,52 +2390,70 @@ objlist_remove(Objlist *list, Obj_Entry *obj)
}
/*
- * Relocate newly-loaded shared objects. The argument is a pointer to
- * the Obj_Entry for the first such object. All objects from the first
- * to the end of the list of objects are relocated. Returns 0 on success,
- * or -1 on failure.
+ * Relocate dag rooted in the specified object.
+ * Returns 0 on success, or -1 on failure.
*/
+
static int
-relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj,
+relocate_object_dag(Obj_Entry *root, bool bind_now, Obj_Entry *rtldobj,
+ int flags, RtldLockState *lockstate)
+{
+ Objlist_Entry *elm;
+ int error;
+
+ error = 0;
+ STAILQ_FOREACH(elm, &root->dagmembers, link) {
+ error = relocate_object(elm->obj, bind_now, rtldobj, flags,
+ lockstate);
+ if (error == -1)
+ break;
+ }
+ return (error);
+}
+
+/*
+ * Relocate single object.
+ * Returns 0 on success, or -1 on failure.
+ */
+static int
+relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
int flags, RtldLockState *lockstate)
{
- Obj_Entry *obj;
- for (obj = first; obj != NULL; obj = obj->next) {
if (obj->relocated)
- continue;
+ return (0);
obj->relocated = true;
if (obj != rtldobj)
- dbg("relocating \"%s\"", obj->path);
+ dbg("relocating \"%s\"", obj->path);
if (obj->symtab == NULL || obj->strtab == NULL ||
- !(obj->valid_hash_sysv || obj->valid_hash_gnu)) {
- _rtld_error("%s: Shared object has no run-time symbol table",
- obj->path);
- return -1;
+ !(obj->valid_hash_sysv || obj->valid_hash_gnu)) {
+ _rtld_error("%s: Shared object has no run-time symbol table",
+ obj->path);
+ return (-1);
}
if (obj->textrel) {
- /* There are relocations to the write-protected text segment. */
- if (mprotect(obj->mapbase, obj->textsize,
- PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
- _rtld_error("%s: Cannot write-enable text segment: %s",
- obj->path, rtld_strerror(errno));
- return -1;
- }
+ /* There are relocations to the write-protected text segment. */
+ if (mprotect(obj->mapbase, obj->textsize,
+ PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
+ _rtld_error("%s: Cannot write-enable text segment: %s",
+ obj->path, rtld_strerror(errno));
+ return (-1);
+ }
}
/* Process the non-PLT relocations. */
if (reloc_non_plt(obj, rtldobj, flags, lockstate))
- return -1;
+ return (-1);
if (obj->textrel) { /* Re-protected the text segment. */
- if (mprotect(obj->mapbase, obj->textsize,
- PROT_READ|PROT_EXEC) == -1) {
- _rtld_error("%s: Cannot write-protect text segment: %s",
- obj->path, rtld_strerror(errno));
- return -1;
- }
+ if (mprotect(obj->mapbase, obj->textsize,
+ PROT_READ|PROT_EXEC) == -1) {
+ _rtld_error("%s: Cannot write-protect text segment: %s",
+ obj->path, rtld_strerror(errno));
+ return (-1);
+ }
}
@@ -2271,18 +2462,19 @@ relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj,
/* Process the PLT relocations. */
if (reloc_plt(obj) == -1)
- return -1;
+ return (-1);
/* Relocate the jump slots if we are doing immediate binding. */
if (obj->bind_now || bind_now)
- if (reloc_jmpslots(obj, flags, lockstate) == -1)
- return -1;
+ if (reloc_jmpslots(obj, flags, lockstate) == -1)
+ return (-1);
if (obj->relro_size > 0) {
- if (mprotect(obj->relro_page, obj->relro_size, PROT_READ) == -1) {
- _rtld_error("%s: Cannot enforce relro protection: %s",
- obj->path, rtld_strerror(errno));
- return -1;
- }
+ if (mprotect(obj->relro_page, obj->relro_size,
+ PROT_READ) == -1) {
+ _rtld_error("%s: Cannot enforce relro protection: %s",
+ obj->path, rtld_strerror(errno));
+ return (-1);
+ }
}
/*
@@ -2292,9 +2484,30 @@ relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj,
*/
obj->magic = RTLD_MAGIC;
obj->version = RTLD_VERSION;
- }
- return (0);
+ return (0);
+}
+
+/*
+ * Relocate newly-loaded shared objects. The argument is a pointer to
+ * the Obj_Entry for the first such object. All objects from the first
+ * to the end of the list of objects are relocated. Returns 0 on success,
+ * or -1 on failure.
+ */
+static int
+relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj,
+ int flags, RtldLockState *lockstate)
+{
+ Obj_Entry *obj;
+ int error;
+
+ for (error = 0, obj = first; obj != NULL; obj = obj->next) {
+ error = relocate_object(obj, bind_now, rtldobj, flags,
+ lockstate);
+ if (error == -1)
+ break;
+ }
+ return (error);
}
/*
@@ -2614,10 +2827,10 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
result = rtld_verify_versions(&obj->dagmembers);
if (result != -1 && ld_tracing)
goto trace;
- if (result == -1 || (relocate_objects(obj,
- (mode & RTLD_MODEMASK) == RTLD_NOW, &obj_rtld,
+ if (result == -1 || relocate_object_dag(obj,
+ (mode & RTLD_MODEMASK) == RTLD_NOW, &obj_rtld,
(lo_flags & RTLD_LO_EARLY) ? SYMLOOK_EARLY : 0,
- lockstate)) == -1) {
+ lockstate) == -1) {
dlopen_cleanup(obj);
obj = NULL;
} else if (lo_flags & RTLD_LO_EARLY) {
@@ -2634,8 +2847,15 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
/* Make list of init functions to call. */
initlist_add_objects(obj, &obj->next, &initlist);
}
+ /*
+ * Process all no_delete objects here, given them own
+ * DAGs to prevent their dependencies from being unloaded.
+ * This has to be done after we have loaded all of the
+ * dependencies, so that we do not miss any.
+ */
+ if (obj != NULL)
+ process_nodelete(obj);
} else {
-
/*
* Bump the reference counts for objects on this DAG. If
* this is the first dlopen() call for the object that was
@@ -3026,14 +3246,6 @@ dl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param)
return (error);
}
-struct fill_search_info_args {
- int request;
- unsigned int flags;
- Dl_serinfo *serinfo;
- Dl_serpath *serpath;
- char *strspace;
-};
-
static void *
fill_search_info(const char *dir, size_t dirlen, void *param)
{
@@ -3043,7 +3255,7 @@ fill_search_info(const char *dir, size_t dirlen, void *param)
if (arg->request == RTLD_DI_SERINFOSIZE) {
arg->serinfo->dls_cnt ++;
- arg->serinfo->dls_size += sizeof(Dl_serpath) + dirlen + 1;
+ arg->serinfo->dls_size += sizeof(struct dl_serpath) + dirlen + 1;
} else {
struct dl_serpath *s_entry;
@@ -3073,10 +3285,12 @@ do_search_info(const Obj_Entry *obj, int request, struct dl_serinfo *info)
_info.dls_size = __offsetof(struct dl_serinfo, dls_serpath);
_info.dls_cnt = 0;
- path_enumerate(ld_library_path, fill_search_info, &args);
path_enumerate(obj->rpath, fill_search_info, &args);
- path_enumerate(gethints(), fill_search_info, &args);
- path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args);
+ path_enumerate(ld_library_path, fill_search_info, &args);
+ path_enumerate(obj->runpath, fill_search_info, &args);
+ path_enumerate(gethints(obj->z_nodeflib), fill_search_info, &args);
+ if (!obj->z_nodeflib)
+ path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args);
if (request == RTLD_DI_SERINFOSIZE) {
@@ -3095,20 +3309,26 @@ do_search_info(const Obj_Entry *obj, int request, struct dl_serinfo *info)
args.serpath = &info->dls_serpath[0];
args.strspace = (char *)&info->dls_serpath[_info.dls_cnt];
+ args.flags = LA_SER_RUNPATH;
+ if (path_enumerate(obj->rpath, fill_search_info, &args) != NULL)
+ return (-1);
+
args.flags = LA_SER_LIBPATH;
if (path_enumerate(ld_library_path, fill_search_info, &args) != NULL)
return (-1);
args.flags = LA_SER_RUNPATH;
- if (path_enumerate(obj->rpath, fill_search_info, &args) != NULL)
+ if (path_enumerate(obj->runpath, fill_search_info, &args) != NULL)
return (-1);
args.flags = LA_SER_CONFIG;
- if (path_enumerate(gethints(), fill_search_info, &args) != NULL)
+ if (path_enumerate(gethints(obj->z_nodeflib), fill_search_info, &args)
+ != NULL)
return (-1);
args.flags = LA_SER_DEFAULT;
- if (path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args) != NULL)
+ if (!obj->z_nodeflib &&
+ path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args) != NULL)
return (-1);
return (0);
}
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index 47389fe6efa3b..0aba7cdc2fb4f 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -222,6 +222,7 @@ typedef struct Struct_Obj_Entry {
const Elf_Hashelt *chain_zero_gnu; /* GNU hash table value array (Zeroed) */
char *rpath; /* Search path specified in object */
+ char *runpath; /* Search path with different priority */
Needed_Entry *needed; /* Shared objects needed by this one (%) */
Needed_Entry *needed_filtees;
Needed_Entry *needed_aux_filtees;
@@ -258,6 +259,7 @@ typedef struct Struct_Obj_Entry {
bool z_nodelete : 1; /* Do not unload the object and dependencies */
bool z_noopen : 1; /* Do not load on dlopen */
bool z_loadfltr : 1; /* Immediately load filtees */
+ bool z_nodeflib : 1; /* Don't search default library path */
bool ref_nodel : 1; /* Refcount increased to prevent dlclose */
bool init_scanned: 1; /* Object is already on init list. */
bool on_fini_list: 1; /* Object is already on fini list. */
@@ -321,6 +323,14 @@ struct Struct_RtldLockState {
sigjmp_buf env;
};
+struct fill_search_info_args {
+ int request;
+ unsigned int flags;
+ struct dl_serinfo *serinfo;
+ struct dl_serpath *serpath;
+ char *strspace;
+};
+
/*
* The pack of arguments and results for the symbol lookup functions.
*/
diff --git a/libexec/save-entropy/save-entropy.sh b/libexec/save-entropy/save-entropy.sh
index b5b37d40c3c7a..e96b543a76b83 100755
--- a/libexec/save-entropy/save-entropy.sh
+++ b/libexec/save-entropy/save-entropy.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2001-2006 Douglas Barton, DougB@FreeBSD.org
+# Copyright (c) 2001-2006,2012 Douglas Barton, dougb@FreeBSD.org
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -29,7 +29,7 @@
# This script is called by cron to store bits of randomness which are
# then used to seed /dev/random on boot.
-# Originally developed by Doug Barton, DougB@FreeBSD.org
+# Originally developed by Doug Barton, dougb@FreeBSD.org
PATH=/bin:/usr/bin
@@ -55,38 +55,36 @@ entropy_save_sz=${entropy_save_sz:-2048}
entropy_save_num=${entropy_save_num:-8}
if [ ! -d "${entropy_dir}" ]; then
- umask 077
- mkdir "${entropy_dir}" || {
- logger -is -t "$0" The entropy directory "${entropy_dir}" does not \
-exist, and cannot be created. Therefore no entropy can be saved. ;
- exit 1;}
- /usr/sbin/chown operator:operator "${entropy_dir}"
- chmod 0700 "${entropy_dir}"
+ install -d -o operator -g operator -m 0700 "${entropy_dir}" || {
+ logger -is -t "$0" The entropy directory "${entropy_dir}" does \
+ not exist, and cannot be created. Therefore no entropy can \
+ be saved.; exit 1; }
fi
+cd "${entropy_dir}" || {
+ logger -is -t "$0" Cannot cd to the entropy directory: "${entropy_dir}". \
+ Entropy file rotation is aborted.; exit 1; }
+
+for f in saved-entropy.*; do
+ case "${f}" in saved-entropy.\*) continue ;; esac # No files match
+ [ ${f#saved-entropy\.} -ge ${entropy_save_num} ] && unlink ${f}
+done
+
umask 377
-esn_m1=$(( ${entropy_save_num} - 1 ))
-for file_num in `jot $esn_m1 $esn_m1 1`; do
- if [ -e "${entropy_dir}/saved-entropy.${file_num}" ]; then
- if [ -f "${entropy_dir}/saved-entropy.${file_num}" ]; then
- new_file=saved-entropy.$(( $file_num + 1 ))
- if [ -e "${entropy_dir}/${new_file}" ]; then
- unlink ${entropy_dir}/${new_file}
- fi
- mv "${entropy_dir}/saved-entropy.${file_num}" \
- "${entropy_dir}/${new_file}"
- else
- logger -is -t "$0" \
-"${entropy_dir}/saved-entropy.${file_num} is not a regular file, and therefore \
-it will not be rotated. Entropy file harvesting is aborted."
- exit 1
- fi
+n=$(( ${entropy_save_num} - 1 ))
+while [ ${n} -ge 1 ]; do
+ if [ -f "saved-entropy.${n}" ]; then
+ mv "saved-entropy.${n}" "saved-entropy.$(( ${n} + 1 ))"
+ elif [ -e "saved-entropy.${n}" -o -L "saved-entropy.${n}" ]; then
+ logger -is -t "$0" \
+ "${entropy_dir}/saved-entropy.${n}" is not a regular file, and so \
+ it will not be rotated. Entropy file rotation is aborted.
+ exit 1
fi
+ n=$(( ${n} - 1 ))
done
-dd if=/dev/random of="${entropy_dir}/saved-entropy.1" \
- bs="$entropy_save_sz" count=1 2> /dev/null
+dd if=/dev/random of=saved-entropy.1 bs=${entropy_save_sz} count=1 2>/dev/null
exit 0
-
diff --git a/libexec/talkd/announce.c b/libexec/talkd/announce.c
index 869197e5c52c7..83c96b724c01b 100644
--- a/libexec/talkd/announce.c
+++ b/libexec/talkd/announce.c
@@ -60,8 +60,6 @@ static const char rcsid[] =
#include "ttymsg.h"
#include "extern.h"
-extern char hostname[];
-
/*
* Announce an invitation to talk.
*/
diff --git a/libexec/talkd/extern.h b/libexec/talkd/extern.h
index cb231a95d1348..a91cb25a71e19 100644
--- a/libexec/talkd/extern.h
+++ b/libexec/talkd/extern.h
@@ -25,6 +25,9 @@
* $FreeBSD$
*/
+extern int debug;
+extern char hostname[];
+
int announce(CTL_MSG *, const char *);
int delete_invite(u_int32_t);
void do_announce(CTL_MSG *, CTL_RESPONSE *);
diff --git a/libexec/talkd/process.c b/libexec/talkd/process.c
index 18ddc42aff1f2..1c5108fc7d59a 100644
--- a/libexec/talkd/process.c
+++ b/libexec/talkd/process.c
@@ -63,8 +63,6 @@ static const char rcsid[] =
#include "extern.h"
-extern int debug;
-
void
process_request(CTL_MSG *mp, CTL_RESPONSE *rp)
{
diff --git a/libexec/talkd/table.c b/libexec/talkd/table.c
index dcaed9c2a3e37..5ad7b61bdf7a1 100644
--- a/libexec/talkd/table.c
+++ b/libexec/talkd/table.c
@@ -64,8 +64,7 @@ static const char rcsid[] =
#define NIL ((TABLE_ENTRY *)0)
-extern int debug;
-struct timeval tp;
+static struct timeval tp;
typedef struct table_entry TABLE_ENTRY;
@@ -78,7 +77,7 @@ struct table_entry {
static void delete(TABLE_ENTRY *);
-TABLE_ENTRY *table = NIL;
+static TABLE_ENTRY *table = NIL;
/*
* Look in the table for an invitation that matches the current
diff --git a/libexec/talkd/talkd.c b/libexec/talkd/talkd.c
index e81cec6eb74d9..56ce4414c1062 100644
--- a/libexec/talkd/talkd.c
+++ b/libexec/talkd/talkd.c
@@ -69,13 +69,13 @@ static const char rcsid[] =
#include "extern.h"
-CTL_MSG request;
-CTL_RESPONSE response;
+static CTL_MSG request;
+static CTL_RESPONSE response;
-int debug = 0;
-long lastmsgtime;
+int debug = 0;
+static long lastmsgtime;
-char hostname[MAXHOSTNAMELEN];
+char hostname[MAXHOSTNAMELEN];
#define TIMEOUT 30
#define MAXIDLE 120
diff --git a/libexec/tftpd/tftp-io.c b/libexec/tftpd/tftp-io.c
index 3ce4f6ef44e70..d5d7fc6401fc8 100644
--- a/libexec/tftpd/tftp-io.c
+++ b/libexec/tftpd/tftp-io.c
@@ -53,7 +53,7 @@ struct sockaddr_storage me_sock;
static int send_packet(int peer, uint16_t block, char *pkt, int size);
-struct errmsg {
+static struct errmsg {
int e_code;
const char *e_msg;
} errmsgs[] = {
@@ -375,7 +375,7 @@ send_data(int peer, uint16_t block, char *data, int size)
/*
* Receive a packet
*/
-jmp_buf timeoutbuf;
+static jmp_buf timeoutbuf;
static void
timeout(int sig __unused)
diff --git a/libexec/tftpd/tftp-utils.c b/libexec/tftpd/tftp-utils.c
index 5613dd1a49257..c55f120a3a4dc 100644
--- a/libexec/tftpd/tftp-utils.c
+++ b/libexec/tftpd/tftp-utils.c
@@ -121,7 +121,7 @@ get_field(int peer, char *buffer, ssize_t size)
/*
* Logging functions
*/
-int _tftp_logtostdout = 1;
+static int _tftp_logtostdout = 1;
void
tftp_openlog(const char *ident, int logopt, int facility)
diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c
index 16702b70cb1f2..a0010b3c50322 100644
--- a/libexec/tftpd/tftpd.c
+++ b/libexec/tftpd/tftpd.c
@@ -107,9 +107,9 @@ static void tftp_xmitfile(int peer, const char *mode);
static int validate_access(int peer, char **, int);
static char peername[NI_MAXHOST];
-FILE *file;
+static FILE *file;
-struct formats {
+static struct formats {
const char *f_mode;
int f_convert;
} formats[] = {
@@ -371,7 +371,10 @@ main(int argc, char *argv[])
}
chdir("/");
setgroups(1, &nobody->pw_gid);
- setuid(nobody->pw_uid);
+ if (setuid(nobody->pw_uid) != 0) {
+ tftp_log(LOG_ERR, "setuid failed");
+ exit(1);
+ }
}
len = sizeof(me_sock);