From c9a06873bd033c975e077c72e7a78bdba1a7eec8 Mon Sep 17 00:00:00 2001 From: Xin Ouyang Date: Sat, 28 Jul 2012 16:11:07 +0800 Subject: findutils-4.4.2: fix build failure while no selinux disto_feature. Current patches for selinux simply add selinux codes without conditional switches. And also, the gnulib patch is incomplete. These will cause build failures while we include selinux layers but do not specify selinux in DISTO_FEATURES. Signed-off-by: Xin Ouyang --- .../findutils-4.4.2/findutils-selinux-gnulib.patch | 1174 ------------------ .../findutils-4.4.2/findutils-selinux.patch | 524 -------- .../findutils-with-selinux-gnulib.patch | 1294 ++++++++++++++++++++ .../findutils-4.4.2/findutils-with-selinux.patch | 528 ++++++++ .../findutils/findutils_4.4.2.bbappend | 6 +- 5 files changed, 1825 insertions(+), 1701 deletions(-) delete mode 100644 recipes-extended/findutils/findutils-4.4.2/findutils-selinux-gnulib.patch delete mode 100644 recipes-extended/findutils/findutils-4.4.2/findutils-selinux.patch create mode 100644 recipes-extended/findutils/findutils-4.4.2/findutils-with-selinux-gnulib.patch create mode 100644 recipes-extended/findutils/findutils-4.4.2/findutils-with-selinux.patch diff --git a/recipes-extended/findutils/findutils-4.4.2/findutils-selinux-gnulib.patch b/recipes-extended/findutils/findutils-4.4.2/findutils-selinux-gnulib.patch deleted file mode 100644 index 85a1c3a..0000000 --- a/recipes-extended/findutils/findutils-4.4.2/findutils-selinux-gnulib.patch +++ /dev/null @@ -1,1174 +0,0 @@ -From: Xin Ouyang -Date: Tue, 26 Jun 2012 13:56:52 +0800 -Subject: [PATCH 2/2] findutils: support selinux and gnulib - -Upstream-Status: Inappropriate [configuration] - -This is a F13 SRPM patch. - -Once the selinux-at module appears on the list within import-gnulib.config, -this patch is no longer needed. ---- - aclocal.m4 | 2 + - gnulib/lib/Makefile.am | 43 ++++++ - gnulib/lib/at-func.c | 98 ++++++++++---- - gnulib/lib/getfilecon.c | 87 ++++++++++++ - gnulib/lib/openat.c | 285 ++++++++++++++++++++-------------------- - gnulib/lib/openat.h | 88 ++++++------- - gnulib/lib/se-selinux.in.h | 73 ++++++++++ - gnulib/lib/selinux-at.c | 72 ++++++++++ - gnulib/lib/selinux-at.h | 52 ++++++++ - gnulib/m4/gnulib-comp.m4 | 12 ++ - gnulib/m4/selinux-context-h.m4 | 16 +++ - gnulib/m4/selinux-selinux-h.m4 | 57 ++++++++ - 12 files changed, 665 insertions(+), 220 deletions(-) - create mode 100644 gnulib/lib/getfilecon.c - create mode 100644 gnulib/lib/se-selinux.in.h - create mode 100644 gnulib/lib/selinux-at.c - create mode 100644 gnulib/lib/selinux-at.h - create mode 100644 gnulib/m4/selinux-context-h.m4 - create mode 100644 gnulib/m4/selinux-selinux-h.m4 - -diff --git a/aclocal.m4 b/aclocal.m4 -index 95ff111..0034170 100644 ---- a/aclocal.m4 -+++ b/aclocal.m4 -@@ -115,6 +115,8 @@ m4_include([gnulib/m4/rpmatch.m4]) - m4_include([gnulib/m4/same.m4]) - m4_include([gnulib/m4/save-cwd.m4]) - m4_include([gnulib/m4/savedir.m4]) -+m4_include([gnulib/m4/selinux-context-h.m4]) -+m4_include([gnulib/m4/selinux-selinux-h.m4]) - m4_include([gnulib/m4/setenv.m4]) - m4_include([gnulib/m4/ssize_t.m4]) - m4_include([gnulib/m4/st_dm_mode.m4]) -diff --git a/gnulib/lib/Makefile.am b/gnulib/lib/Makefile.am -index 59ed5f2..b13e509 100644 ---- a/gnulib/lib/Makefile.am -+++ b/gnulib/lib/Makefile.am -@@ -1007,6 +1007,49 @@ EXTRA_libgnulib_a_SOURCES += savedir.c - - ## end gnulib module savedir - -+## begin gnulib module selinux-at -+ -+ -+EXTRA_DIST += selinux-at.c selinux-at.h -+ -+EXTRA_libgnulib_a_SOURCES += selinux-at.c -+ -+## end gnulib module selinux-at -+ -+## begin gnulib module selinux-h -+ -+libgnulib_a_SOURCES += se-context.in.h se-selinux.in.h -+ -+BUILT_SOURCES += selinux/selinux.h -+selinux/selinux.h: se-selinux.in.h -+ $(AM_V_at)$(MKDIR_P) selinux -+ $(AM_V_GEN)rm -f $@-t $@ && \ -+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ -+ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -+ -e 's|@''NEXT_SELINUX_SELINUX_H''@|$(NEXT_SELINUX_SELINUX_H)|g' \ -+ < $(srcdir)/se-selinux.in.h; \ -+ } > $@-t && \ -+ chmod a-x $@-t && \ -+ mv $@-t $@ -+MOSTLYCLEANFILES += selinux/selinux.h selinux/selinux.h-t -+ -+BUILT_SOURCES += $(SELINUX_CONTEXT_H) -+selinux/context.h: se-context.in.h -+ $(AM_V_at)$(MKDIR_P) selinux -+ $(AM_V_GEN)rm -f $@-t $@ && \ -+ cp $(srcdir)/se-context.in.h $@-t && \ -+ chmod a-x $@-t && \ -+ mv $@-t $@ -+MOSTLYCLEANFILES += selinux/context.h selinux/context.h-t -+MOSTLYCLEANDIRS += selinux -+ -+EXTRA_DIST += getfilecon.c -+ -+EXTRA_libgnulib_a_SOURCES += getfilecon.c -+ -+## end gnulib module selinux-h -+ - ## begin gnulib module setenv - - -diff --git a/gnulib/lib/at-func.c b/gnulib/lib/at-func.c -index c7963fe..73be401 100644 ---- a/gnulib/lib/at-func.c -+++ b/gnulib/lib/at-func.c -@@ -1,5 +1,5 @@ - /* Define an at-style functions like fstatat, unlinkat, fchownat, etc. -- Copyright (C) 2006 Free Software Foundation, Inc. -+ Copyright (C) 2006, 2009 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by -@@ -16,62 +16,106 @@ - - /* written by Jim Meyering */ - --#define CALL_FUNC(F) \ -- (AT_FUNC_USE_F1_COND \ -+#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ -+#include "openat.h" -+#include "openat-priv.h" -+#include "save-cwd.h" -+ -+#ifdef AT_FUNC_USE_F1_COND -+# define CALL_FUNC(F) \ -+ (flag == AT_FUNC_USE_F1_COND \ - ? AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS) \ - : AT_FUNC_F2 (F AT_FUNC_POST_FILE_ARGS)) -+# define VALIDATE_FLAG(F) \ -+ if (flag & ~AT_FUNC_USE_F1_COND) \ -+ { \ -+ errno = EINVAL; \ -+ return FUNC_FAIL; \ -+ } -+#else -+# define CALL_FUNC(F) (AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS)) -+# define VALIDATE_FLAG(F) /* empty */ -+#endif -+ -+#ifdef AT_FUNC_RESULT -+# define FUNC_RESULT AT_FUNC_RESULT -+#else -+# define FUNC_RESULT int -+#endif -+ -+#ifdef AT_FUNC_FAIL -+# define FUNC_FAIL AT_FUNC_FAIL -+#else -+# define FUNC_FAIL -1 -+#endif - --/* Call AT_FUNC_F1 or AT_FUNC_F2 (testing AT_FUNC_USE_F1_COND to -- determine which) to operate on FILE, which is in the directory -- open on descriptor FD. If possible, do it without changing the -+/* Call AT_FUNC_F1 to operate on FILE, which is in the directory -+ open on descriptor FD. If AT_FUNC_USE_F1_COND is defined to a value, -+ AT_FUNC_POST_FILE_PARAM_DECLS must inlude a parameter named flag; -+ call AT_FUNC_F2 if FLAG is 0 or fail if FLAG contains more bits than -+ AT_FUNC_USE_F1_COND. Return int and fail with -1 unless AT_FUNC_RESULT -+ or AT_FUNC_FAIL are defined. If possible, do it without changing the - working directory. Otherwise, resort to using save_cwd/fchdir, - then AT_FUNC_F?/restore_cwd. If either the save_cwd or the restore_cwd - fails, then give a diagnostic and exit nonzero. */ --int -+FUNC_RESULT - AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS) - { -+ /* Be careful to choose names unlikely to conflict with -+ AT_FUNC_POST_FILE_PARAM_DECLS. */ - struct saved_cwd saved_cwd; - int saved_errno; -- int err; -+ FUNC_RESULT err; -+ -+ VALIDATE_FLAG (flag); - - if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) - return CALL_FUNC (file); - - { -- char buf[OPENAT_BUFFER_SIZE]; -- char *proc_file = openat_proc_name (buf, fd, file); -+ char proc_buf[OPENAT_BUFFER_SIZE]; -+ char *proc_file = openat_proc_name (proc_buf, fd, file); - if (proc_file) - { -- int proc_result = CALL_FUNC (proc_file); -- int proc_errno = errno; -- if (proc_file != buf) -- free (proc_file); -- /* If the syscall succeeds, or if it fails with an unexpected -- errno value, then return right away. Otherwise, fall through -- and resort to using save_cwd/restore_cwd. */ -- if (0 <= proc_result) -- return proc_result; -- if (! EXPECTED_ERRNO (proc_errno)) -- { -- errno = proc_errno; -- return proc_result; -- } -+ FUNC_RESULT proc_result = CALL_FUNC (proc_file); -+ int proc_errno = errno; -+ if (proc_file != proc_buf) -+ free (proc_file); -+ /* If the syscall succeeds, or if it fails with an unexpected -+ errno value, then return right away. Otherwise, fall through -+ and resort to using save_cwd/restore_cwd. */ -+ if (FUNC_FAIL != proc_result) -+ return proc_result; -+ if (! EXPECTED_ERRNO (proc_errno)) -+ { -+ errno = proc_errno; -+ return proc_result; -+ } - } - } - - if (save_cwd (&saved_cwd) != 0) - openat_save_fail (errno); -+ if (0 <= fd && fd == saved_cwd.desc) -+ { -+ /* If saving the working directory collides with the user's -+ requested fd, then the user's fd must have been closed to -+ begin with. */ -+ free_cwd (&saved_cwd); -+ errno = EBADF; -+ return FUNC_FAIL; -+ } - - if (fchdir (fd) != 0) - { - saved_errno = errno; - free_cwd (&saved_cwd); - errno = saved_errno; -- return -1; -+ return FUNC_FAIL; - } - - err = CALL_FUNC (file); -- saved_errno = (err < 0 ? errno : 0); -+ saved_errno = (err == FUNC_FAIL ? errno : 0); - - if (restore_cwd (&saved_cwd) != 0) - openat_restore_fail (errno); -@@ -83,3 +127,5 @@ AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS) - return err; - } - #undef CALL_FUNC -+#undef FUNC_RESULT -+#undef FUNC_FAIL -diff --git a/gnulib/lib/getfilecon.c b/gnulib/lib/getfilecon.c -new file mode 100644 -index 0000000..d712307 ---- /dev/null -+++ b/gnulib/lib/getfilecon.c -@@ -0,0 +1,87 @@ -+/* wrap getfilecon, lgetfilecon, and fgetfilecon -+ Copyright (C) 2009 Free Software Foundation, Inc. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3, or (at your option) -+ any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software Foundation, -+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -+ -+/* written by Jim Meyering */ -+ -+#include -+ -+#include -+ -+#include -+#include -+#include -+ -+/* FIXME: remove this once there is an errno-gnu module -+ that guarantees the definition of ENODATA. */ -+#ifndef ENODATA -+# define ENODATA ENOTSUP -+#endif -+ -+#undef getfilecon -+#undef lgetfilecon -+#undef fgetfilecon -+int getfilecon (char const *file, security_context_t *con); -+int lgetfilecon (char const *file, security_context_t *con); -+int fgetfilecon (int fd, security_context_t *con); -+ -+/* getfilecon, lgetfilecon, and fgetfilecon can all misbehave, be it -+ via an old version of libselinux where these would return 0 and set the -+ result context to NULL, or via a modern kernel+lib operating on a file -+ from a disk whose attributes were set by a kernel from around 2006. -+ In that latter case, the functions return a length of 10 for the -+ "unlabeled" context. Map both failures to a return value of -1, and -+ set errno to ENOTSUP in the first case, and ENODATA in the latter. */ -+ -+static inline int -+map_to_failure (int ret, security_context_t *con) -+{ -+ if (ret == 0) -+ { -+ errno = ENOTSUP; -+ return -1; -+ } -+ -+ if (ret == 10 && strcmp (*con, "unlabeled") == 0) -+ { -+ freecon (*con); -+ errno = ENODATA; -+ return -1; -+ } -+ -+ return ret; -+} -+ -+int -+rpl_getfilecon (char const *file, security_context_t *con) -+{ -+ int ret = getfilecon (file, con); -+ return map_to_failure (ret, con); -+} -+ -+int -+rpl_lgetfilecon (char const *file, security_context_t *con) -+{ -+ int ret = lgetfilecon (file, con); -+ return map_to_failure (ret, con); -+} -+ -+int -+rpl_fgetfilecon (int fd, security_context_t *con) -+{ -+ int ret = fgetfilecon (fd, con); -+ return map_to_failure (ret, con); -+} -diff --git a/gnulib/lib/openat.c b/gnulib/lib/openat.c -index 73f24b0..2b15bb5 100644 ---- a/gnulib/lib/openat.c -+++ b/gnulib/lib/openat.c -@@ -1,5 +1,5 @@ - /* provide a replacement openat function -- Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. -+ Copyright (C) 2004-2009 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by -@@ -22,13 +22,108 @@ - - #include - #include -+#include -+#include - - #include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ --#include "fcntl--.h" --#include "lstat.h" - #include "openat-priv.h" - #include "save-cwd.h" - -+#if HAVE_OPENAT -+ -+# undef openat -+ -+/* Like openat, but work around Solaris 9 bugs with trailing slash. */ -+int -+rpl_openat (int dfd, char const *filename, int flags, ...) -+{ -+ mode_t mode; -+ int fd; -+ -+ mode = 0; -+ if (flags & O_CREAT) -+ { -+ va_list arg; -+ va_start (arg, flags); -+ -+ /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 -+ creates crashing code when 'mode_t' is smaller than 'int'. */ -+ mode = va_arg (arg, PROMOTED_MODE_T); -+ -+ va_end (arg); -+ } -+ -+#if OPEN_TRAILING_SLASH_BUG -+ /* If the filename ends in a slash and one of O_CREAT, O_WRONLY, O_RDWR -+ is specified, then fail. -+ Rationale: POSIX -+ says that -+ "A pathname that contains at least one non-slash character and that -+ ends with one or more trailing slashes shall be resolved as if a -+ single dot character ( '.' ) were appended to the pathname." -+ and -+ "The special filename dot shall refer to the directory specified by -+ its predecessor." -+ If the named file already exists as a directory, then -+ - if O_CREAT is specified, open() must fail because of the semantics -+ of O_CREAT, -+ - if O_WRONLY or O_RDWR is specified, open() must fail because POSIX -+ says that it -+ fails with errno = EISDIR in this case. -+ If the named file does not exist or does not name a directory, then -+ - if O_CREAT is specified, open() must fail since open() cannot create -+ directories, -+ - if O_WRONLY or O_RDWR is specified, open() must fail because the -+ file does not contain a '.' directory. */ -+ if (flags & (O_CREAT | O_WRONLY | O_RDWR)) -+ { -+ size_t len = strlen (filename); -+ if (len > 0 && filename[len - 1] == '/') -+ { -+ errno = EISDIR; -+ return -1; -+ } -+ } -+#endif -+ -+ fd = openat (dfd, filename, flags, mode); -+ -+#if OPEN_TRAILING_SLASH_BUG -+ /* If the filename ends in a slash and fd does not refer to a directory, -+ then fail. -+ Rationale: POSIX -+ says that -+ "A pathname that contains at least one non-slash character and that -+ ends with one or more trailing slashes shall be resolved as if a -+ single dot character ( '.' ) were appended to the pathname." -+ and -+ "The special filename dot shall refer to the directory specified by -+ its predecessor." -+ If the named file without the slash is not a directory, open() must fail -+ with ENOTDIR. */ -+ if (fd >= 0) -+ { -+ /* We know len is positive, since open did not fail with ENOENT. */ -+ size_t len = strlen (filename); -+ if (filename[len - 1] == '/') -+ { -+ struct stat statbuf; -+ -+ if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode)) -+ { -+ close (fd); -+ errno = ENOTDIR; -+ return -1; -+ } -+ } -+ } -+#endif -+ -+ return fd; -+} -+ -+#else /* !HAVE_OPENAT */ -+ - /* Replacement for Solaris' openat function. - - First, try to simulate it via open ("/proc/self/fd/FD/FILE"). -@@ -47,12 +142,9 @@ openat (int fd, char const *file, int flags, ...) - va_list arg; - va_start (arg, flags); - -- /* If mode_t is narrower than int, use the promoted type (int), -- not mode_t. Use sizeof to guess whether mode_t is narrower; -- we don't know of any practical counterexamples. */ -- mode = (sizeof (mode_t) < sizeof (int) -- ? va_arg (arg, int) -- : va_arg (arg, mode_t)); -+ /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 -+ creates crashing code when 'mode_t' is smaller than 'int'. */ -+ mode = va_arg (arg, PROMOTED_MODE_T); - - va_end (arg); - } -@@ -73,7 +165,7 @@ openat (int fd, char const *file, int flags, ...) - - int - openat_permissive (int fd, char const *file, int flags, mode_t mode, -- int *cwd_errno) -+ int *cwd_errno) - { - struct saved_cwd saved_cwd; - int saved_errno; -@@ -88,18 +180,18 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode, - char *proc_file = openat_proc_name (buf, fd, file); - if (proc_file) - { -- int open_result = open (proc_file, flags, mode); -- int open_errno = errno; -- if (proc_file != buf) -- free (proc_file); -- /* If the syscall succeeds, or if it fails with an unexpected -- errno value, then return right away. Otherwise, fall through -- and resort to using save_cwd/restore_cwd. */ -- if (0 <= open_result || ! EXPECTED_ERRNO (open_errno)) -- { -- errno = open_errno; -- return open_result; -- } -+ int open_result = open (proc_file, flags, mode); -+ int open_errno = errno; -+ if (proc_file != buf) -+ free (proc_file); -+ /* If the syscall succeeds, or if it fails with an unexpected -+ errno value, then return right away. Otherwise, fall through -+ and resort to using save_cwd/restore_cwd. */ -+ if (0 <= open_result || ! EXPECTED_ERRNO (open_errno)) -+ { -+ errno = open_errno; -+ return open_result; -+ } - } - } - -@@ -107,9 +199,18 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode, - if (! save_ok) - { - if (! cwd_errno) -- openat_save_fail (errno); -+ openat_save_fail (errno); - *cwd_errno = errno; - } -+ if (0 <= fd && fd == saved_cwd.desc) -+ { -+ /* If saving the working directory collides with the user's -+ requested fd, then the user's fd must have been closed to -+ begin with. */ -+ free_cwd (&saved_cwd); -+ errno = EBADF; -+ return -1; -+ } - - err = fchdir (fd); - saved_errno = errno; -@@ -119,11 +220,17 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode, - err = open (file, flags, mode); - saved_errno = errno; - if (save_ok && restore_cwd (&saved_cwd) != 0) -- { -- if (! cwd_errno) -- openat_restore_fail (errno); -- *cwd_errno = errno; -- } -+ { -+ if (! cwd_errno) -+ { -+ /* Don't write a message to just-created fd 2. */ -+ saved_errno = errno; -+ if (err == STDERR_FILENO) -+ close (err); -+ openat_restore_fail (saved_errno); -+ } -+ *cwd_errno = errno; -+ } - } - - free_cwd (&saved_cwd); -@@ -144,125 +251,15 @@ openat_needs_fchdir (void) - char buf[OPENAT_BUFFER_SIZE]; - char *proc_file = openat_proc_name (buf, fd, "."); - if (proc_file) -- { -- needs_fchdir = false; -- if (proc_file != buf) -- free (proc_file); -- } -+ { -+ needs_fchdir = false; -+ if (proc_file != buf) -+ free (proc_file); -+ } - close (fd); - } - - return needs_fchdir; - } - --#if !HAVE_FDOPENDIR -- --/* Replacement for Solaris' function by the same name. -- -- First, try to simulate it via opendir ("/proc/self/fd/FD"). Failing -- that, simulate it by doing save_cwd/fchdir/opendir(".")/restore_cwd. -- If either the save_cwd or the restore_cwd fails (relatively unlikely), -- then give a diagnostic and exit nonzero. -- Otherwise, this function works just like Solaris' fdopendir. -- -- W A R N I N G: -- Unlike the other fd-related functions here, this one -- effectively consumes its FD parameter. The caller should not -- close or otherwise manipulate FD if this function returns successfully. */ --DIR * --fdopendir (int fd) --{ -- struct saved_cwd saved_cwd; -- int saved_errno; -- DIR *dir; -- -- char buf[OPENAT_BUFFER_SIZE]; -- char *proc_file = openat_proc_name (buf, fd, "."); -- if (proc_file) -- { -- dir = opendir (proc_file); -- saved_errno = errno; -- } -- else -- { -- dir = NULL; -- saved_errno = EOPNOTSUPP; -- } -- -- /* If the syscall fails with an expected errno value, resort to -- save_cwd/restore_cwd. */ -- if (! dir && EXPECTED_ERRNO (saved_errno)) -- { -- if (save_cwd (&saved_cwd) != 0) -- openat_save_fail (errno); -- -- if (fchdir (fd) != 0) -- { -- dir = NULL; -- saved_errno = errno; -- } -- else -- { -- dir = opendir ("."); -- saved_errno = errno; -- -- if (restore_cwd (&saved_cwd) != 0) -- openat_restore_fail (errno); -- } -- -- free_cwd (&saved_cwd); -- } -- -- if (dir) -- close (fd); -- if (proc_file != buf) -- free (proc_file); -- errno = saved_errno; -- return dir; --} -- --#endif -- --/* Replacement for Solaris' function by the same name. -- -- First, try to simulate it via l?stat ("/proc/self/fd/FD/FILE"). -- Failing that, simulate it via save_cwd/fchdir/(stat|lstat)/restore_cwd. -- If either the save_cwd or the restore_cwd fails (relatively unlikely), -- then give a diagnostic and exit nonzero. -- Otherwise, this function works just like Solaris' fstatat. */ -- --#define AT_FUNC_NAME fstatat --#define AT_FUNC_F1 lstat --#define AT_FUNC_F2 stat --#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW --#define AT_FUNC_POST_FILE_PARAM_DECLS , struct stat *st, int flag --#define AT_FUNC_POST_FILE_ARGS , st --#include "at-func.c" --#undef AT_FUNC_NAME --#undef AT_FUNC_F1 --#undef AT_FUNC_F2 --#undef AT_FUNC_USE_F1_COND --#undef AT_FUNC_POST_FILE_PARAM_DECLS --#undef AT_FUNC_POST_FILE_ARGS -- --/* Replacement for Solaris' function by the same name. -- -- First, try to simulate it via (unlink|rmdir) ("/proc/self/fd/FD/FILE"). -- Failing that, simulate it via save_cwd/fchdir/(unlink|rmdir)/restore_cwd. -- If either the save_cwd or the restore_cwd fails (relatively unlikely), -- then give a diagnostic and exit nonzero. -- Otherwise, this function works just like Solaris' unlinkat. */ -- --#define AT_FUNC_NAME unlinkat --#define AT_FUNC_F1 rmdir --#define AT_FUNC_F2 unlink --#define AT_FUNC_USE_F1_COND flag == AT_REMOVEDIR --#define AT_FUNC_POST_FILE_PARAM_DECLS , int flag --#define AT_FUNC_POST_FILE_ARGS /* empty */ --#include "at-func.c" --#undef AT_FUNC_NAME --#undef AT_FUNC_F1 --#undef AT_FUNC_F2 --#undef AT_FUNC_USE_F1_COND --#undef AT_FUNC_POST_FILE_PARAM_DECLS --#undef AT_FUNC_POST_FILE_ARGS -+#endif /* !HAVE_OPENAT */ -diff --git a/gnulib/lib/openat.h b/gnulib/lib/openat.h -index b5e4f11..433b998 100644 ---- a/gnulib/lib/openat.h -+++ b/gnulib/lib/openat.h -@@ -1,5 +1,5 @@ - /* provide a replacement openat function -- Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. -+ Copyright (C) 2004-2006, 2008-2009 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by -@@ -16,6 +16,9 @@ - - /* written by Jim Meyering */ - -+#ifndef _GL_HEADER_OPENAT -+#define _GL_HEADER_OPENAT -+ - #include - - #include -@@ -25,7 +28,7 @@ - #include - - #ifndef __attribute__ --# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) - # define __attribute__(x) /* empty */ - # endif - #endif -@@ -34,46 +37,10 @@ - # define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) - #endif - --/* Work around a bug in Solaris 9 and 10: AT_FDCWD is positive. Its -- value exceeds INT_MAX, so its use as an int doesn't conform to the -- C standard, and GCC and Sun C complain in some cases. If the bug -- is present, undef AT_FDCWD here, so it can be redefined below. */ --#if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553 --# undef AT_FDCWD --#endif -- --/* Use the same bit pattern as Solaris 9, but with the proper -- signedness. The bit pattern is important, in case this actually is -- Solaris with the above workaround. */ --#ifndef AT_FDCWD --# define AT_FDCWD (-3041965) --#endif -- --/* Use the same values as Solaris 9. This shouldn't matter, but -- there's no real reason to differ. */ --#ifndef AT_SYMLINK_NOFOLLOW --# define AT_SYMLINK_NOFOLLOW 4096 --# define AT_REMOVEDIR 1 --#endif -- --#ifdef __OPENAT_PREFIX -+#if !HAVE_OPENAT - --# undef openat --# define __OPENAT_CONCAT(x, y) x ## y --# define __OPENAT_XCONCAT(x, y) __OPENAT_CONCAT (x, y) --# define __OPENAT_ID(y) __OPENAT_XCONCAT (__OPENAT_PREFIX, y) --# define openat __OPENAT_ID (openat) --int openat (int fd, char const *file, int flags, /* mode_t mode */ ...); - int openat_permissive (int fd, char const *file, int flags, mode_t mode, - int *cwd_errno); --# if ! HAVE_FDOPENDIR --# define fdopendir __OPENAT_ID (fdopendir) --# endif --DIR *fdopendir (int fd); --# define fstatat __OPENAT_ID (fstatat) --int fstatat (int fd, char const *file, struct stat *st, int flag); --# define unlinkat __OPENAT_ID (unlinkat) --int unlinkat (int fd, char const *file, int flag); - bool openat_needs_fchdir (void); - - #else -@@ -84,19 +51,8 @@ bool openat_needs_fchdir (void); - - #endif - --#if HAVE_OPENAT && ! LSTAT_FOLLOWS_SLASHED_SYMLINK --int rpl_fstatat (int fd, char const *file, struct stat *st, int flag); --# if !COMPILING_FSTATAT --# undef fstatat --# define fstatat rpl_fstatat --# endif --#endif -- --int mkdirat (int fd, char const *file, mode_t mode); - void openat_restore_fail (int) ATTRIBUTE_NORETURN; - void openat_save_fail (int) ATTRIBUTE_NORETURN; --int fchmodat (int fd, char const *file, mode_t mode, int flag); --int fchownat (int fd, char const *file, uid_t owner, gid_t group, int flag); - - /* Using these function names makes application code - slightly more readable than it would be with -@@ -124,3 +80,35 @@ lchmodat (int fd, char const *file, mode_t mode) - { - return fchmodat (fd, file, mode, AT_SYMLINK_NOFOLLOW); - } -+ -+static inline int -+statat (int fd, char const *name, struct stat *st) -+{ -+ return fstatat (fd, name, st, 0); -+} -+ -+static inline int -+lstatat (int fd, char const *name, struct stat *st) -+{ -+ return fstatat (fd, name, st, AT_SYMLINK_NOFOLLOW); -+} -+ -+#if GNULIB_FACCESSAT -+/* For now, there are no wrappers named laccessat or leuidaccessat, -+ since gnulib doesn't support faccessat(,AT_SYMLINK_NOFOLLOW) and -+ since access rights on symlinks are of limited utility. */ -+ -+static inline int -+accessat (int fd, char const *file, int mode) -+{ -+ return faccessat (fd, file, mode, 0); -+} -+ -+static inline int -+euidaccessat (int fd, char const *file, int mode) -+{ -+ return faccessat (fd, file, mode, AT_EACCESS); -+} -+#endif -+ -+#endif /* _GL_HEADER_OPENAT */ -diff --git a/gnulib/lib/se-selinux.in.h b/gnulib/lib/se-selinux.in.h -new file mode 100644 -index 0000000..3f30a3c ---- /dev/null -+++ b/gnulib/lib/se-selinux.in.h -@@ -0,0 +1,73 @@ -+#ifndef _GL_SELINUX_SELINUX_H -+# define _GL_SELINUX_SELINUX_H -+ -+# if __GNUC__ >= 3 -+#pragma GCC system_header -+# endif -+ -+# if HAVE_SELINUX_SELINUX_H -+ -+#@INCLUDE_NEXT@ @NEXT_SELINUX_SELINUX_H@ -+ -+# else -+ -+# include -+# include -+ -+typedef unsigned short security_class_t; -+# define security_context_t char* -+# define is_selinux_enabled() 0 -+ -+static inline int getcon (security_context_t *con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline void freecon (security_context_t con _UNUSED_PARAMETER_) {} -+ -+ -+static inline int getfscreatecon (security_context_t *con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int setfscreatecon (security_context_t con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int matchpathcon (char const *file _UNUSED_PARAMETER_, -+ mode_t m _UNUSED_PARAMETER_, -+ security_context_t *con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int getfilecon (char const *file _UNUSED_PARAMETER_, -+ security_context_t *con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int lgetfilecon (char const *file _UNUSED_PARAMETER_, -+ security_context_t *con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int fgetfilecon (int fd, -+ security_context_t *con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int setfilecon (char const *file _UNUSED_PARAMETER_, -+ security_context_t con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int lsetfilecon (char const *file _UNUSED_PARAMETER_, -+ security_context_t con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int fsetfilecon (int fd _UNUSED_PARAMETER_, -+ security_context_t con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+ -+static inline int security_check_context -+ (security_context_t con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int security_check_context_raw -+ (security_context_t con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int setexeccon (security_context_t con _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int security_compute_create -+ (security_context_t scon _UNUSED_PARAMETER_, -+ security_context_t tcon _UNUSED_PARAMETER_, -+ security_class_t tclass _UNUSED_PARAMETER_, -+ security_context_t *newcon _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+static inline int matchpathcon_init_prefix -+ (char const *path _UNUSED_PARAMETER_, -+ char const *prefix _UNUSED_PARAMETER_) -+ { errno = ENOTSUP; return -1; } -+ -+# endif -+#endif /* _GL_SELINUX_SELINUX_H */ -diff --git a/gnulib/lib/selinux-at.c b/gnulib/lib/selinux-at.c -new file mode 100644 -index 0000000..65f938b ---- /dev/null -+++ b/gnulib/lib/selinux-at.c -@@ -0,0 +1,72 @@ -+/* openat-style fd-relative functions for SE Linux -+ Copyright (C) 2007, 2009 Free Software Foundation, Inc. -+ -+ This program is free software: you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation, either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . */ -+ -+/* written by Jim Meyering */ -+ -+#include -+ -+#include "selinux-at.h" -+#include "openat.h" -+ -+#include -+#include -+#include -+#include -+ -+#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ -+#include "save-cwd.h" -+ -+#include "openat-priv.h" -+ -+#define AT_FUNC_NAME getfileconat -+#define AT_FUNC_F1 getfilecon -+#define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t *con -+#define AT_FUNC_POST_FILE_ARGS , con -+#include "at-func.c" -+#undef AT_FUNC_NAME -+#undef AT_FUNC_F1 -+#undef AT_FUNC_POST_FILE_PARAM_DECLS -+#undef AT_FUNC_POST_FILE_ARGS -+ -+#define AT_FUNC_NAME lgetfileconat -+#define AT_FUNC_F1 lgetfilecon -+#define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t *con -+#define AT_FUNC_POST_FILE_ARGS , con -+#include "at-func.c" -+#undef AT_FUNC_NAME -+#undef AT_FUNC_F1 -+#undef AT_FUNC_POST_FILE_PARAM_DECLS -+#undef AT_FUNC_POST_FILE_ARGS -+ -+#define AT_FUNC_NAME setfileconat -+#define AT_FUNC_F1 setfilecon -+#define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t con -+#define AT_FUNC_POST_FILE_ARGS , con -+#include "at-func.c" -+#undef AT_FUNC_NAME -+#undef AT_FUNC_F1 -+#undef AT_FUNC_POST_FILE_PARAM_DECLS -+#undef AT_FUNC_POST_FILE_ARGS -+ -+#define AT_FUNC_NAME lsetfileconat -+#define AT_FUNC_F1 lsetfilecon -+#define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t con -+#define AT_FUNC_POST_FILE_ARGS , con -+#include "at-func.c" -+#undef AT_FUNC_NAME -+#undef AT_FUNC_F1 -+#undef AT_FUNC_POST_FILE_PARAM_DECLS -+#undef AT_FUNC_POST_FILE_ARGS -diff --git a/gnulib/lib/selinux-at.h b/gnulib/lib/selinux-at.h -new file mode 100644 -index 0000000..1d84c19 ---- /dev/null -+++ b/gnulib/lib/selinux-at.h -@@ -0,0 +1,52 @@ -+/* Prototypes for openat-style fd-relative SELinux functions -+ Copyright (C) 2007, 2009 Free Software Foundation, Inc. -+ -+ This program is free software: you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation, either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . */ -+ -+#include -+#include -+ -+/* These are the dir-fd-relative variants of the functions without the -+ "at" suffix. For example, getfileconat (AT_FDCWD, file, &c) is usually -+ equivalent to getfilecon (file, &c). The emulation is accomplished -+ by first attempting getfilecon ("/proc/self/fd/DIR_FD/FILE", &c). -+ Failing that, simulate it via save_cwd/fchdir/getfilecon/restore_cwd. -+ If either the save_cwd or the restore_cwd fails (relatively unlikely), -+ then give a diagnostic and exit nonzero. */ -+ -+/* dir-fd-relative getfilecon. Set *CON to the SELinux security context -+ of the file specified by DIR_FD and FILE and return the length of *CON. -+ DIR_FD and FILE are interpreted as for fstatat[*]. A non-NULL *CON -+ must be freed with freecon. Upon error, set *CON to NULL, set errno -+ and return -1. -+ [*] with flags=0 here, with flags=AT_SYMLINK_NOFOLLOW for lgetfileconat */ -+int getfileconat (int dir_fd, char const *file, security_context_t *con); -+ -+/* dir-fd-relative lgetfilecon. This function is just like getfileconat, -+ except when DIR_FD and FILE specify a symlink: lgetfileconat operates on -+ the symlink, while getfileconat operates on the referent of the symlink. */ -+int lgetfileconat (int dir_fd, char const *file, security_context_t *con); -+ -+/* dir-fd-relative setfilecon. Set the SELinux security context of -+ the file specified by DIR_FD and FILE to CON. DIR_FD and FILE are -+ interpreted as for fstatat[*]. Upon success, return 0. -+ Otherwise, return -1 and set errno. */ -+int setfileconat (int dir_fd, char const *file, security_context_t con); -+ -+/* dir-fd-relative lsetfilecon. This function is just like setfileconat, -+ except that rather than dereferencing a symlink, this function affects it. */ -+/* dir-fd-relative lsetfilecon. This function is just like setfileconat, -+ except when DIR_FD and FILE specify a symlink: lsetfileconat operates on -+ the symlink, while setfileconat operates on the referent of the symlink. */ -+int lsetfileconat (int dir_fd, char const *file, security_context_t con); -diff --git a/gnulib/m4/gnulib-comp.m4 b/gnulib/m4/gnulib-comp.m4 -index 1efe223..87f11dd 100644 ---- a/gnulib/m4/gnulib-comp.m4 -+++ b/gnulib/m4/gnulib-comp.m4 -@@ -165,6 +165,11 @@ AC_DEFUN([gl_INIT], - gl_SAME - gl_SAVE_CWD - gl_SAVEDIR -+ AC_CHECK_HEADERS([selinux/flask.h]) -+ AC_LIBOBJ([selinux-at]) -+ gl_HEADERS_SELINUX_SELINUX_H -+ gl_HEADERS_SELINUX_CONTEXT_H -+ AC_REQUIRE([AC_C_INLINE]) - gl_FUNC_SETENV - gl_FUNC_UNSETENV - gt_TYPE_SSIZE_T -@@ -425,6 +430,7 @@ AC_DEFUN([gl_FILE_LIST], [ - lib/getdate.h - lib/getdate.y - lib/getdelim.c -+ lib/getfilecon.c - lib/getline.c - lib/getopt.c - lib/getopt.in.h -@@ -506,6 +512,10 @@ AC_DEFUN([gl_FILE_LIST], [ - lib/save-cwd.h - lib/savedir.c - lib/savedir.h -+ lib/se-context.in.h -+ lib/se-selinux.in.h -+ lib/selinux-at.c -+ lib/selinux-at.h - lib/setenv.c - lib/setenv.h - lib/stat-macros.h -@@ -688,6 +698,8 @@ AC_DEFUN([gl_FILE_LIST], [ - m4/same.m4 - m4/save-cwd.m4 - m4/savedir.m4 -+ m4/selinux-context-h.m4 -+ m4/selinux-selinux-h.m4 - m4/setenv.m4 - m4/size_max.m4 - m4/ssize_t.m4 -diff --git a/gnulib/m4/selinux-context-h.m4 b/gnulib/m4/selinux-context-h.m4 -new file mode 100644 -index 0000000..6b0bed1 ---- /dev/null -+++ b/gnulib/m4/selinux-context-h.m4 -@@ -0,0 +1,16 @@ -+# serial 1 -*- Autoconf -*- -+# Copyright (C) 2006, 2007 Free Software Foundation, Inc. -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. -+ -+# From Jim Meyering -+# Provide , if necessary. -+ -+AC_DEFUN([gl_HEADERS_SELINUX_CONTEXT_H], -+[ -+ AC_CHECK_HEADERS([selinux/context.h], -+ [SELINUX_CONTEXT_H=], -+ [SELINUX_CONTEXT_H=selinux/context.h]) -+ AC_SUBST([SELINUX_CONTEXT_H]) -+]) -diff --git a/gnulib/m4/selinux-selinux-h.m4 b/gnulib/m4/selinux-selinux-h.m4 -new file mode 100644 -index 0000000..767c4f7 ---- /dev/null -+++ b/gnulib/m4/selinux-selinux-h.m4 -@@ -0,0 +1,57 @@ -+# serial 3 -*- Autoconf -*- -+# Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. -+ -+# From Jim Meyering -+# Provide , if necessary. -+# If it is already present, provide wrapper functions to guard against -+# misbehavior from getfilecon, lgetfilecon, and fgetfilecon. -+ -+AC_DEFUN([gl_HEADERS_SELINUX_SELINUX_H], -+[ -+ AC_REQUIRE([gl_LIBSELINUX]) -+ AC_CHECK_HEADERS([selinux/selinux.h]) -+ -+ if test "$ac_cv_header_selinux_selinux_h" = yes; then -+ # We do have , so do compile getfilecon.c -+ # and arrange to use its wrappers. -+ AC_LIBOBJ([getfilecon]) -+ gl_CHECK_NEXT_HEADERS([selinux/selinux.h]) -+ AC_DEFINE([getfilecon], [rpl_getfilecon], -+ [Always use our getfilecon wrapper.]) -+ AC_DEFINE([lgetfilecon], [rpl_lgetfilecon], -+ [Always use our lgetfilecon wrapper.]) -+ AC_DEFINE([fgetfilecon], [rpl_fgetfilecon], -+ [Always use our fgetfilecon wrapper.]) -+ fi -+ -+ case "$ac_cv_search_setfilecon:$ac_cv_header_selinux_selinux_h" in -+ no:*) # already warned -+ ;; -+ *:no) -+ AC_MSG_WARN([libselinux was found but selinux/selinux.h is missing.]) -+ AC_MSG_WARN([AC_PACKAGE_NAME will be compiled without SELinux support.]) -+ esac -+]) -+ -+AC_DEFUN([gl_LIBSELINUX], -+[ -+ AC_REQUIRE([AC_CANONICAL_HOST]) -+ AC_REQUIRE([AC_CANONICAL_BUILD]) -+ LIB_SELINUX= -+ gl_save_LIBS=$LIBS -+ AC_SEARCH_LIBS([setfilecon], [selinux], -+ [test "$ac_cv_search_setfilecon" = "none required" || -+ LIB_SELINUX=$ac_cv_search_setfilecon]) -+ AC_SUBST([LIB_SELINUX]) -+ LIBS=$gl_save_LIBS -+ -+ # Warn if SELinux is found but libselinux is absent; -+ if test "$ac_cv_search_setfilecon" = no && -+ test "$host" = "$build" && test -d /selinux; then -+ AC_MSG_WARN([This system supports SELinux but libselinux is missing.]) -+ AC_MSG_WARN([AC_PACKAGE_NAME will be compiled without SELinux support.]) -+ fi -+]) --- -1.7.5.4 - diff --git a/recipes-extended/findutils/findutils-4.4.2/findutils-selinux.patch b/recipes-extended/findutils/findutils-4.4.2/findutils-selinux.patch deleted file mode 100644 index db0ab89..0000000 --- a/recipes-extended/findutils/findutils-4.4.2/findutils-selinux.patch +++ /dev/null @@ -1,524 +0,0 @@ -From: Xin Ouyang -Date: Tue, 26 Jun 2012 13:48:44 +0800 -Subject: [PATCH 1/2] findutils: support selinux - -Upstream-Status: Backport - -This is modified from a F13'sx SRPM patch. - -================================================================================ - - Author: James Youngman - Date: Sat Jul 11 19:55:27 2009 +0100 - - Fix Savannah bug #27017: find -D opt / -fstype ext3 -print , -quit coredump. - - Fix Savannah bug #27017: find -D opt / -fstype ext3 -print , -quit - coredumps. - * find/tree.c (set_new_parent): Initialise struct - predicate->arg_text to NULL (instead of leaving it uninitialised). - (get_new_pred_noarg): Likewise. - (get_new_pred): Initialise predicate->arg_text to - "ThisShouldBeSetToSomethingElse" to make it easier to notice - bugs. - (get_new_pred_chk_op): Use get_new_pred_noarg. - (print_predicate): Use an if statement instead of - two ternary operators. - * find/util.c (insert_primary_withpred): Accept new argument, arg, - being the argument (if any) of this predicate. Pass it to - get_new_pred_chk_op. - (insert_primary): Likewise (pass arg to insert_primary_withpred). - (insert_primary_noarg): New function; calls insert_primary with - arg=NULL. - * find/parser.c (collect_arg_stat_info): Add an output parameter; - the filename from which we collected the stat information. - (parse_closeparen, parse_delete, parse_and, parse_or, - parse_comma): Use get_new_pred_noarg. - (parse_cnewer, parse_newer, parse_anewer): Use new - collect_arg_stat_info and insert_primary interface. - (parse_print, parse_prune, parse_nouser, parse_empty): Use - insert_primary_noarg. - (parse_accesscheck, parse_false): Use insert_primary_noarg. - (parse_used, parse_iname, parse_fprint, insert_fprint, - parse_fstype, parse_ilname): Use new collect_arg and - insert_primary interfaces. - (parse_ipath, parse_lname, do_parse_xmin, parse_name, parse_path, - parse_perm, parse_size, parse_user, parse_time): Use new - collect_arg and insert_primary_withpred interface. - (parse_negate, parse_openparen): Use new get_new_pred_chk_op interface. - (parse_newerXY, parse_nogroup): Use new insert_primary interface. - (insert_regex, parse_samefile): Use new insert_primary_withpred - interface. - (insert_type, insert_fprintf, new_insert_exec_ok, insert_num): Use - new insert_primary_withpred interface. - * find/defs.h (struct predicate.arg_text): make const. - Add declarations for new function get_new_pred_noarg and - insert_primary_noarg. Add 'arg' parameter to get_new_pred_chk_op - and insert_primary_withpred. ---- - NEWS | 6 +++ - doc/find.texi | 18 +++++++- - find/Makefile.am | 2 +- - find/defs.h | 6 +++ - find/find.1 | 4 ++ - find/parser.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++- - find/pred.c | 47 ++++++++++++++++++++ - find/tree.c | 2 + - 8 files changed, 209 insertions(+), 4 deletions(-) - -diff --git a/NEWS b/NEWS -index 342a3d3..df0681c 100644 ---- a/NEWS -+++ b/NEWS -@@ -1,5 +1,11 @@ - GNU findutils NEWS - User visible changes. -*- outline -*- (allout) - -+* Major changes in release 4.4.2, 2009-11-26 -+ -+** Functional Enhancements to find -+ -+patch #4848: Patch - Support for SELinux -+ - * Major changes in release 4.4.2, 2009-05-16 - - ** Bug Fixes -diff --git a/doc/find.texi b/doc/find.texi -index 391ffa0..f599bbc 100644 ---- a/doc/find.texi -+++ b/doc/find.texi -@@ -7,7 +7,6 @@ - @c %**end of header - - @include version.texi --@include ../locate/dblocation.texi - - @iftex - @finalout -@@ -1242,6 +1241,14 @@ situation. - - @end deffn - -+@deffn Test -context pattern -+True if file's SELinux context matches the pattern @var{pattern}. -+The pattern uses shell glob matching. -+ -+This predicate is supported only on @code{find} versions compiled with -+SELinux support and only when SELinux is enabled. -+@end deffn -+ - @node Contents - @section Contents - -@@ -1733,6 +1740,7 @@ from the novel you are reading. - * Size Directives:: - * Location Directives:: - * Time Directives:: -+* Other Directives:: - * Formatting Flags:: - @end menu - -@@ -1890,6 +1898,14 @@ File's last modification time in the format specified by @var{k} - (@pxref{Time Formats}). - @end table - -+@node Other Directives -+@subsubsection Other Directives -+ -+@table @code -+@item %Z -+File's SELinux context, or empty string if the file has no SELinux context. -+@end table -+ - @node Time Formats - @subsection Time Formats - -diff --git a/find/Makefile.am b/find/Makefile.am -index b001509..6fc7df3 100644 ---- a/find/Makefile.am -+++ b/find/Makefile.am -@@ -26,7 +26,7 @@ endif - - EXTRA_DIST = defs.h $(man_MANS) - INCLUDES = -I../gnulib/lib -I$(top_srcdir)/lib -I$(top_srcdir)/gnulib/lib -I../intl -DLOCALEDIR=\"$(localedir)\" --LDADD = ./libfindtools.a ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@ @LIB_CLOCK_GETTIME@ @FINDLIBS@ -+LDADD = ./libfindtools.a ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@ @LIB_CLOCK_GETTIME@ @FINDLIBS@ @LIB_SELINUX@ - man_MANS = find.1 - SUBDIRS = . testsuite - -diff --git a/find/defs.h b/find/defs.h -index 4539fd9..e7e3a69 100644 ---- a/find/defs.h -+++ b/find/defs.h -@@ -48,6 +48,7 @@ Please stop compiling the program now - #include /* for bool/boolean */ - #include /* for uintmax_t */ - #include /* S_ISUID etc. */ -+#include - - - -@@ -315,6 +316,7 @@ struct predicate - struct samefile_file_id samefileid; /* samefile */ - mode_t type; /* type */ - struct format_val printf_vec; /* printf fprintf fprint ls fls print0 fprint0 print */ -+ security_context_t scontext; /* security context */ - } args; - - /* The next predicate in the user input sequence, -@@ -459,6 +461,7 @@ PREDICATEFUNCTION pred_used; - PREDICATEFUNCTION pred_user; - PREDICATEFUNCTION pred_writable; - PREDICATEFUNCTION pred_xtype; -+PREDICATEFUNCTION pred_context; - - - -@@ -604,6 +607,9 @@ struct options - */ - int regex_options; - -+ /* function used to get file context */ -+ int (*x_getfilecon) (int, const char *, security_context_t *); -+ - /* Optimisation level. One is the default. - */ - unsigned short optimisation_level; -diff --git a/find/find.1 b/find/find.1 -index 8b67ae3..1d23b17 100644 ---- a/find/find.1 -+++ b/find/find.1 -@@ -933,6 +933,8 @@ if \fIc\fR is `l'. In other words, for symbolic links, - checks the type of the file that - .B \-type - does not check. -+.IP "\-context \fIpattern\fR" -+(SELinux only) Security context of the file matches glob \fIpattern\fR. - - .SS ACTIONS - .IP "\-delete\fR" -@@ -1354,6 +1356,8 @@ File's type (like in - U=unknown type (shouldn't happen) - .IP %Y - File's type (like %y), plus follow symlinks: L=loop, N=nonexistent -+.IP %Z -+(SELinux only) file's security context. - .PP - A `%' character followed by any other character is discarded, but the - other character is printed (don't rely on this, as further format -diff --git a/find/parser.c b/find/parser.c -index 08758ee..d7fc9ce 100644 ---- a/find/parser.c -+++ b/find/parser.c -@@ -53,6 +53,8 @@ - #include - #include - -+#include "selinux-at.h" -+ - #if ENABLE_NLS - # include - # define _(Text) gettext (Text) -@@ -155,6 +157,7 @@ static boolean parse_noignore_race PARAMS((const struct parser_table*, char *arg - static boolean parse_warn PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); - static boolean parse_xtype PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); - static boolean parse_quit PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); -+static boolean parse_context PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); - - boolean parse_print PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); - -@@ -251,6 +254,7 @@ static struct parser_table const parse_table[] = - PARSE_TEST ("cmin", cmin), /* GNU */ - PARSE_TEST ("cnewer", cnewer), /* GNU */ - {ARG_TEST, "ctime", parse_time, pred_ctime}, /* POSIX */ -+ PARSE_TEST ("context", context), /* GNU */ - PARSE_POSOPT ("daystart", daystart), /* GNU */ - PARSE_ACTION ("delete", delete), /* GNU, Mac OS, FreeBSD */ - PARSE_OPTION ("d", d), /* Mac OS X, FreeBSD, NetBSD, OpenBSD, but deprecated in favour of -depth */ -@@ -347,6 +351,86 @@ static struct parser_table const parse_table[] = - static const char *first_nonoption_arg = NULL; - static const struct parser_table *noop = NULL; - -+static int -+fallback_getfilecon (int fd, const char *name, security_context_t *p, -+ int prev_rv) -+{ -+ /* Our original getfilecon () call failed. Perhaps we can't follow a -+ * symbolic link. If that might be the problem, lgetfilecon () the link. -+ * Otherwise, admit defeat. */ -+ switch (errno) -+ { -+ case ENOENT: -+ case ENOTDIR: -+#ifdef DEBUG_STAT -+ fprintf (stderr, "fallback_getfilecon(): getfilecon(%s) failed; falling " -+ "back on lgetfilecon()\n", name); -+#endif -+ return lgetfileconat (fd, name, p); -+ -+ case EACCES: -+ case EIO: -+ case ELOOP: -+ case ENAMETOOLONG: -+#ifdef EOVERFLOW -+ case EOVERFLOW: /* EOVERFLOW is not #defined on UNICOS. */ -+#endif -+ default: -+ return prev_rv; -+ } -+} -+ -+/* optionh_getfilecon () implements the getfilecon operation when the -+ * -H option is in effect. -+ * -+ * If the item to be examined is a command-line argument, we follow -+ * symbolic links. If the getfilecon () call fails on the command-line -+ * item, we fall back on the properties of the symbolic link. -+ * -+ * If the item to be examined is not a command-line argument, we -+ * examine the link itself. */ -+int -+optionh_getfilecon (int fd, const char *name, security_context_t *p) -+{ -+ int rv; -+ if (0 == state.curdepth) -+ { -+ /* This file is from the command line; dereference the link (if it is -+ a link). */ -+ rv = getfileconat (fd, name, p); -+ if (0 == rv) -+ return 0; /* success */ -+ else -+ return fallback_getfilecon (fd, name, p, rv); -+ } -+ else -+ { -+ /* Not a file on the command line; do not dereference the link. */ -+ return lgetfileconat (fd, name, p); -+ } -+} -+ -+/* optionl_getfilecon () implements the getfilecon operation when the -+ * -L option is in effect. That option makes us examine the thing the -+ * symbolic link points to, not the symbolic link itself. */ -+int -+optionl_getfilecon (int fd, const char *name, security_context_t *p) -+{ -+ int rv = getfileconat (fd, name, p); -+ if (0 == rv) -+ return 0; /* normal case. */ -+ else -+ return fallback_getfilecon (fd, name, p, rv); -+} -+ -+/* optionp_getfilecon () implements the stat operation when the -P -+ * option is in effect (this is also the default). That option makes -+ * us examine the symbolic link itself, not the thing it points to. */ -+int -+optionp_getfilecon (int fd, const char *name, security_context_t *p) -+{ -+ return lgetfileconat (fd, name, p); -+} - - void - check_option_combinations(const struct predicate *p) -@@ -450,11 +534,13 @@ set_follow_state(enum SymlinkOption opt) - { - case SYMLINK_ALWAYS_DEREF: /* -L */ - options.xstat = optionl_stat; -+ options.x_getfilecon = optionl_getfilecon; - options.no_leaf_check = true; - break; - - case SYMLINK_NEVER_DEREF: /* -P (default) */ - options.xstat = optionp_stat; -+ options.x_getfilecon = optionp_getfilecon; - /* Can't turn no_leaf_check off because the user might have specified - * -noleaf anyway - */ -@@ -462,6 +548,7 @@ set_follow_state(enum SymlinkOption opt) - - case SYMLINK_DEREF_ARGSONLY: /* -H */ - options.xstat = optionh_stat; -+ options.x_getfilecon = optionh_getfilecon; - options.no_leaf_check = true; - } - } -@@ -1146,8 +1233,10 @@ tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N\n\ - -nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN\n\ - -readable -writable -executable\n\ - -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\ -- -used N -user NAME -xtype [bcdpfls]\n")); -+ -used N -user NAME -xtype [bcdpfls]")); - puts (_("\ -+ -context CONTEXT\n")); -+ puts (_("\n\ - actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print \n\ - -fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit\n\ - -exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;\n\ -@@ -2574,6 +2663,11 @@ parse_version (const struct parser_table* entry, char **argv, int *arg_ptr) - printf("LEAF_OPTIMISATION "); - ++features; - #endif -+ if (0 < is_selinux_enabled ()) -+ { -+ printf ("SELINUX "); -+ ++features; -+ } - - flags = 0; - if (is_fts_enabled(&flags)) -@@ -2609,6 +2703,31 @@ parse_version (const struct parser_table* entry, char **argv, int *arg_ptr) - } - - static boolean -+parse_context (const struct parser_table* entry, char **argv, int *arg_ptr) -+{ -+ struct predicate *our_pred; -+ -+ if ((argv == NULL) || (argv[*arg_ptr] == NULL)) -+ return false; -+ -+ if (is_selinux_enabled () <= 0) -+ { -+ error (1, 0, _("invalid predicate -context: SELinux is not enabled.")); -+ return false; -+ } -+ our_pred = insert_primary (entry, NULL); -+ our_pred->est_success_rate = 0.01f; -+ our_pred->need_stat = false; -+#ifdef DEBUG -+ our_pred->p_name = find_pred_name (pred_context); -+#endif /*DEBUG*/ -+ our_pred->args.scontext = argv[*arg_ptr]; -+ -+ (*arg_ptr)++; -+ return true; -+} -+ -+static boolean - parse_xdev (const struct parser_table* entry, char **argv, int *arg_ptr) - { - options.stay_on_filesystem = true; -@@ -2861,7 +2980,7 @@ insert_fprintf (struct format_val *vec, - if (*scan2 == '.') - for (scan2++; ISDIGIT (*scan2); scan2++) - /* Do nothing. */ ; -- if (strchr ("abcdDfFgGhHiklmMnpPsStuUyY", *scan2)) -+ if (strchr ("abcdDfFgGhHiklmMnpPsStuUyYZ", *scan2)) - { - segmentp = make_segment (segmentp, format, scan2 - format, - KIND_FORMAT, *scan2, 0, -@@ -2991,6 +3110,11 @@ make_segment (struct segment **segment, - *fmt++ = 's'; - break; - -+ case 'Z': /* SELinux security context */ -+ mycost = NeedsAccessInfo; -+ *fmt++ = 's'; -+ break; -+ - case 'H': /* ARGV element file was found under */ - *fmt++ = 's'; - break; -diff --git a/find/pred.c b/find/pred.c -index b1f48a0..7c34119 100644 ---- a/find/pred.c -+++ b/find/pred.c -@@ -48,6 +48,8 @@ - #include "error.h" - #include "verify.h" - -+#include -+ - #if ENABLE_NLS - # include - # define _(Text) gettext (Text) -@@ -230,6 +232,7 @@ struct pred_assoc pred_table[] = - {pred_user, "user "}, - {pred_writable, "writable "}, - {pred_xtype, "xtype "}, -+ {pred_context, "context"}, - {0, "none "} - }; - #endif -@@ -1054,6 +1057,30 @@ do_fprintf(struct format_val *dest, - mode_to_filetype(stat_buf->st_mode & S_IFMT)); - } - break; -+ -+ case 'Z': /* SELinux security context */ -+ { -+ security_context_t scontext; -+ int rv = (*options.x_getfilecon) (state.cwd_dir_fd, state.rel_pathname, -+ &scontext); -+ if (rv < 0) -+ { -+ /* If getfilecon fails, there will in the general case -+ still be some text to print. We just make %Z expand -+ to an empty string. */ -+ checked_fprintf (dest, segment->text, ""); -+ -+ error (0, errno, "getfilecon: %s", -+ safely_quote_err_filename (0, pathname)); -+ state.exit_status = 1; -+ } -+ else -+ { -+ checked_fprintf (dest, segment->text, scontext); -+ freecon (scontext); -+ } -+ } -+ break; - } - /* end of KIND_FORMAT case */ - break; -@@ -1844,6 +1871,26 @@ pred_xtype (const char *pathname, struct stat *stat_buf, struct predicate *pred_ - */ - return (pred_type (pathname, &sbuf, pred_ptr)); - } -+ -+ -+boolean -+pred_context (const char *pathname, struct stat *stat_buf, -+ struct predicate *pred_ptr) -+{ -+ security_context_t scontext; -+ int rv = (*options.x_getfilecon) (state.cwd_dir_fd, state.rel_pathname, -+ &scontext); -+ if (rv < 0) -+ { -+ error (0, errno, "getfilecon: %s", safely_quote_err_filename (0, pathname)); -+ return false; -+ } -+ -+ rv = (fnmatch (pred_ptr->args.scontext, scontext, 0) == 0); -+ freecon (scontext); -+ return rv; -+} -+ - - /* 1) fork to get a child; parent remembers the child pid - 2) child execs the command requested -diff --git a/find/tree.c b/find/tree.c -index 60a0601..63100fb 100644 ---- a/find/tree.c -+++ b/find/tree.c -@@ -909,6 +909,7 @@ static struct pred_cost_lookup costlookup[] = - { pred_cmin , NeedsStatInfo, }, - { pred_cnewer , NeedsStatInfo, }, - { pred_comma , NeedsNothing, }, -+ { pred_context , NeedsAccessInfo }, - { pred_ctime , NeedsStatInfo, }, - { pred_delete , NeedsSyncDiskHit }, - { pred_empty , NeedsStatInfo }, -@@ -1453,6 +1454,7 @@ get_new_pred (const struct parser_table *entry) - last_pred->p_cost = NeedsUnknown; - last_pred->arg_text = "ThisShouldBeSetToSomethingElse"; - last_pred->args.str = NULL; -+ last_pred->args.scontext = NULL; - last_pred->pred_next = NULL; - last_pred->pred_left = NULL; - last_pred->pred_right = NULL; --- -1.7.5.4 - diff --git a/recipes-extended/findutils/findutils-4.4.2/findutils-with-selinux-gnulib.patch b/recipes-extended/findutils/findutils-4.4.2/findutils-with-selinux-gnulib.patch new file mode 100644 index 0000000..866ecdc --- /dev/null +++ b/recipes-extended/findutils/findutils-4.4.2/findutils-with-selinux-gnulib.patch @@ -0,0 +1,1294 @@ +Subject: [PATCH] findutils: support selinux and gnulib + +Upstream-Status: Inappropriate [configuration] + +This is modified from a F13 SRPM patch. + +Once the selinux-at module appears on the list within import-gnulib.config, +this patch is no longer needed. + +Signed-off-by: Xin Ouyang +--- + aclocal.m4 | 2 + + gnulib/lib/Makefile.am | 44 +++++++ + gnulib/lib/at-func.c | 98 ++++++++++---- + gnulib/lib/getfilecon.c | 87 ++++++++++++ + gnulib/lib/openat.c | 285 ++++++++++++++++++++-------------------- + gnulib/lib/openat.h | 88 ++++++------- + gnulib/lib/se-context.in.h | 34 +++++ + gnulib/lib/se-selinux.in.h | 103 +++++++++++++++ + gnulib/lib/selinux-at.c | 72 ++++++++++ + gnulib/lib/selinux-at.h | 52 ++++++++ + gnulib/m4/gnulib-comp.m4 | 12 ++ + gnulib/m4/include_next.m4 | 29 +++- + gnulib/m4/selinux-context-h.m4 | 16 +++ + gnulib/m4/selinux-selinux-h.m4 | 57 ++++++++ + 14 files changed, 753 insertions(+), 226 deletions(-) + create mode 100644 gnulib/lib/getfilecon.c + create mode 100644 gnulib/lib/se-context.in.h + create mode 100644 gnulib/lib/se-selinux.in.h + create mode 100644 gnulib/lib/selinux-at.c + create mode 100644 gnulib/lib/selinux-at.h + create mode 100644 gnulib/m4/selinux-context-h.m4 + create mode 100644 gnulib/m4/selinux-selinux-h.m4 + +diff --git a/aclocal.m4 b/aclocal.m4 +index 1f97dda..61ad660 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -1039,6 +1039,8 @@ m4_include([gnulib/m4/rpmatch.m4]) + m4_include([gnulib/m4/same.m4]) + m4_include([gnulib/m4/save-cwd.m4]) + m4_include([gnulib/m4/savedir.m4]) ++m4_include([gnulib/m4/selinux-context-h.m4]) ++m4_include([gnulib/m4/selinux-selinux-h.m4]) + m4_include([gnulib/m4/setenv.m4]) + m4_include([gnulib/m4/ssize_t.m4]) + m4_include([gnulib/m4/st_dm_mode.m4]) +diff --git a/gnulib/lib/Makefile.am b/gnulib/lib/Makefile.am +index 59ed5f2..7f105a9 100644 +--- a/gnulib/lib/Makefile.am ++++ b/gnulib/lib/Makefile.am +@@ -1007,6 +1007,50 @@ EXTRA_libgnulib_a_SOURCES += savedir.c + + ## end gnulib module savedir + ++## begin gnulib module selinux-at ++ ++ ++EXTRA_DIST += selinux-at.c selinux-at.h ++ ++EXTRA_libgnulib_a_SOURCES += selinux-at.c ++ ++## end gnulib module selinux-at ++ ++## begin gnulib module selinux-h ++ ++libgnulib_a_SOURCES += se-context.in.h se-selinux.in.h ++ ++BUILT_SOURCES += selinux/selinux.h ++selinux/selinux.h: se-selinux.in.h ++ $(AM_V_at)$(MKDIR_P) selinux ++ $(AM_V_GEN)rm -f $@-t $@ && \ ++ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ ++ sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ ++ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ ++ -e 's|@''NEXT_SELINUX_SELINUX_H''@|$(NEXT_SELINUX_SELINUX_H)|g' \ ++ < $(srcdir)/se-selinux.in.h; \ ++ } > $@-t && \ ++ chmod a-x $@-t && \ ++ mv $@-t $@ ++MOSTLYCLEANFILES += selinux/selinux.h selinux/selinux.h-t ++ ++BUILT_SOURCES += $(SELINUX_CONTEXT_H) ++selinux/context.h: se-context.in.h ++ $(AM_V_at)$(MKDIR_P) selinux ++ $(AM_V_GEN)rm -f $@-t $@ && \ ++ cp $(srcdir)/se-context.in.h $@-t && \ ++ chmod a-x $@-t && \ ++ mv $@-t $@ ++MOSTLYCLEANFILES += selinux/context.h selinux/context.h-t ++MOSTLYCLEANDIRS += selinux ++ ++EXTRA_DIST += getfilecon.c ++ ++EXTRA_libgnulib_a_SOURCES += getfilecon.c ++ ++## end gnulib module selinux-h ++ + ## begin gnulib module setenv + + +diff --git a/gnulib/lib/at-func.c b/gnulib/lib/at-func.c +index c7963fe..73be401 100644 +--- a/gnulib/lib/at-func.c ++++ b/gnulib/lib/at-func.c +@@ -1,5 +1,5 @@ + /* Define an at-style functions like fstatat, unlinkat, fchownat, etc. +- Copyright (C) 2006 Free Software Foundation, Inc. ++ Copyright (C) 2006, 2009 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -16,62 +16,106 @@ + + /* written by Jim Meyering */ + +-#define CALL_FUNC(F) \ +- (AT_FUNC_USE_F1_COND \ ++#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ ++#include "openat.h" ++#include "openat-priv.h" ++#include "save-cwd.h" ++ ++#ifdef AT_FUNC_USE_F1_COND ++# define CALL_FUNC(F) \ ++ (flag == AT_FUNC_USE_F1_COND \ + ? AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS) \ + : AT_FUNC_F2 (F AT_FUNC_POST_FILE_ARGS)) ++# define VALIDATE_FLAG(F) \ ++ if (flag & ~AT_FUNC_USE_F1_COND) \ ++ { \ ++ errno = EINVAL; \ ++ return FUNC_FAIL; \ ++ } ++#else ++# define CALL_FUNC(F) (AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS)) ++# define VALIDATE_FLAG(F) /* empty */ ++#endif ++ ++#ifdef AT_FUNC_RESULT ++# define FUNC_RESULT AT_FUNC_RESULT ++#else ++# define FUNC_RESULT int ++#endif ++ ++#ifdef AT_FUNC_FAIL ++# define FUNC_FAIL AT_FUNC_FAIL ++#else ++# define FUNC_FAIL -1 ++#endif + +-/* Call AT_FUNC_F1 or AT_FUNC_F2 (testing AT_FUNC_USE_F1_COND to +- determine which) to operate on FILE, which is in the directory +- open on descriptor FD. If possible, do it without changing the ++/* Call AT_FUNC_F1 to operate on FILE, which is in the directory ++ open on descriptor FD. If AT_FUNC_USE_F1_COND is defined to a value, ++ AT_FUNC_POST_FILE_PARAM_DECLS must inlude a parameter named flag; ++ call AT_FUNC_F2 if FLAG is 0 or fail if FLAG contains more bits than ++ AT_FUNC_USE_F1_COND. Return int and fail with -1 unless AT_FUNC_RESULT ++ or AT_FUNC_FAIL are defined. If possible, do it without changing the + working directory. Otherwise, resort to using save_cwd/fchdir, + then AT_FUNC_F?/restore_cwd. If either the save_cwd or the restore_cwd + fails, then give a diagnostic and exit nonzero. */ +-int ++FUNC_RESULT + AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS) + { ++ /* Be careful to choose names unlikely to conflict with ++ AT_FUNC_POST_FILE_PARAM_DECLS. */ + struct saved_cwd saved_cwd; + int saved_errno; +- int err; ++ FUNC_RESULT err; ++ ++ VALIDATE_FLAG (flag); + + if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) + return CALL_FUNC (file); + + { +- char buf[OPENAT_BUFFER_SIZE]; +- char *proc_file = openat_proc_name (buf, fd, file); ++ char proc_buf[OPENAT_BUFFER_SIZE]; ++ char *proc_file = openat_proc_name (proc_buf, fd, file); + if (proc_file) + { +- int proc_result = CALL_FUNC (proc_file); +- int proc_errno = errno; +- if (proc_file != buf) +- free (proc_file); +- /* If the syscall succeeds, or if it fails with an unexpected +- errno value, then return right away. Otherwise, fall through +- and resort to using save_cwd/restore_cwd. */ +- if (0 <= proc_result) +- return proc_result; +- if (! EXPECTED_ERRNO (proc_errno)) +- { +- errno = proc_errno; +- return proc_result; +- } ++ FUNC_RESULT proc_result = CALL_FUNC (proc_file); ++ int proc_errno = errno; ++ if (proc_file != proc_buf) ++ free (proc_file); ++ /* If the syscall succeeds, or if it fails with an unexpected ++ errno value, then return right away. Otherwise, fall through ++ and resort to using save_cwd/restore_cwd. */ ++ if (FUNC_FAIL != proc_result) ++ return proc_result; ++ if (! EXPECTED_ERRNO (proc_errno)) ++ { ++ errno = proc_errno; ++ return proc_result; ++ } + } + } + + if (save_cwd (&saved_cwd) != 0) + openat_save_fail (errno); ++ if (0 <= fd && fd == saved_cwd.desc) ++ { ++ /* If saving the working directory collides with the user's ++ requested fd, then the user's fd must have been closed to ++ begin with. */ ++ free_cwd (&saved_cwd); ++ errno = EBADF; ++ return FUNC_FAIL; ++ } + + if (fchdir (fd) != 0) + { + saved_errno = errno; + free_cwd (&saved_cwd); + errno = saved_errno; +- return -1; ++ return FUNC_FAIL; + } + + err = CALL_FUNC (file); +- saved_errno = (err < 0 ? errno : 0); ++ saved_errno = (err == FUNC_FAIL ? errno : 0); + + if (restore_cwd (&saved_cwd) != 0) + openat_restore_fail (errno); +@@ -83,3 +127,5 @@ AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS) + return err; + } + #undef CALL_FUNC ++#undef FUNC_RESULT ++#undef FUNC_FAIL +diff --git a/gnulib/lib/getfilecon.c b/gnulib/lib/getfilecon.c +new file mode 100644 +index 0000000..d712307 +--- /dev/null ++++ b/gnulib/lib/getfilecon.c +@@ -0,0 +1,87 @@ ++/* wrap getfilecon, lgetfilecon, and fgetfilecon ++ Copyright (C) 2009 Free Software Foundation, Inc. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3, or (at your option) ++ any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software Foundation, ++ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ++ ++/* written by Jim Meyering */ ++ ++#include ++ ++#include ++ ++#include ++#include ++#include ++ ++/* FIXME: remove this once there is an errno-gnu module ++ that guarantees the definition of ENODATA. */ ++#ifndef ENODATA ++# define ENODATA ENOTSUP ++#endif ++ ++#undef getfilecon ++#undef lgetfilecon ++#undef fgetfilecon ++int getfilecon (char const *file, security_context_t *con); ++int lgetfilecon (char const *file, security_context_t *con); ++int fgetfilecon (int fd, security_context_t *con); ++ ++/* getfilecon, lgetfilecon, and fgetfilecon can all misbehave, be it ++ via an old version of libselinux where these would return 0 and set the ++ result context to NULL, or via a modern kernel+lib operating on a file ++ from a disk whose attributes were set by a kernel from around 2006. ++ In that latter case, the functions return a length of 10 for the ++ "unlabeled" context. Map both failures to a return value of -1, and ++ set errno to ENOTSUP in the first case, and ENODATA in the latter. */ ++ ++static inline int ++map_to_failure (int ret, security_context_t *con) ++{ ++ if (ret == 0) ++ { ++ errno = ENOTSUP; ++ return -1; ++ } ++ ++ if (ret == 10 && strcmp (*con, "unlabeled") == 0) ++ { ++ freecon (*con); ++ errno = ENODATA; ++ return -1; ++ } ++ ++ return ret; ++} ++ ++int ++rpl_getfilecon (char const *file, security_context_t *con) ++{ ++ int ret = getfilecon (file, con); ++ return map_to_failure (ret, con); ++} ++ ++int ++rpl_lgetfilecon (char const *file, security_context_t *con) ++{ ++ int ret = lgetfilecon (file, con); ++ return map_to_failure (ret, con); ++} ++ ++int ++rpl_fgetfilecon (int fd, security_context_t *con) ++{ ++ int ret = fgetfilecon (fd, con); ++ return map_to_failure (ret, con); ++} +diff --git a/gnulib/lib/openat.c b/gnulib/lib/openat.c +index 73f24b0..2b15bb5 100644 +--- a/gnulib/lib/openat.c ++++ b/gnulib/lib/openat.c +@@ -1,5 +1,5 @@ + /* provide a replacement openat function +- Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. ++ Copyright (C) 2004-2009 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -22,13 +22,108 @@ + + #include + #include ++#include ++#include + + #include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ +-#include "fcntl--.h" +-#include "lstat.h" + #include "openat-priv.h" + #include "save-cwd.h" + ++#if HAVE_OPENAT ++ ++# undef openat ++ ++/* Like openat, but work around Solaris 9 bugs with trailing slash. */ ++int ++rpl_openat (int dfd, char const *filename, int flags, ...) ++{ ++ mode_t mode; ++ int fd; ++ ++ mode = 0; ++ if (flags & O_CREAT) ++ { ++ va_list arg; ++ va_start (arg, flags); ++ ++ /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 ++ creates crashing code when 'mode_t' is smaller than 'int'. */ ++ mode = va_arg (arg, PROMOTED_MODE_T); ++ ++ va_end (arg); ++ } ++ ++#if OPEN_TRAILING_SLASH_BUG ++ /* If the filename ends in a slash and one of O_CREAT, O_WRONLY, O_RDWR ++ is specified, then fail. ++ Rationale: POSIX ++ says that ++ "A pathname that contains at least one non-slash character and that ++ ends with one or more trailing slashes shall be resolved as if a ++ single dot character ( '.' ) were appended to the pathname." ++ and ++ "The special filename dot shall refer to the directory specified by ++ its predecessor." ++ If the named file already exists as a directory, then ++ - if O_CREAT is specified, open() must fail because of the semantics ++ of O_CREAT, ++ - if O_WRONLY or O_RDWR is specified, open() must fail because POSIX ++ says that it ++ fails with errno = EISDIR in this case. ++ If the named file does not exist or does not name a directory, then ++ - if O_CREAT is specified, open() must fail since open() cannot create ++ directories, ++ - if O_WRONLY or O_RDWR is specified, open() must fail because the ++ file does not contain a '.' directory. */ ++ if (flags & (O_CREAT | O_WRONLY | O_RDWR)) ++ { ++ size_t len = strlen (filename); ++ if (len > 0 && filename[len - 1] == '/') ++ { ++ errno = EISDIR; ++ return -1; ++ } ++ } ++#endif ++ ++ fd = openat (dfd, filename, flags, mode); ++ ++#if OPEN_TRAILING_SLASH_BUG ++ /* If the filename ends in a slash and fd does not refer to a directory, ++ then fail. ++ Rationale: POSIX ++ says that ++ "A pathname that contains at least one non-slash character and that ++ ends with one or more trailing slashes shall be resolved as if a ++ single dot character ( '.' ) were appended to the pathname." ++ and ++ "The special filename dot shall refer to the directory specified by ++ its predecessor." ++ If the named file without the slash is not a directory, open() must fail ++ with ENOTDIR. */ ++ if (fd >= 0) ++ { ++ /* We know len is positive, since open did not fail with ENOENT. */ ++ size_t len = strlen (filename); ++ if (filename[len - 1] == '/') ++ { ++ struct stat statbuf; ++ ++ if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode)) ++ { ++ close (fd); ++ errno = ENOTDIR; ++ return -1; ++ } ++ } ++ } ++#endif ++ ++ return fd; ++} ++ ++#else /* !HAVE_OPENAT */ ++ + /* Replacement for Solaris' openat function. + + First, try to simulate it via open ("/proc/self/fd/FD/FILE"). +@@ -47,12 +142,9 @@ openat (int fd, char const *file, int flags, ...) + va_list arg; + va_start (arg, flags); + +- /* If mode_t is narrower than int, use the promoted type (int), +- not mode_t. Use sizeof to guess whether mode_t is narrower; +- we don't know of any practical counterexamples. */ +- mode = (sizeof (mode_t) < sizeof (int) +- ? va_arg (arg, int) +- : va_arg (arg, mode_t)); ++ /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 ++ creates crashing code when 'mode_t' is smaller than 'int'. */ ++ mode = va_arg (arg, PROMOTED_MODE_T); + + va_end (arg); + } +@@ -73,7 +165,7 @@ openat (int fd, char const *file, int flags, ...) + + int + openat_permissive (int fd, char const *file, int flags, mode_t mode, +- int *cwd_errno) ++ int *cwd_errno) + { + struct saved_cwd saved_cwd; + int saved_errno; +@@ -88,18 +180,18 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode, + char *proc_file = openat_proc_name (buf, fd, file); + if (proc_file) + { +- int open_result = open (proc_file, flags, mode); +- int open_errno = errno; +- if (proc_file != buf) +- free (proc_file); +- /* If the syscall succeeds, or if it fails with an unexpected +- errno value, then return right away. Otherwise, fall through +- and resort to using save_cwd/restore_cwd. */ +- if (0 <= open_result || ! EXPECTED_ERRNO (open_errno)) +- { +- errno = open_errno; +- return open_result; +- } ++ int open_result = open (proc_file, flags, mode); ++ int open_errno = errno; ++ if (proc_file != buf) ++ free (proc_file); ++ /* If the syscall succeeds, or if it fails with an unexpected ++ errno value, then return right away. Otherwise, fall through ++ and resort to using save_cwd/restore_cwd. */ ++ if (0 <= open_result || ! EXPECTED_ERRNO (open_errno)) ++ { ++ errno = open_errno; ++ return open_result; ++ } + } + } + +@@ -107,9 +199,18 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode, + if (! save_ok) + { + if (! cwd_errno) +- openat_save_fail (errno); ++ openat_save_fail (errno); + *cwd_errno = errno; + } ++ if (0 <= fd && fd == saved_cwd.desc) ++ { ++ /* If saving the working directory collides with the user's ++ requested fd, then the user's fd must have been closed to ++ begin with. */ ++ free_cwd (&saved_cwd); ++ errno = EBADF; ++ return -1; ++ } + + err = fchdir (fd); + saved_errno = errno; +@@ -119,11 +220,17 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode, + err = open (file, flags, mode); + saved_errno = errno; + if (save_ok && restore_cwd (&saved_cwd) != 0) +- { +- if (! cwd_errno) +- openat_restore_fail (errno); +- *cwd_errno = errno; +- } ++ { ++ if (! cwd_errno) ++ { ++ /* Don't write a message to just-created fd 2. */ ++ saved_errno = errno; ++ if (err == STDERR_FILENO) ++ close (err); ++ openat_restore_fail (saved_errno); ++ } ++ *cwd_errno = errno; ++ } + } + + free_cwd (&saved_cwd); +@@ -144,125 +251,15 @@ openat_needs_fchdir (void) + char buf[OPENAT_BUFFER_SIZE]; + char *proc_file = openat_proc_name (buf, fd, "."); + if (proc_file) +- { +- needs_fchdir = false; +- if (proc_file != buf) +- free (proc_file); +- } ++ { ++ needs_fchdir = false; ++ if (proc_file != buf) ++ free (proc_file); ++ } + close (fd); + } + + return needs_fchdir; + } + +-#if !HAVE_FDOPENDIR +- +-/* Replacement for Solaris' function by the same name. +- +- First, try to simulate it via opendir ("/proc/self/fd/FD"). Failing +- that, simulate it by doing save_cwd/fchdir/opendir(".")/restore_cwd. +- If either the save_cwd or the restore_cwd fails (relatively unlikely), +- then give a diagnostic and exit nonzero. +- Otherwise, this function works just like Solaris' fdopendir. +- +- W A R N I N G: +- Unlike the other fd-related functions here, this one +- effectively consumes its FD parameter. The caller should not +- close or otherwise manipulate FD if this function returns successfully. */ +-DIR * +-fdopendir (int fd) +-{ +- struct saved_cwd saved_cwd; +- int saved_errno; +- DIR *dir; +- +- char buf[OPENAT_BUFFER_SIZE]; +- char *proc_file = openat_proc_name (buf, fd, "."); +- if (proc_file) +- { +- dir = opendir (proc_file); +- saved_errno = errno; +- } +- else +- { +- dir = NULL; +- saved_errno = EOPNOTSUPP; +- } +- +- /* If the syscall fails with an expected errno value, resort to +- save_cwd/restore_cwd. */ +- if (! dir && EXPECTED_ERRNO (saved_errno)) +- { +- if (save_cwd (&saved_cwd) != 0) +- openat_save_fail (errno); +- +- if (fchdir (fd) != 0) +- { +- dir = NULL; +- saved_errno = errno; +- } +- else +- { +- dir = opendir ("."); +- saved_errno = errno; +- +- if (restore_cwd (&saved_cwd) != 0) +- openat_restore_fail (errno); +- } +- +- free_cwd (&saved_cwd); +- } +- +- if (dir) +- close (fd); +- if (proc_file != buf) +- free (proc_file); +- errno = saved_errno; +- return dir; +-} +- +-#endif +- +-/* Replacement for Solaris' function by the same name. +- +- First, try to simulate it via l?stat ("/proc/self/fd/FD/FILE"). +- Failing that, simulate it via save_cwd/fchdir/(stat|lstat)/restore_cwd. +- If either the save_cwd or the restore_cwd fails (relatively unlikely), +- then give a diagnostic and exit nonzero. +- Otherwise, this function works just like Solaris' fstatat. */ +- +-#define AT_FUNC_NAME fstatat +-#define AT_FUNC_F1 lstat +-#define AT_FUNC_F2 stat +-#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW +-#define AT_FUNC_POST_FILE_PARAM_DECLS , struct stat *st, int flag +-#define AT_FUNC_POST_FILE_ARGS , st +-#include "at-func.c" +-#undef AT_FUNC_NAME +-#undef AT_FUNC_F1 +-#undef AT_FUNC_F2 +-#undef AT_FUNC_USE_F1_COND +-#undef AT_FUNC_POST_FILE_PARAM_DECLS +-#undef AT_FUNC_POST_FILE_ARGS +- +-/* Replacement for Solaris' function by the same name. +- +- First, try to simulate it via (unlink|rmdir) ("/proc/self/fd/FD/FILE"). +- Failing that, simulate it via save_cwd/fchdir/(unlink|rmdir)/restore_cwd. +- If either the save_cwd or the restore_cwd fails (relatively unlikely), +- then give a diagnostic and exit nonzero. +- Otherwise, this function works just like Solaris' unlinkat. */ +- +-#define AT_FUNC_NAME unlinkat +-#define AT_FUNC_F1 rmdir +-#define AT_FUNC_F2 unlink +-#define AT_FUNC_USE_F1_COND flag == AT_REMOVEDIR +-#define AT_FUNC_POST_FILE_PARAM_DECLS , int flag +-#define AT_FUNC_POST_FILE_ARGS /* empty */ +-#include "at-func.c" +-#undef AT_FUNC_NAME +-#undef AT_FUNC_F1 +-#undef AT_FUNC_F2 +-#undef AT_FUNC_USE_F1_COND +-#undef AT_FUNC_POST_FILE_PARAM_DECLS +-#undef AT_FUNC_POST_FILE_ARGS ++#endif /* !HAVE_OPENAT */ +diff --git a/gnulib/lib/openat.h b/gnulib/lib/openat.h +index b5e4f11..433b998 100644 +--- a/gnulib/lib/openat.h ++++ b/gnulib/lib/openat.h +@@ -1,5 +1,5 @@ + /* provide a replacement openat function +- Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 2004-2006, 2008-2009 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -16,6 +16,9 @@ + + /* written by Jim Meyering */ + ++#ifndef _GL_HEADER_OPENAT ++#define _GL_HEADER_OPENAT ++ + #include + + #include +@@ -25,7 +28,7 @@ + #include + + #ifndef __attribute__ +-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ ++# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) + # define __attribute__(x) /* empty */ + # endif + #endif +@@ -34,46 +37,10 @@ + # define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) + #endif + +-/* Work around a bug in Solaris 9 and 10: AT_FDCWD is positive. Its +- value exceeds INT_MAX, so its use as an int doesn't conform to the +- C standard, and GCC and Sun C complain in some cases. If the bug +- is present, undef AT_FDCWD here, so it can be redefined below. */ +-#if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553 +-# undef AT_FDCWD +-#endif +- +-/* Use the same bit pattern as Solaris 9, but with the proper +- signedness. The bit pattern is important, in case this actually is +- Solaris with the above workaround. */ +-#ifndef AT_FDCWD +-# define AT_FDCWD (-3041965) +-#endif +- +-/* Use the same values as Solaris 9. This shouldn't matter, but +- there's no real reason to differ. */ +-#ifndef AT_SYMLINK_NOFOLLOW +-# define AT_SYMLINK_NOFOLLOW 4096 +-# define AT_REMOVEDIR 1 +-#endif +- +-#ifdef __OPENAT_PREFIX ++#if !HAVE_OPENAT + +-# undef openat +-# define __OPENAT_CONCAT(x, y) x ## y +-# define __OPENAT_XCONCAT(x, y) __OPENAT_CONCAT (x, y) +-# define __OPENAT_ID(y) __OPENAT_XCONCAT (__OPENAT_PREFIX, y) +-# define openat __OPENAT_ID (openat) +-int openat (int fd, char const *file, int flags, /* mode_t mode */ ...); + int openat_permissive (int fd, char const *file, int flags, mode_t mode, + int *cwd_errno); +-# if ! HAVE_FDOPENDIR +-# define fdopendir __OPENAT_ID (fdopendir) +-# endif +-DIR *fdopendir (int fd); +-# define fstatat __OPENAT_ID (fstatat) +-int fstatat (int fd, char const *file, struct stat *st, int flag); +-# define unlinkat __OPENAT_ID (unlinkat) +-int unlinkat (int fd, char const *file, int flag); + bool openat_needs_fchdir (void); + + #else +@@ -84,19 +51,8 @@ bool openat_needs_fchdir (void); + + #endif + +-#if HAVE_OPENAT && ! LSTAT_FOLLOWS_SLASHED_SYMLINK +-int rpl_fstatat (int fd, char const *file, struct stat *st, int flag); +-# if !COMPILING_FSTATAT +-# undef fstatat +-# define fstatat rpl_fstatat +-# endif +-#endif +- +-int mkdirat (int fd, char const *file, mode_t mode); + void openat_restore_fail (int) ATTRIBUTE_NORETURN; + void openat_save_fail (int) ATTRIBUTE_NORETURN; +-int fchmodat (int fd, char const *file, mode_t mode, int flag); +-int fchownat (int fd, char const *file, uid_t owner, gid_t group, int flag); + + /* Using these function names makes application code + slightly more readable than it would be with +@@ -124,3 +80,35 @@ lchmodat (int fd, char const *file, mode_t mode) + { + return fchmodat (fd, file, mode, AT_SYMLINK_NOFOLLOW); + } ++ ++static inline int ++statat (int fd, char const *name, struct stat *st) ++{ ++ return fstatat (fd, name, st, 0); ++} ++ ++static inline int ++lstatat (int fd, char const *name, struct stat *st) ++{ ++ return fstatat (fd, name, st, AT_SYMLINK_NOFOLLOW); ++} ++ ++#if GNULIB_FACCESSAT ++/* For now, there are no wrappers named laccessat or leuidaccessat, ++ since gnulib doesn't support faccessat(,AT_SYMLINK_NOFOLLOW) and ++ since access rights on symlinks are of limited utility. */ ++ ++static inline int ++accessat (int fd, char const *file, int mode) ++{ ++ return faccessat (fd, file, mode, 0); ++} ++ ++static inline int ++euidaccessat (int fd, char const *file, int mode) ++{ ++ return faccessat (fd, file, mode, AT_EACCESS); ++} ++#endif ++ ++#endif /* _GL_HEADER_OPENAT */ +diff --git a/gnulib/lib/se-context.in.h b/gnulib/lib/se-context.in.h +new file mode 100644 +index 0000000..a34a7fb +--- /dev/null ++++ b/gnulib/lib/se-context.in.h +@@ -0,0 +1,34 @@ ++#ifndef SELINUX_CONTEXT_H ++# define SELINUX_CONTEXT_H ++ ++# include ++ ++#ifndef _GL_UNUSED_PARAMETER ++# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) ++# define _GL_UNUSED_PARAMETER __attribute__ ((__unused__)) ++# else ++# define _GL_UNUSED_PARAMETER ++# endif ++#endif ++ ++typedef int context_t; ++static inline context_t context_new (char const *s _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return 0; } ++static inline char *context_str (context_t con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return (void *) 0; } ++static inline void context_free (context_t c _GL_UNUSED_PARAMETER) {} ++ ++static inline int context_user_set (context_t sc _GL_UNUSED_PARAMETER, ++ char const *s _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int context_role_set (context_t sc _GL_UNUSED_PARAMETER, ++ char const *s _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int context_range_set (context_t sc _GL_UNUSED_PARAMETER, ++ char const *s _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int context_type_set (context_t sc _GL_UNUSED_PARAMETER, ++ char const *s _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++ ++#endif +diff --git a/gnulib/lib/se-selinux.in.h b/gnulib/lib/se-selinux.in.h +new file mode 100644 +index 0000000..d683101 +--- /dev/null ++++ b/gnulib/lib/se-selinux.in.h +@@ -0,0 +1,103 @@ ++/* Replacement for platforms that lack it. ++ Copyright (C) 2008-2011 Free Software Foundation, Inc. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++#ifndef _GL_SELINUX_SELINUX_H ++# define _GL_SELINUX_SELINUX_H ++ ++# if __GNUC__ >= 3 ++@PRAGMA_SYSTEM_HEADER@ ++# endif ++@PRAGMA_COLUMNS@ ++ ++# if HAVE_SELINUX_SELINUX_H ++ ++#@INCLUDE_NEXT@ @NEXT_SELINUX_SELINUX_H@ ++ ++# else ++ ++# include ++# include ++ ++#ifndef _GL_UNUSED_PARAMETER ++# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) ++# define _GL_UNUSED_PARAMETER __attribute__ ((__unused__)) ++# else ++# define _GL_UNUSED_PARAMETER ++# endif ++#endif ++ ++# if !GNULIB_defined_security_types ++ ++typedef unsigned short security_class_t; ++# define security_context_t char* ++# define is_selinux_enabled() 0 ++ ++static inline int getcon (security_context_t *con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline void freecon (security_context_t con _GL_UNUSED_PARAMETER) {} ++ ++ ++static inline int getfscreatecon (security_context_t *con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int setfscreatecon (security_context_t con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int matchpathcon (char const *file _GL_UNUSED_PARAMETER, ++ mode_t m _GL_UNUSED_PARAMETER, ++ security_context_t *con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int getfilecon (char const *file _GL_UNUSED_PARAMETER, ++ security_context_t *con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int lgetfilecon (char const *file _GL_UNUSED_PARAMETER, ++ security_context_t *con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int fgetfilecon (int fd, ++ security_context_t *con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int setfilecon (char const *file _GL_UNUSED_PARAMETER, ++ security_context_t con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int lsetfilecon (char const *file _GL_UNUSED_PARAMETER, ++ security_context_t con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int fsetfilecon (int fd _GL_UNUSED_PARAMETER, ++ security_context_t con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++ ++static inline int security_check_context ++ (security_context_t con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int security_check_context_raw ++ (security_context_t con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int setexeccon (security_context_t con _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int security_compute_create ++ (security_context_t scon _GL_UNUSED_PARAMETER, ++ security_context_t tcon _GL_UNUSED_PARAMETER, ++ security_class_t tclass _GL_UNUSED_PARAMETER, ++ security_context_t *newcon _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++static inline int matchpathcon_init_prefix ++ (char const *path _GL_UNUSED_PARAMETER, ++ char const *prefix _GL_UNUSED_PARAMETER) ++ { errno = ENOTSUP; return -1; } ++ ++# define GNULIB_defined_security_types 1 ++# endif ++ ++# endif ++#endif /* _GL_SELINUX_SELINUX_H */ +diff --git a/gnulib/lib/selinux-at.c b/gnulib/lib/selinux-at.c +new file mode 100644 +index 0000000..65f938b +--- /dev/null ++++ b/gnulib/lib/selinux-at.c +@@ -0,0 +1,72 @@ ++/* openat-style fd-relative functions for SE Linux ++ Copyright (C) 2007, 2009 Free Software Foundation, Inc. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* written by Jim Meyering */ ++ ++#include ++ ++#include "selinux-at.h" ++#include "openat.h" ++ ++#include ++#include ++#include ++#include ++ ++#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ ++#include "save-cwd.h" ++ ++#include "openat-priv.h" ++ ++#define AT_FUNC_NAME getfileconat ++#define AT_FUNC_F1 getfilecon ++#define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t *con ++#define AT_FUNC_POST_FILE_ARGS , con ++#include "at-func.c" ++#undef AT_FUNC_NAME ++#undef AT_FUNC_F1 ++#undef AT_FUNC_POST_FILE_PARAM_DECLS ++#undef AT_FUNC_POST_FILE_ARGS ++ ++#define AT_FUNC_NAME lgetfileconat ++#define AT_FUNC_F1 lgetfilecon ++#define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t *con ++#define AT_FUNC_POST_FILE_ARGS , con ++#include "at-func.c" ++#undef AT_FUNC_NAME ++#undef AT_FUNC_F1 ++#undef AT_FUNC_POST_FILE_PARAM_DECLS ++#undef AT_FUNC_POST_FILE_ARGS ++ ++#define AT_FUNC_NAME setfileconat ++#define AT_FUNC_F1 setfilecon ++#define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t con ++#define AT_FUNC_POST_FILE_ARGS , con ++#include "at-func.c" ++#undef AT_FUNC_NAME ++#undef AT_FUNC_F1 ++#undef AT_FUNC_POST_FILE_PARAM_DECLS ++#undef AT_FUNC_POST_FILE_ARGS ++ ++#define AT_FUNC_NAME lsetfileconat ++#define AT_FUNC_F1 lsetfilecon ++#define AT_FUNC_POST_FILE_PARAM_DECLS , security_context_t con ++#define AT_FUNC_POST_FILE_ARGS , con ++#include "at-func.c" ++#undef AT_FUNC_NAME ++#undef AT_FUNC_F1 ++#undef AT_FUNC_POST_FILE_PARAM_DECLS ++#undef AT_FUNC_POST_FILE_ARGS +diff --git a/gnulib/lib/selinux-at.h b/gnulib/lib/selinux-at.h +new file mode 100644 +index 0000000..1d84c19 +--- /dev/null ++++ b/gnulib/lib/selinux-at.h +@@ -0,0 +1,52 @@ ++/* Prototypes for openat-style fd-relative SELinux functions ++ Copyright (C) 2007, 2009 Free Software Foundation, Inc. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++#include ++#include ++ ++/* These are the dir-fd-relative variants of the functions without the ++ "at" suffix. For example, getfileconat (AT_FDCWD, file, &c) is usually ++ equivalent to getfilecon (file, &c). The emulation is accomplished ++ by first attempting getfilecon ("/proc/self/fd/DIR_FD/FILE", &c). ++ Failing that, simulate it via save_cwd/fchdir/getfilecon/restore_cwd. ++ If either the save_cwd or the restore_cwd fails (relatively unlikely), ++ then give a diagnostic and exit nonzero. */ ++ ++/* dir-fd-relative getfilecon. Set *CON to the SELinux security context ++ of the file specified by DIR_FD and FILE and return the length of *CON. ++ DIR_FD and FILE are interpreted as for fstatat[*]. A non-NULL *CON ++ must be freed with freecon. Upon error, set *CON to NULL, set errno ++ and return -1. ++ [*] with flags=0 here, with flags=AT_SYMLINK_NOFOLLOW for lgetfileconat */ ++int getfileconat (int dir_fd, char const *file, security_context_t *con); ++ ++/* dir-fd-relative lgetfilecon. This function is just like getfileconat, ++ except when DIR_FD and FILE specify a symlink: lgetfileconat operates on ++ the symlink, while getfileconat operates on the referent of the symlink. */ ++int lgetfileconat (int dir_fd, char const *file, security_context_t *con); ++ ++/* dir-fd-relative setfilecon. Set the SELinux security context of ++ the file specified by DIR_FD and FILE to CON. DIR_FD and FILE are ++ interpreted as for fstatat[*]. Upon success, return 0. ++ Otherwise, return -1 and set errno. */ ++int setfileconat (int dir_fd, char const *file, security_context_t con); ++ ++/* dir-fd-relative lsetfilecon. This function is just like setfileconat, ++ except that rather than dereferencing a symlink, this function affects it. */ ++/* dir-fd-relative lsetfilecon. This function is just like setfileconat, ++ except when DIR_FD and FILE specify a symlink: lsetfileconat operates on ++ the symlink, while setfileconat operates on the referent of the symlink. */ ++int lsetfileconat (int dir_fd, char const *file, security_context_t con); +diff --git a/gnulib/m4/gnulib-comp.m4 b/gnulib/m4/gnulib-comp.m4 +index 1efe223..87f11dd 100644 +--- a/gnulib/m4/gnulib-comp.m4 ++++ b/gnulib/m4/gnulib-comp.m4 +@@ -165,6 +165,11 @@ AC_DEFUN([gl_INIT], + gl_SAME + gl_SAVE_CWD + gl_SAVEDIR ++ AC_CHECK_HEADERS([selinux/flask.h]) ++ AC_LIBOBJ([selinux-at]) ++ gl_HEADERS_SELINUX_SELINUX_H ++ gl_HEADERS_SELINUX_CONTEXT_H ++ AC_REQUIRE([AC_C_INLINE]) + gl_FUNC_SETENV + gl_FUNC_UNSETENV + gt_TYPE_SSIZE_T +@@ -425,6 +430,7 @@ AC_DEFUN([gl_FILE_LIST], [ + lib/getdate.h + lib/getdate.y + lib/getdelim.c ++ lib/getfilecon.c + lib/getline.c + lib/getopt.c + lib/getopt.in.h +@@ -506,6 +512,10 @@ AC_DEFUN([gl_FILE_LIST], [ + lib/save-cwd.h + lib/savedir.c + lib/savedir.h ++ lib/se-context.in.h ++ lib/se-selinux.in.h ++ lib/selinux-at.c ++ lib/selinux-at.h + lib/setenv.c + lib/setenv.h + lib/stat-macros.h +@@ -688,6 +698,8 @@ AC_DEFUN([gl_FILE_LIST], [ + m4/same.m4 + m4/save-cwd.m4 + m4/savedir.m4 ++ m4/selinux-context-h.m4 ++ m4/selinux-selinux-h.m4 + m4/setenv.m4 + m4/size_max.m4 + m4/ssize_t.m4 +diff --git a/gnulib/m4/include_next.m4 b/gnulib/m4/include_next.m4 +index 7ce472b..79edd7c 100644 +--- a/gnulib/m4/include_next.m4 ++++ b/gnulib/m4/include_next.m4 +@@ -36,18 +36,35 @@ EOF + CPPFLAGS="$save_CPPFLAGS" + rm -rf conftestd1 conftestd2 + ]) ++ PRAGMA_SYSTEM_HEADER= + if test $gl_cv_have_include_next = yes; then +- +- dnl FIXME: Remove HAVE_INCLUDE_NEXT and update everything that uses it +- dnl to use @INCLUDE_NEXT@ instead. +- AC_DEFINE([HAVE_INCLUDE_NEXT], 1, +- [Define if your compiler supports the #include_next directive.]) +- + INCLUDE_NEXT=include_next ++ if test -n "$GCC"; then ++ PRAGMA_SYSTEM_HEADER='#pragma GCC system_header' ++ fi + else + INCLUDE_NEXT=include + fi + AC_SUBST([INCLUDE_NEXT]) ++ AC_SUBST([PRAGMA_SYSTEM_HEADER]) ++ AC_CACHE_CHECK([whether system header files limit the line length], ++ [gl_cv_pragma_columns], ++ [dnl HP NonStop systems, which define __TANDEM, have this misfeature. ++ AC_EGREP_CPP([choke me], ++ [ ++#ifdef __TANDEM ++choke me ++#endif ++ ], ++ [gl_cv_pragma_columns=yes], ++ [gl_cv_pragma_columns=no]) ++ ]) ++ if test $gl_cv_pragma_columns = yes; then ++ PRAGMA_COLUMNS="#pragma COLUMNS 10000" ++ else ++ PRAGMA_COLUMNS= ++ fi ++ AC_SUBST([PRAGMA_COLUMNS]) + ]) + + # gl_CHECK_NEXT_HEADERS(HEADER1 HEADER2 ...) +diff --git a/gnulib/m4/selinux-context-h.m4 b/gnulib/m4/selinux-context-h.m4 +new file mode 100644 +index 0000000..6b0bed1 +--- /dev/null ++++ b/gnulib/m4/selinux-context-h.m4 +@@ -0,0 +1,16 @@ ++# serial 1 -*- Autoconf -*- ++# Copyright (C) 2006, 2007 Free Software Foundation, Inc. ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# From Jim Meyering ++# Provide , if necessary. ++ ++AC_DEFUN([gl_HEADERS_SELINUX_CONTEXT_H], ++[ ++ AC_CHECK_HEADERS([selinux/context.h], ++ [SELINUX_CONTEXT_H=], ++ [SELINUX_CONTEXT_H=selinux/context.h]) ++ AC_SUBST([SELINUX_CONTEXT_H]) ++]) +diff --git a/gnulib/m4/selinux-selinux-h.m4 b/gnulib/m4/selinux-selinux-h.m4 +new file mode 100644 +index 0000000..767c4f7 +--- /dev/null ++++ b/gnulib/m4/selinux-selinux-h.m4 +@@ -0,0 +1,57 @@ ++# serial 3 -*- Autoconf -*- ++# Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc. ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# From Jim Meyering ++# Provide , if necessary. ++# If it is already present, provide wrapper functions to guard against ++# misbehavior from getfilecon, lgetfilecon, and fgetfilecon. ++ ++AC_DEFUN([gl_HEADERS_SELINUX_SELINUX_H], ++[ ++ AC_REQUIRE([gl_LIBSELINUX]) ++ AC_CHECK_HEADERS([selinux/selinux.h]) ++ ++ if test "$ac_cv_header_selinux_selinux_h" = yes; then ++ # We do have , so do compile getfilecon.c ++ # and arrange to use its wrappers. ++ AC_LIBOBJ([getfilecon]) ++ gl_CHECK_NEXT_HEADERS([selinux/selinux.h]) ++ AC_DEFINE([getfilecon], [rpl_getfilecon], ++ [Always use our getfilecon wrapper.]) ++ AC_DEFINE([lgetfilecon], [rpl_lgetfilecon], ++ [Always use our lgetfilecon wrapper.]) ++ AC_DEFINE([fgetfilecon], [rpl_fgetfilecon], ++ [Always use our fgetfilecon wrapper.]) ++ fi ++ ++ case "$ac_cv_search_setfilecon:$ac_cv_header_selinux_selinux_h" in ++ no:*) # already warned ++ ;; ++ *:no) ++ AC_MSG_WARN([libselinux was found but selinux/selinux.h is missing.]) ++ AC_MSG_WARN([AC_PACKAGE_NAME will be compiled without SELinux support.]) ++ esac ++]) ++ ++AC_DEFUN([gl_LIBSELINUX], ++[ ++ AC_REQUIRE([AC_CANONICAL_HOST]) ++ AC_REQUIRE([AC_CANONICAL_BUILD]) ++ LIB_SELINUX= ++ gl_save_LIBS=$LIBS ++ AC_SEARCH_LIBS([setfilecon], [selinux], ++ [test "$ac_cv_search_setfilecon" = "none required" || ++ LIB_SELINUX=$ac_cv_search_setfilecon]) ++ AC_SUBST([LIB_SELINUX]) ++ LIBS=$gl_save_LIBS ++ ++ # Warn if SELinux is found but libselinux is absent; ++ if test "$ac_cv_search_setfilecon" = no && ++ test "$host" = "$build" && test -d /selinux; then ++ AC_MSG_WARN([This system supports SELinux but libselinux is missing.]) ++ AC_MSG_WARN([AC_PACKAGE_NAME will be compiled without SELinux support.]) ++ fi ++]) +-- +1.7.9.6 + diff --git a/recipes-extended/findutils/findutils-4.4.2/findutils-with-selinux.patch b/recipes-extended/findutils/findutils-4.4.2/findutils-with-selinux.patch new file mode 100644 index 0000000..9597b09 --- /dev/null +++ b/recipes-extended/findutils/findutils-4.4.2/findutils-with-selinux.patch @@ -0,0 +1,528 @@ +Subject: [PATCH] findutils: support selinux + +Upstream-Status: Backport + +This is modified from a F13'sx SRPM patch, with conditional +selinux support. + +Signed-off-by: Xin Ouyang +--- + configure.ac | 11 ++++ + doc/find.texi | 18 ++++++- + find/Makefile.am | 2 +- + find/defs.h | 14 +++++ + find/find.1 | 4 ++ + find/parser.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + find/pred.c | 54 +++++++++++++++++++ + find/tree.c | 6 +++ + 8 files changed, 261 insertions(+), 3 deletions(-) + +diff --git a/configure.ac b/configure.ac +index f4849b3..2dd3b13 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -114,6 +114,17 @@ AC_CHECK_LIB([m],[fabs],[FINDLIBS="-lm $FINDLIBS"] + AC_DEFINE_UNQUOTED(HAVE_FABS_IN_LIBM,1,[fabs is defined in -lm])) + AC_SUBST([FINDLIBS]) + ++AC_ARG_WITH([selinux], ++ AS_HELP_STRING([--without-selinux], [disable SELinux support]), ++ [:], ++ [AC_CHECK_LIB([selinux], [is_selinux_enabled], [with_selinux=yes], [with_selinux=no])]) ++if test x$with_selinux = xyes; then ++ AC_DEFINE([WITH_SELINUX], [1], [Define to support SELinux]) ++ AC_SUBST([LIBSELINUX], [-lselinux]) ++else ++ AC_SUBST([LIBSELINUX], [ ]) ++fi ++ + dnl Checks for header files. + AC_HEADER_STDC + dnl Assume unistd.h is present - coreutils does too. +diff --git a/doc/find.texi b/doc/find.texi +index 391ffa0..f599bbc 100644 +--- a/doc/find.texi ++++ b/doc/find.texi +@@ -7,7 +7,6 @@ + @c %**end of header + + @include version.texi +-@include ../locate/dblocation.texi + + @iftex + @finalout +@@ -1242,6 +1241,14 @@ situation. + + @end deffn + ++@deffn Test -context pattern ++True if file's SELinux context matches the pattern @var{pattern}. ++The pattern uses shell glob matching. ++ ++This predicate is supported only on @code{find} versions compiled with ++SELinux support and only when SELinux is enabled. ++@end deffn ++ + @node Contents + @section Contents + +@@ -1733,6 +1740,7 @@ from the novel you are reading. + * Size Directives:: + * Location Directives:: + * Time Directives:: ++* Other Directives:: + * Formatting Flags:: + @end menu + +@@ -1890,6 +1898,14 @@ File's last modification time in the format specified by @var{k} + (@pxref{Time Formats}). + @end table + ++@node Other Directives ++@subsubsection Other Directives ++ ++@table @code ++@item %Z ++File's SELinux context, or empty string if the file has no SELinux context. ++@end table ++ + @node Time Formats + @subsection Time Formats + +diff --git a/find/Makefile.am b/find/Makefile.am +index b001509..6fc7df3 100644 +--- a/find/Makefile.am ++++ b/find/Makefile.am +@@ -26,7 +26,7 @@ endif + + EXTRA_DIST = defs.h $(man_MANS) + INCLUDES = -I../gnulib/lib -I$(top_srcdir)/lib -I$(top_srcdir)/gnulib/lib -I../intl -DLOCALEDIR=\"$(localedir)\" +-LDADD = ./libfindtools.a ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@ @LIB_CLOCK_GETTIME@ @FINDLIBS@ ++LDADD = ./libfindtools.a ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@ @LIB_CLOCK_GETTIME@ @FINDLIBS@ @LIBSELINUX@ + man_MANS = find.1 + SUBDIRS = . testsuite + +diff --git a/find/defs.h b/find/defs.h +index 4539fd9..4f3b168 100644 +--- a/find/defs.h ++++ b/find/defs.h +@@ -48,6 +48,9 @@ Please stop compiling the program now + #include /* for bool/boolean */ + #include /* for uintmax_t */ + #include /* S_ISUID etc. */ ++#ifdef WITH_SELINUX ++#include ++#endif + + + +@@ -315,6 +318,9 @@ struct predicate + struct samefile_file_id samefileid; /* samefile */ + mode_t type; /* type */ + struct format_val printf_vec; /* printf fprintf fprint ls fls print0 fprint0 print */ ++#ifdef WITH_SELINUX ++ security_context_t scontext; /* security context */ ++#endif + } args; + + /* The next predicate in the user input sequence, +@@ -459,6 +465,9 @@ PREDICATEFUNCTION pred_used; + PREDICATEFUNCTION pred_user; + PREDICATEFUNCTION pred_writable; + PREDICATEFUNCTION pred_xtype; ++#ifdef WITH_SELINUX ++PREDICATEFUNCTION pred_context; ++#endif + + + +@@ -604,6 +613,11 @@ struct options + */ + int regex_options; + ++#ifdef WITH_SELINUX ++ /* function used to get file context */ ++ int (*x_getfilecon) (int, const char *, security_context_t *); ++#endif ++ + /* Optimisation level. One is the default. + */ + unsigned short optimisation_level; +diff --git a/find/find.1 b/find/find.1 +index 8b67ae3..1d23b17 100644 +--- a/find/find.1 ++++ b/find/find.1 +@@ -933,6 +933,8 @@ if \fIc\fR is `l'. In other words, for symbolic links, + checks the type of the file that + .B \-type + does not check. ++.IP "\-context \fIpattern\fR" ++(SELinux only) Security context of the file matches glob \fIpattern\fR. + + .SS ACTIONS + .IP "\-delete\fR" +@@ -1354,6 +1356,8 @@ File's type (like in + U=unknown type (shouldn't happen) + .IP %Y + File's type (like %y), plus follow symlinks: L=loop, N=nonexistent ++.IP %Z ++(SELinux only) file's security context. + .PP + A `%' character followed by any other character is discarded, but the + other character is printed (don't rely on this, as further format +diff --git a/find/parser.c b/find/parser.c +index 08758ee..02f9067 100644 +--- a/find/parser.c ++++ b/find/parser.c +@@ -53,6 +53,10 @@ + #include + #include + ++#ifdef WITH_SELINUX ++#include "selinux-at.h" ++#endif ++ + #if ENABLE_NLS + # include + # define _(Text) gettext (Text) +@@ -155,6 +159,9 @@ static boolean parse_noignore_race PARAMS((const struct parser_table*, char *arg + static boolean parse_warn PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); + static boolean parse_xtype PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); + static boolean parse_quit PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); ++#ifdef WITH_SELINUX ++static boolean parse_context PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); ++#endif + + boolean parse_print PARAMS((const struct parser_table*, char *argv[], int *arg_ptr)); + +@@ -251,6 +258,9 @@ static struct parser_table const parse_table[] = + PARSE_TEST ("cmin", cmin), /* GNU */ + PARSE_TEST ("cnewer", cnewer), /* GNU */ + {ARG_TEST, "ctime", parse_time, pred_ctime}, /* POSIX */ ++#ifdef WITH_SELINUX ++ PARSE_TEST ("context", context), /* GNU */ ++#endif + PARSE_POSOPT ("daystart", daystart), /* GNU */ + PARSE_ACTION ("delete", delete), /* GNU, Mac OS, FreeBSD */ + PARSE_OPTION ("d", d), /* Mac OS X, FreeBSD, NetBSD, OpenBSD, but deprecated in favour of -depth */ +@@ -347,6 +357,89 @@ static struct parser_table const parse_table[] = + static const char *first_nonoption_arg = NULL; + static const struct parser_table *noop = NULL; + ++#ifdef WITH_SELINUX ++static int ++fallback_getfilecon (int fd, const char *name, security_context_t *p, ++ int prev_rv) ++{ ++ /* Our original getfilecon () call failed. Perhaps we can't follow a ++ * symbolic link. If that might be the problem, lgetfilecon () the link. ++ * Otherwise, admit defeat. */ ++ switch (errno) ++ { ++ case ENOENT: ++ case ENOTDIR: ++#ifdef DEBUG_STAT ++ fprintf (stderr, "fallback_getfilecon(): getfilecon(%s) failed; falling " ++ "back on lgetfilecon()\n", name); ++#endif ++ return lgetfileconat (fd, name, p); ++ ++ case EACCES: ++ case EIO: ++ case ELOOP: ++ case ENAMETOOLONG: ++#ifdef EOVERFLOW ++ case EOVERFLOW: /* EOVERFLOW is not #defined on UNICOS. */ ++#endif ++ default: ++ return prev_rv; ++ } ++} ++ ++/* optionh_getfilecon () implements the getfilecon operation when the ++ * -H option is in effect. ++ * ++ * If the item to be examined is a command-line argument, we follow ++ * symbolic links. If the getfilecon () call fails on the command-line ++ * item, we fall back on the properties of the symbolic link. ++ * ++ * If the item to be examined is not a command-line argument, we ++ * examine the link itself. */ ++int ++optionh_getfilecon (int fd, const char *name, security_context_t *p) ++{ ++ int rv; ++ if (0 == state.curdepth) ++ { ++ /* This file is from the command line; dereference the link (if it is ++ a link). */ ++ rv = getfileconat (fd, name, p); ++ if (0 == rv) ++ return 0; /* success */ ++ else ++ return fallback_getfilecon (fd, name, p, rv); ++ } ++ else ++ { ++ /* Not a file on the command line; do not dereference the link. */ ++ return lgetfileconat (fd, name, p); ++ } ++} ++ ++/* optionl_getfilecon () implements the getfilecon operation when the ++ * -L option is in effect. That option makes us examine the thing the ++ * symbolic link points to, not the symbolic link itself. */ ++int ++optionl_getfilecon (int fd, const char *name, security_context_t *p) ++{ ++ int rv = getfileconat (fd, name, p); ++ if (0 == rv) ++ return 0; /* normal case. */ ++ else ++ return fallback_getfilecon (fd, name, p, rv); ++} ++ ++/* optionp_getfilecon () implements the stat operation when the -P ++ * option is in effect (this is also the default). That option makes ++ * us examine the symbolic link itself, not the thing it points to. */ ++int ++optionp_getfilecon (int fd, const char *name, security_context_t *p) ++{ ++ return lgetfileconat (fd, name, p); ++} ++ ++#endif + + void + check_option_combinations(const struct predicate *p) +@@ -450,11 +543,17 @@ set_follow_state(enum SymlinkOption opt) + { + case SYMLINK_ALWAYS_DEREF: /* -L */ + options.xstat = optionl_stat; ++#ifdef WITH_SELINUX ++ options.x_getfilecon = optionl_getfilecon; ++#endif + options.no_leaf_check = true; + break; + + case SYMLINK_NEVER_DEREF: /* -P (default) */ + options.xstat = optionp_stat; ++#ifdef WITH_SELINUX ++ options.x_getfilecon = optionp_getfilecon; ++#endif + /* Can't turn no_leaf_check off because the user might have specified + * -noleaf anyway + */ +@@ -462,6 +561,9 @@ set_follow_state(enum SymlinkOption opt) + + case SYMLINK_DEREF_ARGSONLY: /* -H */ + options.xstat = optionh_stat; ++#ifdef WITH_SELINUX ++ options.x_getfilecon = optionh_getfilecon; ++#endif + options.no_leaf_check = true; + } + } +@@ -1146,8 +1248,14 @@ tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N\n\ + -nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN\n\ + -readable -writable -executable\n\ + -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\ +- -used N -user NAME -xtype [bcdpfls]\n")); ++ -used N -user NAME -xtype [bcdpfls]")); ++#ifdef WITH_SELINUX + puts (_("\ ++ -context CONTEXT\n")); ++#else ++ puts (_("\n")); ++#endif ++ puts (_("\n\ + actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print \n\ + -fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit\n\ + -exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;\n\ +@@ -2574,6 +2682,13 @@ parse_version (const struct parser_table* entry, char **argv, int *arg_ptr) + printf("LEAF_OPTIMISATION "); + ++features; + #endif ++#ifdef WITH_SELINUX ++ if (0 < is_selinux_enabled ()) ++ { ++ printf ("SELINUX "); ++ ++features; ++ } ++#endif + + flags = 0; + if (is_fts_enabled(&flags)) +@@ -2608,6 +2723,33 @@ parse_version (const struct parser_table* entry, char **argv, int *arg_ptr) + exit (0); + } + ++#ifdef WITH_SELINUX ++static boolean ++parse_context (const struct parser_table* entry, char **argv, int *arg_ptr) ++{ ++ struct predicate *our_pred; ++ ++ if ((argv == NULL) || (argv[*arg_ptr] == NULL)) ++ return false; ++ ++ if (is_selinux_enabled () <= 0) ++ { ++ error (1, 0, _("invalid predicate -context: SELinux is not enabled.")); ++ return false; ++ } ++ our_pred = insert_primary (entry, NULL); ++ our_pred->est_success_rate = 0.01f; ++ our_pred->need_stat = false; ++#ifdef DEBUG ++ our_pred->p_name = find_pred_name (pred_context); ++#endif /*DEBUG*/ ++ our_pred->args.scontext = argv[*arg_ptr]; ++ ++ (*arg_ptr)++; ++ return true; ++} ++#endif ++ + static boolean + parse_xdev (const struct parser_table* entry, char **argv, int *arg_ptr) + { +@@ -2861,7 +3003,11 @@ insert_fprintf (struct format_val *vec, + if (*scan2 == '.') + for (scan2++; ISDIGIT (*scan2); scan2++) + /* Do nothing. */ ; ++#ifdef WITH_SELINUX ++ if (strchr ("abcdDfFgGhHiklmMnpPsStuUyYZ", *scan2)) ++#else + if (strchr ("abcdDfFgGhHiklmMnpPsStuUyY", *scan2)) ++#endif + { + segmentp = make_segment (segmentp, format, scan2 - format, + KIND_FORMAT, *scan2, 0, +@@ -2991,6 +3137,13 @@ make_segment (struct segment **segment, + *fmt++ = 's'; + break; + ++#ifdef WITH_SELINUX ++ case 'Z': /* SELinux security context */ ++ mycost = NeedsAccessInfo; ++ *fmt++ = 's'; ++ break; ++#endif ++ + case 'H': /* ARGV element file was found under */ + *fmt++ = 's'; + break; +diff --git a/find/pred.c b/find/pred.c +index b1f48a0..43cfd19 100644 +--- a/find/pred.c ++++ b/find/pred.c +@@ -48,6 +48,10 @@ + #include "error.h" + #include "verify.h" + ++#ifdef WITH_SELINUX ++#include ++#endif ++ + #if ENABLE_NLS + # include + # define _(Text) gettext (Text) +@@ -230,6 +234,9 @@ struct pred_assoc pred_table[] = + {pred_user, "user "}, + {pred_writable, "writable "}, + {pred_xtype, "xtype "}, ++#ifdef WITH_SELINUX ++ {pred_context, "context"}, ++#endif + {0, "none "} + }; + #endif +@@ -1054,6 +1061,32 @@ do_fprintf(struct format_val *dest, + mode_to_filetype(stat_buf->st_mode & S_IFMT)); + } + break; ++ ++#ifdef WITH_SELINUX ++ case 'Z': /* SELinux security context */ ++ { ++ security_context_t scontext; ++ int rv = (*options.x_getfilecon) (state.cwd_dir_fd, state.rel_pathname, ++ &scontext); ++ if (rv < 0) ++ { ++ /* If getfilecon fails, there will in the general case ++ still be some text to print. We just make %Z expand ++ to an empty string. */ ++ checked_fprintf (dest, segment->text, ""); ++ ++ error (0, errno, "getfilecon: %s", ++ safely_quote_err_filename (0, pathname)); ++ state.exit_status = 1; ++ } ++ else ++ { ++ checked_fprintf (dest, segment->text, scontext); ++ freecon (scontext); ++ } ++ } ++ break; ++#endif + } + /* end of KIND_FORMAT case */ + break; +@@ -1844,6 +1877,27 @@ pred_xtype (const char *pathname, struct stat *stat_buf, struct predicate *pred_ + */ + return (pred_type (pathname, &sbuf, pred_ptr)); + } ++ ++#ifdef WITH_SELINUX ++boolean ++pred_context (const char *pathname, struct stat *stat_buf, ++ struct predicate *pred_ptr) ++{ ++ security_context_t scontext; ++ int rv = (*options.x_getfilecon) (state.cwd_dir_fd, state.rel_pathname, ++ &scontext); ++ if (rv < 0) ++ { ++ error (0, errno, "getfilecon: %s", safely_quote_err_filename (0, pathname)); ++ return false; ++ } ++ ++ rv = (fnmatch (pred_ptr->args.scontext, scontext, 0) == 0); ++ freecon (scontext); ++ return rv; ++} ++#endif ++ + + /* 1) fork to get a child; parent remembers the child pid + 2) child execs the command requested +diff --git a/find/tree.c b/find/tree.c +index 60a0601..6d48c09 100644 +--- a/find/tree.c ++++ b/find/tree.c +@@ -909,6 +909,9 @@ static struct pred_cost_lookup costlookup[] = + { pred_cmin , NeedsStatInfo, }, + { pred_cnewer , NeedsStatInfo, }, + { pred_comma , NeedsNothing, }, ++#ifdef WITH_SELINUX ++ { pred_context , NeedsAccessInfo }, ++#endif + { pred_ctime , NeedsStatInfo, }, + { pred_delete , NeedsSyncDiskHit }, + { pred_empty , NeedsStatInfo }, +@@ -1453,6 +1456,9 @@ get_new_pred (const struct parser_table *entry) + last_pred->p_cost = NeedsUnknown; + last_pred->arg_text = "ThisShouldBeSetToSomethingElse"; + last_pred->args.str = NULL; ++#ifdef WITH_SELINUX ++ last_pred->args.scontext = NULL; ++#endif + last_pred->pred_next = NULL; + last_pred->pred_left = NULL; + last_pred->pred_right = NULL; +-- +1.7.9.6 + diff --git a/recipes-extended/findutils/findutils_4.4.2.bbappend b/recipes-extended/findutils/findutils_4.4.2.bbappend index a3922d8..eb94cfa 100644 --- a/recipes-extended/findutils/findutils_4.4.2.bbappend +++ b/recipes-extended/findutils/findutils_4.4.2.bbappend @@ -1,9 +1,9 @@ -PR .= ".1" +PR .= ".2" FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:" -SRC_URI += "file://findutils-selinux.patch" -SRC_URI += "file://findutils-selinux-gnulib.patch" +SRC_URI += "file://findutils-with-selinux.patch" +SRC_URI += "file://findutils-with-selinux-gnulib.patch" DEPENDS += "${@base_contains('DISTRO_FEATURES', 'selinux', 'libselinux', '', d)}" -- cgit v1.2.3-54-g00ecf