2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 01:49:11 +00:00

Move openat() emulation to lib/util and at unlinkat() emulation.

This commit is contained in:
Todd C. Miller 2019-10-24 20:04:30 -06:00
parent 4dacf81082
commit 0d69de5b25
8 changed files with 204 additions and 36 deletions

View File

@ -119,6 +119,7 @@ lib/util/mksigname.c
lib/util/mksigname.h lib/util/mksigname.h
lib/util/mktemp.c lib/util/mktemp.c
lib/util/nanosleep.c lib/util/nanosleep.c
lib/util/openat.c
lib/util/parseln.c lib/util/parseln.c
lib/util/pipe2.c lib/util/pipe2.c
lib/util/progname.c lib/util/progname.c
@ -195,6 +196,7 @@ lib/util/sudo_dso.c
lib/util/term.c lib/util/term.c
lib/util/ttyname_dev.c lib/util/ttyname_dev.c
lib/util/ttysize.c lib/util/ttysize.c
lib/util/unlinkat.c
lib/util/util.exp.in lib/util/util.exp.in
lib/util/utimens.c lib/util/utimens.c
lib/util/vsyslog.c lib/util/vsyslog.c

View File

@ -861,6 +861,9 @@
/* Define to 1 if you have the <unistd.h> header file. */ /* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H #undef HAVE_UNISTD_H
/* Define to 1 if you have the `unlinkat' function. */
#undef HAVE_UNLINKAT
/* Define to 1 if you have the `unsetenv' function. */ /* Define to 1 if you have the `unsetenv' function. */
#undef HAVE_UNSETENV #undef HAVE_UNSETENV

55
configure vendored
View File

@ -2881,7 +2881,6 @@ as_fn_append ac_func_list " killpg"
as_fn_append ac_func_list " nl_langinfo" as_fn_append ac_func_list " nl_langinfo"
as_fn_append ac_func_list " pread" as_fn_append ac_func_list " pread"
as_fn_append ac_func_list " pwrite" as_fn_append ac_func_list " pwrite"
as_fn_append ac_func_list " openat"
as_fn_append ac_func_list " faccessat" as_fn_append ac_func_list " faccessat"
as_fn_append ac_func_list " wordexp" as_fn_append ac_func_list " wordexp"
as_fn_append ac_func_list " getauxval" as_fn_append ac_func_list " getauxval"
@ -19211,8 +19210,6 @@ done
case "$host_os" in case "$host_os" in
hpux*) hpux*)
if test X"$ac_cv_func_pread" = X"yes"; then if test X"$ac_cv_func_pread" = X"yes"; then
@ -20444,6 +20441,58 @@ esac
fi fi
fi
done
for ac_func in openat
do :
ac_fn_c_check_func "$LINENO" "openat" "ac_cv_func_openat"
if test "x$ac_cv_func_openat" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_OPENAT 1
_ACEOF
else
case " $LIBOBJS " in
*" openat.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS openat.$ac_objext"
;;
esac
for _sym in sudo_openat; do
COMPAT_EXP="${COMPAT_EXP}${_sym}
"
done
fi
done
for ac_func in unlinkat
do :
ac_fn_c_check_func "$LINENO" "unlinkat" "ac_cv_func_unlinkat"
if test "x$ac_cv_func_unlinkat" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_UNLINKAT 1
_ACEOF
else
case " $LIBOBJS " in
*" unlinkat.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS unlinkat.$ac_objext"
;;
esac
for _sym in sudo_unlinkat; do
COMPAT_EXP="${COMPAT_EXP}${_sym}
"
done
fi fi
done done

View File

@ -2506,7 +2506,7 @@ dnl
dnl Function checks dnl Function checks
dnl dnl
AC_FUNC_GETGROUPS AC_FUNC_GETGROUPS
AC_CHECK_FUNCS_ONCE([fexecve killpg nl_langinfo pread pwrite openat faccessat wordexp getauxval]) AC_CHECK_FUNCS_ONCE([fexecve killpg nl_langinfo pread pwrite faccessat wordexp getauxval])
case "$host_os" in case "$host_os" in
hpux*) hpux*)
if test X"$ac_cv_func_pread" = X"yes"; then if test X"$ac_cv_func_pread" = X"yes"; then
@ -2720,6 +2720,14 @@ AC_CHECK_FUNCS(nanosleep, [], [
SUDO_APPEND_COMPAT_EXP(sudo_nanosleep) SUDO_APPEND_COMPAT_EXP(sudo_nanosleep)
]) ])
]) ])
AC_CHECK_FUNCS([openat], [], [
AC_LIBOBJ(openat)
SUDO_APPEND_COMPAT_EXP(sudo_openat)
])
AC_CHECK_FUNCS([unlinkat], [], [
AC_LIBOBJ(unlinkat)
SUDO_APPEND_COMPAT_EXP(sudo_unlinkat)
])
AC_CHECK_FUNCS([pipe2], [], [ AC_CHECK_FUNCS([pipe2], [], [
AC_LIBOBJ(pipe2) AC_LIBOBJ(pipe2)
SUDO_APPEND_COMPAT_EXP(sudo_pipe2) SUDO_APPEND_COMPAT_EXP(sudo_pipe2)

View File

@ -479,7 +479,12 @@ __dso_public int sudo_mkstemps(char *path, int slen);
__dso_public int sudo_nanosleep(const struct timespec *timeout, struct timespec *remainder); __dso_public int sudo_nanosleep(const struct timespec *timeout, struct timespec *remainder);
#undef nanosleep #undef nanosleep
# define nanosleep(_a, _b) sudo_nanosleep((_a), (_b)) # define nanosleep(_a, _b) sudo_nanosleep((_a), (_b))
#endif #endif /* HAVE_NANOSLEEP */
#ifndef HAVE_OPENAT
__dso_public int sudo_openat(int dfd, const char *path, int flags, mode_t mode);
# undef openat
# define openat(_a, _b, _c, _d) sudo_openat((_a), (_b), (_c), (_d))
#endif /* HAVE_OPENAT */
#ifndef HAVE_PW_DUP #ifndef HAVE_PW_DUP
__dso_public struct passwd *sudo_pw_dup(const struct passwd *pw); __dso_public struct passwd *sudo_pw_dup(const struct passwd *pw);
# undef pw_dup # undef pw_dup
@ -530,5 +535,10 @@ __dso_public int sudo_pipe2(int fildes[2], int flags);
# undef pipe2 # undef pipe2
# define pipe2(_a, _b) sudo_pipe2((_a), (_b)) # define pipe2(_a, _b) sudo_pipe2((_a), (_b))
#endif /* HAVE_PIPE2 */ #endif /* HAVE_PIPE2 */
#ifndef HAVE_UNLINKAT
__dso_public int sudo_unlinkat(int dfd, const char *path, int flag);
# undef unlinkat
# define unlinkat(_a, _b, _c) sudo_unlinkat((_a), (_b), (_c))
#endif /* HAVE_UNLINKAT */
#endif /* SUDO_COMPAT_H */ #endif /* SUDO_COMPAT_H */

65
lib/util/openat.c Normal file
View File

@ -0,0 +1,65 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 2015, 2019 Todd C. Miller <Todd.Miller@sudo.ws>
*
* 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.
*/
/*
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include "sudo_compat.h"
#ifndef HAVE_OPENAT
int
sudo_openat(int dfd, const char *path, int flags, mode_t mode)
{
int fd, odfd;
if (dfd == AT_FDCWD)
return open(path, flags, mode);
/* Save cwd */
if ((odfd = open(".", O_RDONLY)) == -1)
return -1;
if (fchdir(dfd) == -1) {
close(odfd);
return -1;
}
fd = open(path, flags, mode);
/* Restore cwd */
if (fchdir(odfd) == -1) {
/* Should not happen */
if (fd != -1) {
close(fd);
fd = -1;
}
}
close(odfd);
return fd;
}
#endif /* HAVE_OPENAT */

62
lib/util/unlinkat.c Normal file
View File

@ -0,0 +1,62 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 2019 Todd C. Miller <Todd.Miller@sudo.ws>
*
* 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.
*/
/*
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include "sudo_compat.h"
#ifndef HAVE_UNLINKAT
int
sudo_unlinkat(int dfd, const char *path, int flag)
{
int odfd, ret;
if (dfd == AT_FDCWD)
return unlink(path);
/* Save cwd */
if ((odfd = open(".", O_RDONLY)) == -1)
return -1;
if (fchdir(dfd) == -1) {
close(odfd);
return -1;
}
ret = unlink(path);
/* Restore cwd */
if (fchdir(odfd) == -1) {
/* Should not happen */
ret = -1;
}
close(odfd);
return ret;
}
#endif /* HAVE_UNLINKAT */

View File

@ -262,37 +262,6 @@ sudo_edit_mktemp(const char *ofile, char **tfile)
debug_return_int(tfd); debug_return_int(tfd);
} }
#ifndef HAVE_OPENAT
static int
sudo_openat(int dfd, const char *path, int flags, mode_t mode)
{
int fd, odfd;
debug_decl(sudo_openat, SUDO_DEBUG_EDIT)
if (dfd == AT_FDCWD)
debug_return_int(open(path, flags, mode));
/* Save cwd */
if ((odfd = open(".", O_RDONLY)) == -1)
debug_return_int(-1);
if (fchdir(dfd) == -1) {
close(odfd);
debug_return_int(-1);
}
fd = open(path, flags, mode);
/* Restore cwd */
if (fchdir(odfd) == -1)
sudo_fatal(U_("unable to restore current working directory"));
close(odfd);
debug_return_int(fd);
}
#define openat sudo_openat
#endif /* HAVE_OPENAT */
#ifdef O_NOFOLLOW #ifdef O_NOFOLLOW
static int static int
sudo_edit_openat_nofollow(int dfd, char *path, int oflags, mode_t mode) sudo_edit_openat_nofollow(int dfd, char *path, int oflags, mode_t mode)