summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2017-02-09 11:26:48 -0200
committerRenato Botelho <renato@netgate.com>2017-02-09 11:26:48 -0200
commit4a05f5440acda223e6a0ec5157bc32ecc0f09ff9 (patch)
tree4c2ece480e5d4155ed35bec62996de40eb179f18 /libexec
parent681a482d8fc4bfc14a24f7a9d75cca6337f2a520 (diff)
parenta1e52233c91fd46e666297270ab655f1abff8535 (diff)
downloadFreeBSD-src-4a05f5440acda223e6a0ec5157bc32ecc0f09ff9.zip
FreeBSD-src-4a05f5440acda223e6a0ec5157bc32ecc0f09ff9.tar.gz
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/rtld.c32
-rw-r--r--libexec/rtld-elf/rtld_lock.c61
-rw-r--r--libexec/tftpd/Makefile9
-rw-r--r--libexec/tftpd/tftpd.c7
4 files changed, 68 insertions, 41 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index f5b43db..1be409b 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -104,6 +104,7 @@ static int load_needed_objects(Obj_Entry *, int);
static int load_preload_objects(void);
static Obj_Entry *load_object(const char *, int fd, const Obj_Entry *, int);
static void map_stacks_exec(RtldLockState *);
+static int obj_enforce_relro(Obj_Entry *);
static Obj_Entry *obj_from_addr(const void *);
static void objlist_call_fini(Objlist *, Obj_Entry *, RtldLockState *);
static void objlist_call_init(Objlist *, RtldLockState *);
@@ -609,6 +610,10 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
if (do_copy_relocations(obj_main) == -1)
rtld_die();
+ dbg("enforcing main obj relro");
+ if (obj_enforce_relro(obj_main) == -1)
+ rtld_die();
+
if (getenv(LD_ "DUMP_REL_POST") != NULL) {
dump_relocations(obj_main);
exit (0);
@@ -2691,14 +2696,8 @@ relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
reloc_non_plt(obj, rtldobj, flags | SYMLOOK_IFUNC, lockstate))
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 (!obj->mainprog && obj_enforce_relro(obj) == -1)
+ return (-1);
/*
* Set up the magic number and version in the Obj_Entry. These
@@ -3471,7 +3470,7 @@ dl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param)
error = 0;
wlock_acquire(rtld_phdr_lock, &phdr_lockstate);
- rlock_acquire(rtld_bind_lock, &bind_lockstate);
+ wlock_acquire(rtld_bind_lock, &bind_lockstate);
for (obj = globallist_curr(TAILQ_FIRST(&obj_list)); obj != NULL;) {
TAILQ_INSERT_AFTER(&obj_list, obj, &marker, next);
rtld_fill_dl_phdr_info(obj, &phdr_info);
@@ -3479,7 +3478,7 @@ dl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param)
error = callback(&phdr_info, sizeof phdr_info, param);
- rlock_acquire(rtld_bind_lock, &bind_lockstate);
+ wlock_acquire(rtld_bind_lock, &bind_lockstate);
obj = globallist_next(&marker);
TAILQ_REMOVE(&obj_list, &marker, next);
if (error != 0) {
@@ -4986,6 +4985,19 @@ _rtld_is_dlopened(void *arg)
return (res);
}
+int
+obj_enforce_relro(Obj_Entry *obj)
+{
+
+ if (obj->relro_size > 0 && 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);
+ }
+ return (0);
+}
+
static void
map_stacks_exec(RtldLockState *lockstate)
{
diff --git a/libexec/rtld-elf/rtld_lock.c b/libexec/rtld-elf/rtld_lock.c
index f31546c..c4d2a0b 100644
--- a/libexec/rtld-elf/rtld_lock.c
+++ b/libexec/rtld-elf/rtld_lock.c
@@ -38,8 +38,8 @@
* In this algorithm the lock is a single word. Its low-order bit is
* set when a writer holds the lock. The remaining high-order bits
* contain a count of readers desiring the lock. The algorithm requires
- * atomic "compare_and_store" and "add" operations, which we implement
- * using assembly language sequences in "rtld_start.S".
+ * atomic "compare_and_store" and "add" operations, which we take
+ * from machine/atomic.h.
*/
#include <sys/param.h>
@@ -64,10 +64,10 @@ typedef struct Struct_Lock {
} Lock;
static sigset_t fullsigmask, oldsigmask;
-static int thread_flag;
+static int thread_flag, wnested;
static void *
-def_lock_create()
+def_lock_create(void)
{
void *base;
char *p;
@@ -117,29 +117,34 @@ def_rlock_acquire(void *lock)
static void
def_wlock_acquire(void *lock)
{
- Lock *l = (Lock *)lock;
- sigset_t tmp_oldsigmask;
+ Lock *l;
+ sigset_t tmp_oldsigmask;
- for ( ; ; ) {
- sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
- if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG))
- break;
- sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
- }
- oldsigmask = tmp_oldsigmask;
+ l = (Lock *)lock;
+ for (;;) {
+ sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
+ if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG))
+ break;
+ sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
+ }
+ if (atomic_fetchadd_int(&wnested, 1) == 0)
+ oldsigmask = tmp_oldsigmask;
}
static void
def_lock_release(void *lock)
{
- Lock *l = (Lock *)lock;
-
- if ((l->lock & WAFLAG) == 0)
- atomic_add_rel_int(&l->lock, -RC_INCR);
- else {
- atomic_add_rel_int(&l->lock, -WAFLAG);
- sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
- }
+ Lock *l;
+
+ l = (Lock *)lock;
+ if ((l->lock & WAFLAG) == 0)
+ atomic_add_rel_int(&l->lock, -RC_INCR);
+ else {
+ assert(wnested > 0);
+ atomic_add_rel_int(&l->lock, -WAFLAG);
+ if (atomic_fetchadd_int(&wnested, -1) == 1)
+ sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
+ }
}
static int
@@ -269,7 +274,7 @@ lock_restart_for_upgrade(RtldLockState *lockstate)
}
void
-lockdflt_init()
+lockdflt_init(void)
{
int i;
@@ -373,12 +378,12 @@ _rtld_atfork_pre(int *locks)
return;
/*
- * Warning: this does not work with the rtld compat locks
- * above, since the thread signal mask is corrupted (set to
- * all signals blocked) if two locks are taken in write mode.
- * The caller of the _rtld_atfork_pre() must provide the
- * working implementation of the locks, and libthr locks are
- * fine.
+ * Warning: this did not worked well with the rtld compat
+ * locks above, when the thread signal mask was corrupted (set
+ * to all signals blocked) if two locks were taken
+ * simultaneously in the write mode. The caller of the
+ * _rtld_atfork_pre() must provide the working implementation
+ * of the locks anyway, and libthr locks are fine.
*/
wlock_acquire(rtld_phdr_lock, &ls[0]);
wlock_acquire(rtld_bind_lock, &ls[1]);
diff --git a/libexec/tftpd/Makefile b/libexec/tftpd/Makefile
index f005001..abee70c 100644
--- a/libexec/tftpd/Makefile
+++ b/libexec/tftpd/Makefile
@@ -1,13 +1,18 @@
# @(#)Makefile 8.1 (Berkeley) 6/4/93
# $FreeBSD$
+.include <bsd.own.mk>
+
PROG= tftpd
MAN= tftpd.8
SRCS= tftp-file.c tftp-io.c tftp-options.c tftp-transfer.c tftp-utils.c
SRCS+= tftpd.c
WFORMAT=0
-DPADD= ${LIBWRAP}
-LDADD= -lwrap
+.if ${MK_TCP_WRAPPERS} != "no"
+CFLAGS+= -DLIBWRAP
+DPADD+= ${LIBWRAP}
+LDADD+= -lwrap
+.endif
.include <bsd.prog.mk>
diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c
index 571fa59..26d8105 100644
--- a/libexec/tftpd/tftpd.c
+++ b/libexec/tftpd/tftpd.c
@@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
-#include <tcpd.h>
#include <unistd.h>
#include "tftp-file.h"
@@ -75,6 +74,10 @@ __FBSDID("$FreeBSD$");
#include "tftp-transfer.h"
#include "tftp-options.h"
+#ifdef LIBWRAP
+#include <tcpd.h>
+#endif
+
static void tftp_wrq(int peer, char *, ssize_t);
static void tftp_rrq(int peer, char *, ssize_t);
@@ -281,6 +284,7 @@ main(int argc, char *argv[])
}
}
+#ifdef LIBWRAP
/*
* See if the client is allowed to talk to me.
* (This needs to be done before the chroot())
@@ -329,6 +333,7 @@ main(int argc, char *argv[])
"Full access allowed"
"in /etc/hosts.allow");
}
+#endif
/*
* Since we exit here, we should do that only after the above
OpenPOWER on IntegriCloud