From a584fc6a6b81183ed6ce1724237c6744cdd6559e Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 16 Jun 2009 09:19:59 -0700 Subject: Consolidate PIE linking Makefile rules. (cherry picked from commit 435aa54b3b9c1c87498e8bb3831394fd42220fa7) --- ChangeLog | 8 ++++++++ Makeconfig | 16 ++++++++++++++++ elf/Makefile | 9 +-------- nscd/Makefile | 11 ++--------- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7cf44d1100..cee59c1769 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-06-02 H.J. Lu + + * Makeconfig (+link-pie): Define. + (+prectorS): Define. + (+postctorS): Define. + * elf/Makefile ($(objpfx)tst-pie1): Use $(+link-pie). + * nscd/Makefile ($(objpfx)nscd): Likewise. + 2009-05-22 Jakub Jelinek * sysdeps/unix/sysv/linux/accept4.c: Include kernel-features.h. diff --git a/Makeconfig b/Makeconfig index 875fb679aa..9f134cc137 100644 --- a/Makeconfig +++ b/Makeconfig @@ -434,6 +434,19 @@ ifndef +link $(common-objpfx)libc% $(+postinit),$^) \ $(link-extra-libs) $(link-libc) $(+postctor) $(+postinit) endif +# Command for linking PIE programs with the C library. +ifndef +link-pie ++link-pie = $(CC) -pie -Wl,-O1 -nostdlib -nostartfiles -o $@ \ + $(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ + $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ + $(addprefix $(csu-objpfx),S$(start-installed-name)) \ + $(+preinit) $(+prectorS) \ + $(filter-out $(addprefix $(csu-objpfx),start.o \ + S$(start-installed-name))\ + $(+preinit) $(link-extra-libs) \ + $(common-objpfx)libc% $(+postinit),$^) \ + $(link-extra-libs) $(link-libc) $(+postctorS) $(+postinit) +endif # Command for statically linking programs with the C library. ifndef +link-static +link-static = $(CC) -nostdlib -nostartfiles -static -o $@ \ @@ -538,6 +551,9 @@ ifeq ($(elf),yes) +postinit = $(addprefix $(csu-objpfx),crtn.o) +prector = `$(CC) --print-file-name=crtbegin.o` +postctor = `$(CC) --print-file-name=crtend.o` +# Variants of the two previous definitions for linking PIE programs. ++prectorS = `$(CC) --print-file-name=crtbeginS.o` ++postctorS = `$(CC) --print-file-name=crtendS.o` +interp = $(addprefix $(elf-objpfx),interp.os) endif csu-objpfx = $(common-objpfx)csu/ diff --git a/elf/Makefile b/elf/Makefile index b2b5a6538e..208538cc8f 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -833,14 +833,7 @@ $(objpfx)tst-pie1.out: $(objpfx)tst-pie1 $< > $@ $(objpfx)tst-pie1: $(objpfx)tst-pie1.o $(objpfx)tst-piemod1.so - $(LINK.o) -pie -Wl,-O1 \ - $(sysdep-LDFLAGS) $(config-LDFLAGS) \ - $(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \ - $(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \ - $(LDFLAGS) $(LDFLAGS-$(@F)) \ - -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link) \ - -o $@ $(objpfx)tst-pie1.o $(objpfx)tst-piemod1.so \ - $(common-objpfx)libc_nonshared.a + $(+link-pie) generated += tst-pie1 tst-pie1.out tst-pie1.o endif diff --git a/nscd/Makefile b/nscd/Makefile index 364ddfe8dd..4abae8c661 100644 --- a/nscd/Makefile +++ b/nscd/Makefile @@ -1,5 +1,4 @@ -# Copyright (C) 1998,2000,2002,2003,2004,2005,2006,2007,2008 -# Free Software Foundation, Inc. +# Copyright (C) 1998,2000,2002-2009 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -128,13 +127,7 @@ ifeq (yesyes,$(have-fpie)$(build-shared)) relro-LDFLAGS += -Wl,-z,now $(objpfx)nscd: $(addprefix $(objpfx),$(nscd-modules:=.o)) - $(LINK.o) -pie -Wl,-O1 $(nscd-cflags) \ - $(sysdep-LDFLAGS) $(config-LDFLAGS) $(relro-LDFLAGS) \ - $(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \ - $(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \ - $(LDFLAGS) $(LDFLAGS-$(@F)) \ - -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link) \ - -o $@ $^ $(LDLIBS-nscd) $(common-objpfx)libc_nonshared.a + $(+link-pie) endif # This makes sure -DNOT_IN_libc is passed for all these modules. -- cgit 1.4.1 From a7800930627c2ee5d4d3b373f62c897e0c321c19 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 16 Jun 2009 15:58:07 -0700 Subject: Extend pt_chown to drop privileges. If libcap is available, use it to drop privileges in pt_chown before starting the work to change the permissions and ownership of the slave device. (cherry picked from commit f793b62438a3cfdbcc5ba453eebee1db3f315bea) --- ChangeLog | 4 ++++ login/Makefile | 7 ++++++- login/programs/pt_chown.c | 45 ++++++++++++++++++++++++++++++++++++------- sysdeps/generic/pty-private.h | 5 +++-- sysdeps/unix/grantpt.c | 5 ++++- 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index cee59c1769..a714c3eb17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-06-16 Ulrich Drepper + + * login/Makefile: If necessary link pt_chown with -lcap. + 2009-06-02 H.J. Lu * Makeconfig (+link-pie): Define. diff --git a/login/Makefile b/login/Makefile index b02d385b66..427c050a89 100644 --- a/login/Makefile +++ b/login/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1996-1998,2000-2002,2003,2007 Free Software Foundation, Inc. +# Copyright (C) 1996-1998,2000-2003,2007, 2009 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -54,6 +54,11 @@ otherlibs += $(nssobjdir)/libnss_files.a $(resolvobjdir)/libnss_dns.a \ $(resolvobjdir)/libresolv.a $(common-objpfx)libc.a endif +ifeq (yes,$(have-libcap)) +libcap = -lcap +endif +LDLIBS-pt_chown = $(libcap) + # pt_chown needs to be setuid root. $(inst_libexecdir)/pt_chown: $(objpfx)pt_chown $(+force) $(make-target-directory) diff --git a/login/programs/pt_chown.c b/login/programs/pt_chown.c index 485eddabc9..9544653693 100644 --- a/login/programs/pt_chown.c +++ b/login/programs/pt_chown.c @@ -29,6 +29,10 @@ #include #include #include +#ifdef HAVE_LIBCAP +# include +# include +#endif #include "pty-private.h" @@ -99,7 +103,7 @@ static int do_pt_chown (void) { char *pty; - struct stat st; + struct stat64 st; struct group *p; gid_t gid; @@ -110,7 +114,7 @@ do_pt_chown (void) /* Check that the returned slave pseudo terminal is a character device. */ - if (stat (pty, &st) < 0 || !S_ISCHR(st.st_mode)) + if (stat64 (pty, &st) < 0 || !S_ISCHR (st.st_mode)) return FAIL_EINVAL; /* Get the group ID of the special `tty' group. */ @@ -135,16 +139,43 @@ int main (int argc, char *argv[]) { uid_t euid = geteuid (); + uid_t uid = getuid (); int remaining; - /* Normal invocation of this program is with no arguments and - with privileges. - FIXME: Should use capable (CAP_CHOWN|CAP_FOWNER). */ if (argc == 1 && euid == 0) - return do_pt_chown (); + { +#ifdef HAVE_LIBCAP + /* Drop privileges. */ + if (uid != euid) + { + static const cap_value_t cap_list[] = + { CAP_CHOWN, CAP_FOWNER }; +# define ncap_list (sizeof (cap_list) / sizeof (cap_list[0])) + cap_t caps = cap_init (); + if (caps == NULL) + error (FAIL_ENOMEM, errno, + _("Failed to initialize drop of capabilities")); + + /* There is no reason why these should not work. */ + cap_set_flag (caps, CAP_PERMITTED, ncap_list, cap_list, CAP_SET); + cap_set_flag (caps, CAP_EFFECTIVE, ncap_list, cap_list, CAP_SET); + + int res = cap_set_proc (caps); + + cap_free (caps); + + if (__builtin_expect (res != 0, 0)) + error (FAIL_EXEC, errno, _("cap_set_proc failed")); + } +#endif + + /* Normal invocation of this program is with no arguments and + with privileges. */ + return do_pt_chown (); + } /* We aren't going to be using privileges, so drop them right now. */ - setuid (getuid ()); + setuid (uid); /* Set locale via LC_ALL. */ setlocale (LC_ALL, ""); diff --git a/sysdeps/generic/pty-private.h b/sysdeps/generic/pty-private.h index d6ec2cee68..493f40551d 100644 --- a/sysdeps/generic/pty-private.h +++ b/sysdeps/generic/pty-private.h @@ -1,5 +1,5 @@ /* Internal defenitions and declarations for pseudo terminal functions. - Copyright (C) 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Zack Weinberg , 1998. @@ -39,7 +39,8 @@ enum /* failure modes */ FAIL_EBADF = 1, FAIL_EINVAL, FAIL_EACCES, - FAIL_EXEC + FAIL_EXEC, + FAIL_ENOMEM }; #endif /* pty-private.h */ diff --git a/sysdeps/unix/grantpt.c b/sysdeps/unix/grantpt.c index bdedbacec8..39797841c5 100644 --- a/sysdeps/unix/grantpt.c +++ b/sysdeps/unix/grantpt.c @@ -185,7 +185,7 @@ grantpt (int fd) if (!WIFEXITED (w)) __set_errno (ENOEXEC); else - switch (WEXITSTATUS(w)) + switch (WEXITSTATUS (w)) { case 0: retval = 0; @@ -202,6 +202,9 @@ grantpt (int fd) case FAIL_EXEC: __set_errno (ENOEXEC); break; + case FAIL_ENOMEM: + __set_errno (ENOMEM); + break; default: assert(! "getpt: internal error: invalid exit code from pt_chown"); -- cgit 1.4.1 From c87c885303b406c5f636841b8289425062f3c7c6 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 16 Jun 2009 20:46:42 -0700 Subject: Build pt_chown as PIE. (cherry picked from commit f051ddfe22d3db4e77d6a545d5363be8b986cb96) --- ChangeLog | 4 ++++ login/Makefile | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/ChangeLog b/ChangeLog index a714c3eb17..ec8c64aedf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-06-16 Ulrich Drepper + + * login/Makefile: Build pt_chown as PIE. + 2009-06-16 Ulrich Drepper * login/Makefile: If necessary link pt_chown with -lcap. diff --git a/login/Makefile b/login/Makefile index 427c050a89..beb2a5c3a8 100644 --- a/login/Makefile +++ b/login/Makefile @@ -54,10 +54,23 @@ otherlibs += $(nssobjdir)/libnss_files.a $(resolvobjdir)/libnss_dns.a \ $(resolvobjdir)/libresolv.a $(common-objpfx)libc.a endif +ifeq (yesyes,$(have-fpie)$(build-shared)) +pt_chown-cflags += $(pie-ccflag) +endif +ifeq (yes,$(have-ssp)) +pt_chown-cflags += -fstack-protector +endif ifeq (yes,$(have-libcap)) libcap = -lcap endif +CFLAGS-pt_chown.c = $(pt_chown-cflags) LDLIBS-pt_chown = $(libcap) +ifeq (yesyes,$(have-fpie)$(build-shared)) +LDFLAGS-pt_chown = -Wl,-z,now + +$(objpfx)pt_chown: $(objpfx)pt_chown.o + $(+link-pie) +endif # pt_chown needs to be setuid root. $(inst_libexecdir)/pt_chown: $(objpfx)pt_chown $(+force) -- cgit 1.4.1