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.
This commit is contained in:
parent
fab8238de6
commit
f793b62438
|
@ -1,3 +1,7 @@
|
|||
2009-06-16 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* login/Makefile: If necessary link pt_chown with -lcap.
|
||||
|
||||
2009-06-16 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/x86_64/memchr.S (memchr): Use unsigned instead of signed
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_LIBCAP
|
||||
# include <sys/capability.h>
|
||||
# include <sys/prctl.h>
|
||||
#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. */
|
||||
|
@ -136,16 +140,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, "");
|
||||
|
|
|
@ -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 <zack@rabi.phys.columbia.edu>, 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 */
|
||||
|
|
|
@ -202,7 +202,7 @@ grantpt (int fd)
|
|||
if (!WIFEXITED (w))
|
||||
__set_errno (ENOEXEC);
|
||||
else
|
||||
switch (WEXITSTATUS(w))
|
||||
switch (WEXITSTATUS (w))
|
||||
{
|
||||
case 0:
|
||||
retval = 0;
|
||||
|
@ -219,6 +219,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");
|
||||
|
|
Loading…
Reference in New Issue