mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 09:57:41 +00:00
Add fchmodat() and fstatat() emulation.
Note that fchmodat() emulation does not support AT_SYMLINK_NOFOLLOW
This commit is contained in:
parent
13e3eaad5f
commit
dbf78d0716
2
MANIFEST
2
MANIFEST
@ -111,7 +111,9 @@ lib/util/event.c
|
||||
lib/util/event_poll.c
|
||||
lib/util/event_select.c
|
||||
lib/util/fatal.c
|
||||
lib/util/fchmodat.c
|
||||
lib/util/fnmatch.c
|
||||
lib/util/fstatat.c
|
||||
lib/util/getaddrinfo.c
|
||||
lib/util/getcwd.c
|
||||
lib/util/getdelim.c
|
||||
|
@ -242,6 +242,9 @@
|
||||
/* Define to 1 if you have the `faccessat' function. */
|
||||
#undef HAVE_FACCESSAT
|
||||
|
||||
/* Define to 1 if you have the `fchmodat' function. */
|
||||
#undef HAVE_FCHMODAT
|
||||
|
||||
/* Define to 1 if your system has the F_CLOSEM fcntl. */
|
||||
#undef HAVE_FCNTL_CLOSEM
|
||||
|
||||
@ -257,6 +260,9 @@
|
||||
/* Define to 1 if you have the `fseeko' function. */
|
||||
#undef HAVE_FSEEKO
|
||||
|
||||
/* Define to 1 if you have the `fstatat' function. */
|
||||
#undef HAVE_FSTATAT
|
||||
|
||||
/* Define to 1 if you have the `futime' function. */
|
||||
#undef HAVE_FUTIME
|
||||
|
||||
|
52
configure
vendored
52
configure
vendored
@ -20508,6 +20508,58 @@ esac
|
||||
done
|
||||
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
for ac_func in fchmodat
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "fchmodat" "ac_cv_func_fchmodat"
|
||||
if test "x$ac_cv_func_fchmodat" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_FCHMODAT 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
|
||||
case " $LIBOBJS " in
|
||||
*" fchmodat.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS fchmodat.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
for _sym in sudo_fchmodat; do
|
||||
COMPAT_EXP="${COMPAT_EXP}${_sym}
|
||||
"
|
||||
done
|
||||
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
for ac_func in fstatat
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "fstatat" "ac_cv_func_fstatat"
|
||||
if test "x$ac_cv_func_fstatat" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_FSTATAT 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
|
||||
case " $LIBOBJS " in
|
||||
*" fstatat.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS fstatat.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
for _sym in sudo_fstatat; do
|
||||
COMPAT_EXP="${COMPAT_EXP}${_sym}
|
||||
"
|
||||
done
|
||||
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
@ -2732,6 +2732,14 @@ AC_CHECK_FUNCS([unlinkat], [], [
|
||||
AC_LIBOBJ(unlinkat)
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_unlinkat)
|
||||
])
|
||||
AC_CHECK_FUNCS([fchmodat], [], [
|
||||
AC_LIBOBJ(fchmodat)
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_fchmodat)
|
||||
])
|
||||
AC_CHECK_FUNCS([fstatat], [], [
|
||||
AC_LIBOBJ(fstatat)
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_fstatat)
|
||||
])
|
||||
AC_CHECK_FUNCS([pipe2], [], [
|
||||
AC_LIBOBJ(pipe2)
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_pipe2)
|
||||
|
@ -212,10 +212,13 @@
|
||||
# define UTIME_NOW -2L
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(HAVE_OPENAT) || (!defined(HAVE_FUTIMENS) && !defined(HAVE_UTIMENSAT))
|
||||
#if !defined(HAVE_OPENAT) || (!defined(HAVE_FUTIMENS) && !defined(HAVE_UTIMENSAT)) || !defined(HAVE_FCHMODAT) || !defined(HAVE_FSTATAT) || !defined(HAVE_UNLINKAT)
|
||||
# ifndef AT_FDCWD
|
||||
# define AT_FDCWD -100
|
||||
# endif
|
||||
# ifndef AT_SYMLINK_NOFOLLOW
|
||||
# define AT_SYMLINK_NOFOLLOW 0x02
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* For pipe2() emulation. */
|
||||
@ -385,6 +388,7 @@ int getdomainname(char *, size_t);
|
||||
*/
|
||||
|
||||
struct passwd;
|
||||
struct stat;
|
||||
struct timespec;
|
||||
|
||||
#ifndef HAVE_CLOSEFROM
|
||||
@ -412,6 +416,16 @@ __dso_public int sudo_utimensat(int fd, const char *file, const struct timespec
|
||||
# undef utimensat
|
||||
# define utimensat(_a, _b, _c, _d) sudo_utimensat((_a), (_b), (_c), (_d))
|
||||
#endif /* HAVE_UTIMENSAT */
|
||||
#ifndef HAVE_FCHMODAT
|
||||
__dso_public int sudo_fchmodat(int dfd, const char *path, mode_t mode, int flag);
|
||||
# undef fchmodat
|
||||
# define fchmodat(_a, _b, _c, _d) sudo_fchmodat((_a), (_b), (_c), (_d))
|
||||
#endif /* HAVE_FCHMODAT */
|
||||
#ifndef HAVE_FSTATAT
|
||||
__dso_public int sudo_fstatat(int dfd, const char *path, struct stat *sb, int flag);
|
||||
# undef fstatat
|
||||
# define fstatat(_a, _b, _c, _d) sudo_fstatat((_a), (_b), (_c), (_d))
|
||||
#endif /* HAVE_FSTATAT */
|
||||
#ifndef HAVE_FUTIMENS
|
||||
__dso_public int sudo_futimens(int fd, const struct timespec *times);
|
||||
# undef futimens
|
||||
|
@ -562,6 +562,14 @@ fatal.i: $(srcdir)/fatal.c $(incdir)/compat/getaddrinfo.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
fatal.plog: fatal.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/fatal.c --i-file $< --output-file $@
|
||||
fchmodat.lo: $(srcdir)/fchmodat.c $(incdir)/sudo_compat.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/fchmodat.c
|
||||
fchmodat.i: $(srcdir)/fchmodat.c $(incdir)/sudo_compat.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
fchmodat.plog: fchmodat.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/fchmodat.c --i-file $< --output-file $@
|
||||
fnm_test.lo: $(srcdir)/regress/fnmatch/fnm_test.c $(incdir)/compat/fnmatch.h \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
@ -582,6 +590,12 @@ fnmatch.i: $(srcdir)/fnmatch.c $(incdir)/compat/charclass.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
fnmatch.plog: fnmatch.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/fnmatch.c --i-file $< --output-file $@
|
||||
fstatat.lo: $(srcdir)/fstatat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/fstatat.c
|
||||
fstatat.i: $(srcdir)/fstatat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
fstatat.plog: fstatat.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/fstatat.c --i-file $< --output-file $@
|
||||
getaddrinfo.lo: $(srcdir)/getaddrinfo.c $(incdir)/compat/getaddrinfo.h \
|
||||
$(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getaddrinfo.c
|
||||
@ -866,6 +880,12 @@ nanosleep.i: $(srcdir)/nanosleep.c $(incdir)/compat/stdbool.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
nanosleep.plog: nanosleep.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/nanosleep.c --i-file $< --output-file $@
|
||||
openat.lo: $(srcdir)/openat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/openat.c
|
||||
openat.i: $(srcdir)/openat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
openat.plog: openat.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/openat.c --i-file $< --output-file $@
|
||||
parse_gids_test.lo: $(srcdir)/regress/parse_gids/parse_gids_test.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
|
||||
@ -1246,6 +1266,14 @@ ttysize.i: $(srcdir)/ttysize.c $(incdir)/compat/stdbool.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
ttysize.plog: ttysize.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/ttysize.c --i-file $< --output-file $@
|
||||
unlinkat.lo: $(srcdir)/unlinkat.c $(incdir)/sudo_compat.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/unlinkat.c
|
||||
unlinkat.i: $(srcdir)/unlinkat.c $(incdir)/sudo_compat.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
unlinkat.plog: unlinkat.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/unlinkat.c --i-file $< --output-file $@
|
||||
utimens.lo: $(srcdir)/utimens.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
|
71
lib/util/fchmodat.c
Normal file
71
lib/util/fchmodat.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 <sys/stat.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sudo_compat.h"
|
||||
|
||||
#ifndef HAVE_FCHMODAT
|
||||
int
|
||||
sudo_fchmodat(int dfd, const char *path, mode_t mode, int flag)
|
||||
{
|
||||
int odfd, ret = -1;
|
||||
|
||||
if (ISSET(flag, AT_SYMLINK_NOFOLLOW)) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dfd == (int)AT_FDCWD)
|
||||
return chmod(path, mode);
|
||||
|
||||
/* Save cwd */
|
||||
if ((odfd = open(".", O_RDONLY)) == -1)
|
||||
goto done;
|
||||
|
||||
if (fchdir(dfd) == -1)
|
||||
goto done;
|
||||
|
||||
ret = chmod(path, mode);
|
||||
|
||||
/* Restore cwd */
|
||||
if (fchdir(odfd) == -1) {
|
||||
/* Should not happen */
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
done:
|
||||
if (odfd != -1)
|
||||
close(odfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_FCHMODAT */
|
72
lib/util/fstatat.c
Normal file
72
lib/util/fstatat.c
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 <sys/stat.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sudo_compat.h"
|
||||
|
||||
#ifndef HAVE_FSTATAT
|
||||
int
|
||||
sudo_fstatat(int dfd, const char *path, struct stat *sb, int flag)
|
||||
{
|
||||
int odfd, ret = -1;
|
||||
|
||||
if (dfd == (int)AT_FDCWD) {
|
||||
if (ISSET(flag, AT_SYMLINK_NOFOLLOW))
|
||||
return lstat(path, sb);
|
||||
else
|
||||
return stat(path, sb);
|
||||
}
|
||||
|
||||
/* Save cwd */
|
||||
if ((odfd = open(".", O_RDONLY)) == -1)
|
||||
goto done;
|
||||
|
||||
if (fchdir(dfd) == -1)
|
||||
goto done;
|
||||
|
||||
if (ISSET(flag, AT_SYMLINK_NOFOLLOW))
|
||||
ret = lstat(path, sb);
|
||||
else
|
||||
ret = stat(path, sb);
|
||||
|
||||
/* Restore cwd */
|
||||
if (fchdir(odfd) == -1) {
|
||||
/* Should not happen */
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
done:
|
||||
if (odfd != -1)
|
||||
close(odfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_FSTATAT */
|
2
mkdep.pl
2
mkdep.pl
@ -116,7 +116,7 @@ sub mkdep {
|
||||
# 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:\@DIGEST\@:digest.lo digest_openssl.lo digest_gcrypt.lo:;
|
||||
$makefile =~ s:\@LTLIBOBJS\@:arc4random.lo arc4random_uniform.lo closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getentropy.lo getgrouplist.lo getdelim.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo str2sig.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo utimens.lo vsyslog.lo pipe2.lo:;
|
||||
$makefile =~ s:\@LTLIBOBJS\@:arc4random.lo arc4random_uniform.lo closefrom.lo fchmodat.lo fstatat.lo fnmatch.lo getaddrinfo.lo getcwd.lo getentropy.lo getgrouplist.lo getdelim.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo openat.lo pipe2.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo str2sig.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo unlinkat.lo utimens.lo vsyslog.lo:;
|
||||
|
||||
# Parse OBJS lines
|
||||
my %objs;
|
||||
|
Loading…
x
Reference in New Issue
Block a user