Instead of setprogname(), add initprogname() which gets the program

name for getprogname() using /proc or pstat() if possible.
This commit is contained in:
Todd C. Miller
2013-12-01 19:12:21 -07:00
parent 902215a8c0
commit 0d81263e26
21 changed files with 147 additions and 108 deletions

View File

@@ -21,6 +21,7 @@ common/fileops.c
common/fmt_string.c
common/gidlist.c
common/lbuf.c
common/progname.c
common/regress/sudo_conf/conf_test.c
common/regress/sudo_conf/test1.in
common/regress/sudo_conf/test1.out.ok
@@ -69,7 +70,6 @@ compat/getgrouplist.c
compat/getline.c
compat/getopt.h
compat/getopt_long.c
compat/getprogname.c
compat/glob.c
compat/glob.h
compat/isblank.c

View File

@@ -67,9 +67,9 @@ DEFS = @OSDEFS@ -D_PATH_SUDO_CONF=\"$(sysconfdir)/sudo.conf\"
SHELL = @SHELL@
LTOBJS = alloc.lo atobool.lo atoid.lo event.lo fatal.lo fileops.lo \
fmt_string.lo gidlist.lo lbuf.lo secure_path.lo setgroups.lo \
sudo_conf.lo sudo_debug.lo sudo_dso.lo sudo_printf.lo term.lo \
ttysize.lo @COMMON_OBJS@
fmt_string.lo gidlist.lo lbuf.lo progname.lo secure_path.lo \
setgroups.lo sudo_conf.lo sudo_debug.lo sudo_dso.lo sudo_printf.lo \
term.lo ttysize.lo @COMMON_OBJS@
PARSELN_TEST_OBJS = parseln_test.lo locale_stub.lo
@@ -228,6 +228,8 @@ parseln_test.lo: $(srcdir)/regress/sudo_parseln/parseln_test.c \
$(incdir)/fileops.h $(incdir)/missing.h \
$(top_builddir)/config.h $(top_srcdir)/compat/stdbool.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/regress/sudo_parseln/parseln_test.c
progname.lo: $(srcdir)/progname.c $(incdir)/missing.h $(top_builddir)/config.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/progname.c
secure_path.lo: $(srcdir)/secure_path.c $(incdir)/missing.h \
$(incdir)/secure_path.h $(incdir)/sudo_debug.h \
$(top_builddir)/config.h

123
common/progname.c Normal file
View File

@@ -0,0 +1,123 @@
/*
* Copyright (c) 2013 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <config.h>
/* Large files not supported by procfs.h */
#if defined(HAVE_PROCFS_H) || defined(HAVE_SYS_PROCFS_H)
# undef _FILE_OFFSET_BITS
# undef _LARGE_FILES
#endif
#include <sys/types.h>
#ifdef HAVE_PSTAT_GETPROC
# include <sys/param.h>
# include <sys/pstat.h>
#endif
#if defined(HAVE_PROCFS_H)
# include <procfs.h>
#elif defined(HAVE_SYS_PROCFS_H)
# include <sys/procfs.h>
#endif
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif /* STDC_HEADERS */
#ifdef HAVE_STRING_H
# include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif /* HAVE_STRINGS_H */
#include <errno.h>
#include <fcntl.h>
#include "missing.h"
#if defined(HAVE_GETPROGNAME) || defined(HAVE___PROGNAME)
/* STUB */
void
initprogname(const char *name)
{
return;
}
#else
static const char *progname = "";
void
initprogname(const char *name)
{
const char *base;
#ifdef HAVE_PSTAT_GETPROC
static char ucomm[PST_UCOMMLEN];
struct pst_status pstat;
int rc;
/*
* Determine the progname from pst_ucomm in struct pst_status.
* We may get EOVERFLOW if the whole thing doesn't fit but that is OK.
*/
rc = pstat_getproc(&pstat, sizeof(pstat), (size_t)0, (int)getpid());
if (rc != -1 || errno == EOVERFLOW) {
strlcpy(ucomm, pstat.pst_ucomm, sizeof(ucomm));
progname = ucomm;
return;
}
#elif defined(HAVE_PROCFS_H) || defined(HAVE_SYS_PROCFS_H)
/* XXX - configure check for psinfo.pr_fname */
static char ucomm[PRFNSZ];
struct psinfo psinfo;
char path[PATH_MAX];
ssize_t nread;
int fd;
/* Try to determine the tty from pr_ttydev in /proc/pid/psinfo. */
snprintf(path, sizeof(path), "/proc/%u/psinfo", (unsigned int)getpid());
if ((fd = open(path, O_RDONLY, 0)) != -1) {
nread = read(fd, &psinfo, sizeof(psinfo));
close(fd);
if (nread == (ssize_t)sizeof(psinfo)) {
strlcpy(ucomm, psinfo.pr_fname, sizeof(ucomm));
progname = ucomm;
return;
}
}
#endif /* HAVE_PSTAT_GETPROC */
if ((base = strrchr(name, '/')) != NULL) {
base++;
} else {
base = name;
}
progname = base;
}
const char *
getprogname(void)
{
return progname;
}
#endif /* !HAVE_GETPROGNAME && !HAVE___PROGNAME */

View File

@@ -185,9 +185,6 @@ getline.lo: $(srcdir)/getline.c $(incdir)/missing.h $(top_builddir)/config.h
getopt_long.lo: $(srcdir)/getopt_long.c $(incdir)/fatal.h $(incdir)/missing.h \
$(top_builddir)/config.h $(top_srcdir)/compat/getopt.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/getopt_long.c
getprogname.lo: $(srcdir)/getprogname.c $(incdir)/missing.h \
$(top_builddir)/config.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/getprogname.c
glob.lo: $(srcdir)/glob.c $(incdir)/missing.h $(top_builddir)/config.h \
$(top_srcdir)/compat/charclass.h $(top_srcdir)/compat/glob.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/glob.c

View File

@@ -1,49 +0,0 @@
/*
* Copyright (c) 2010, 2013 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <config.h>
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include "missing.h"
static const char *progname = "sudo";
void
setprogname(const char *name)
{
const char *base;
if ((base = strrchr(name, '/')) != NULL) {
base++;
} else {
base = name;
}
if (strcmp(progname, base) != 0)
progname = base;
}
const char *
getprogname(void)
{
return progname;
}
#endif /* !HAVE_GETPROGNAME !HAVE___PROGNAME */

7
configure vendored
View File

@@ -18672,13 +18672,6 @@ fi
if test "$sudo_cv___progname" = "yes"; then
$as_echo "#define HAVE___PROGNAME 1" >>confdefs.h
else
case " $LIBOBJS " in
*" getprogname.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS getprogname.$ac_objext"
;;
esac
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv___progname" >&5
$as_echo "$sudo_cv___progname" >&6; }

View File

@@ -2559,8 +2559,6 @@ AC_CHECK_FUNCS(getprogname, , [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[extern char *__progname; (void)puts(__progname);]])], [sudo_cv___progname=yes], [sudo_cv___progname=no])])
if test "$sudo_cv___progname" = "yes"; then
AC_DEFINE(HAVE___PROGNAME)
else
AC_LIBOBJ(getprogname)
fi
AC_MSG_RESULT($sudo_cv___progname)
])

View File

@@ -282,7 +282,6 @@ extern const char *__progname;
# define getprogname() (__progname)
# else
const char *getprogname(void);
void setprogname(const char *);
# endif /* HAVE___PROGNAME */
#endif /* !HAVE_GETPROGNAME */
@@ -447,5 +446,6 @@ char *strsignal(int);
#ifndef HAVE_SIG2STR
int sig2str(int, char *);
#endif
void initprogname(const char *);
#endif /* _SUDO_MISSING_H */

View File

@@ -70,7 +70,7 @@ sub mkdep {
$makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo sssd.lo:;
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getprogname.lo getopt_long.lo glob.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo pw_dup.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo utimes.lo globtest.o fnm_test.o:;
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo pw_dup.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo utimes.lo globtest.o fnm_test.o:;
# Parse OBJS lines
my %objs;

View File

@@ -138,11 +138,9 @@ policy_open(unsigned int version, sudo_conv_t conversation,
if (strncmp(*ui, "runas_group=", sizeof("runas_group=") - 1) == 0) {
runas_group = *ui + sizeof("runas_group=") - 1;
}
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
if (strncmp(*ui, "progname=", sizeof("progname=") - 1) == 0) {
setprogname(*ui + sizeof("progname=") - 1);
initprogname(*ui + sizeof("progname=") - 1);
}
#endif
/* Check to see if sudo was called as sudoedit or with -e flag. */
if (strncmp(*ui, "sudoedit=", sizeof("sudoedit=") - 1) == 0) {
if (strcasecmp(*ui + sizeof("sudoedit=") - 1, "true") == 0)

View File

@@ -253,12 +253,10 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
continue;
}
#endif /* HAVE_BSD_AUTH_H */
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
if (MATCHES(*cur, "progname=")) {
setprogname(*cur + sizeof("progname=") - 1);
initprogname(*cur + sizeof("progname=") - 1);
continue;
}
#endif
if (MATCHES(*cur, "network_addrs=")) {
interfaces_string = *cur + sizeof("network_addrs=") - 1;
set_interfaces(interfaces_string);

View File

@@ -51,7 +51,7 @@ __dso_public int main(int argc, char *argv[]);
static void
usage(void)
{
fprintf(stderr, "usage: load_symbols plugin.so symbols_file\n");
fprintf(stderr, "usage: %s plugin.so symbols_file\n", getprogname());
exit(1);
}
@@ -65,9 +65,7 @@ main(int argc, char *argv[])
FILE *fp;
int ntests = 0, errors = 0;
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
setprogname(argc > 0 ? argv[0] : "check_symbols");
#endif
initprogname(argc > 0 ? argv[0] : "check_symbols");
if (argc != 3)
usage();

View File

@@ -55,7 +55,7 @@ __dso_public int main(int argc, char *argv[]);
static void
usage(void)
{
fprintf(stderr, "usage: check_iolog_path datafile\n");
fprintf(stderr, "usage: %s datafile\n", getprogname());
exit(1);
}
@@ -106,9 +106,7 @@ main(int argc, char *argv[])
int errors = 0;
int tests = 0;
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
setprogname(argc > 0 ? argv[0] : "check_iolog_path");
#endif
initprogname(argc > 0 ? argv[0] : "check_iolog_path");
if (argc != 2)
usage();

View File

@@ -49,7 +49,7 @@ __dso_public int main(int argc, char *argv[]);
static void
usage(void)
{
fprintf(stderr, "usage: check_wrap inputfile\n");
fprintf(stderr, "usage: %s inputfile\n", getprogname());
exit(1);
}
@@ -61,9 +61,7 @@ main(int argc, char *argv[])
char *cp, *dash, *line, lines[2][2048];
int which = 0;
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
setprogname(argc > 0 ? argv[0] : "check_wrap");
#endif
initprogname(argc > 0 ? argv[0] : "check_wrap");
if (argc != 2)
usage();

View File

@@ -79,7 +79,7 @@ check_addr(char *input)
static void
usage(void)
{
fprintf(stderr, "usage: check_addr datafile\n");
fprintf(stderr, "usage: %s datafile\n", getprogname());
exit(1);
}
@@ -91,9 +91,7 @@ main(int argc, char *argv[])
size_t len;
FILE *fp;
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
setprogname(argc > 0 ? argv[0] : "check_addr");
#endif
initprogname(argc > 0 ? argv[0] : "check_addr");
if (argc != 2)
usage();

View File

@@ -243,10 +243,7 @@ main(int argc, char *argv[])
}
#endif
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
setprogname(argc > 0 ? argv[0] : "sudoreplay");
#endif
initprogname(argc > 0 ? argv[0] : "sudoreplay");
sudoers_setlocale(SUDOERS_LOCALE_USER, NULL);
decimal = localeconv()->decimal_point;
bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have sudoreplay domain */

View File

@@ -138,9 +138,7 @@ main(int argc, char *argv[])
sudoersdebug = 1;
#endif
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
setprogname(argc > 0 ? argv[0] : "testsudoers");
#endif
initprogname(argc > 0 ? argv[0] : "testsudoers");
sudoers_setlocale(SUDOERS_LOCALE_USER, NULL);
bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have own domain */

View File

@@ -166,10 +166,7 @@ main(int argc, char *argv[])
}
#endif
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
setprogname(argc > 0 ? argv[0] : "visudo");
#endif
initprogname(argc > 0 ? argv[0] : "visudo");
sudoers_setlocale(SUDOERS_LOCALE_USER, NULL);
bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have visudo domain */
textdomain("sudoers");

View File

@@ -185,7 +185,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
env_add = emalloc2(env_size, sizeof(char *));
/* Pass progname to plugin so it can call setprogname() */
/* Pass progname to plugin so it can call initprogname() */
sudo_settings[ARG_PROGNAME].value = getprogname();
/* First, check to see if we were invoked as "sudoedit". */

View File

@@ -52,9 +52,7 @@ main(int argc, char *argv[])
char *tty_libc, *tty_sudo;
int rval = 0;
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
setprogname(argc > 0 ? argv[0] : "check_ttyname");
#endif
initprogname(argc > 0 ? argv[0] : "check_ttyname");
/* Lookup tty name via libc. */
if ((tty_libc = ttyname(STDIN_FILENO)) == NULL &&

View File

@@ -299,10 +299,7 @@ main(int argc, char *argv[], char *envp[])
int
os_init_common(int argc, char *argv[], char *envp[])
{
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
if (argc > 0)
setprogname(argv[0]);
#endif
initprogname(argc > 0 ? argv[0] : "sudo");
#ifdef STATIC_SUDOERS_PLUGIN
preload_static_symbols();
#endif