bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

getfilecon, lgetfilecon, fgetfilecon wrappers


From: Jim Meyering
Subject: getfilecon, lgetfilecon, fgetfilecon wrappers
Date: Fri, 09 Oct 2009 10:17:23 +0200

I've written an addition to the selinux-h module
that makes it wrap the three getfilecon functions.

I debated whether to take the stdlib.in.h approach and create separate
per-function modules, but know of no application that would use selinux-h
without also using at least one of the three affected functions, so
opted to merely add to the existing selinux-h module.

Also, when writing the documentation, I was not particularly comfortable
in duplicating getfilecon.texi's contents in each of lgetfilecon.texi and
fgetfilecon.texi.  So instead, I created a new file, getfilecon-desc.texi
with a @macro for the body, and merely used the macro from each of the
three .texi files.  It generates the right info documentation, so it
should be ok.  But since this is the first such use of a @macro definition
under doc/ I have to wonder...  Is there some problem with that?


>From f4dc80620e25623a69aa852bec5a52e150cedd4a Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Wed, 7 Oct 2009 19:00:42 +0200
Subject: [PATCH] selinux-h: always use getfilecon wrappers

* lib/getfilecon.c: New file.
* lib/se-selinux.in.h: Use a better inclusion guard symbol name.
[HAVE_SELINUX_SELINUX_H]: Include-next <selinux/selinux.h>.
[!HAVE_SELINUX_SELINUX_H]: Use better parameter names.
(fgetfilecon): Provide a stub.
* m4/selinux-selinux-h.m4 (gl_HEADERS_SELINUX_SELINUX_H): Don't
AC_SUBST SELINUX_SELINUX_H, since now we're generating that
file unconditionally.
When <selinux/selinux.h> is found, arrange to use wrappers.
* modules/selinux-h (Files): Add getfilecon.c.
(Makefile.am): Substitute include-next-related bits
into the now-always-generated selinux/selinux.h file.
* doc/glibc-functions/getfilecon.texi: New file.
* doc/glibc-functions/lgetfilecon.texi: New file.
* doc/glibc-functions/fgetfilecon.texi: New file.
* doc/glibc-functions/getfilecon-desc.texi: New file.
* doc/gnulib.texi (Glibc selinux/selinux.h): New section, by
which to pull in the new files.
* MODULES.html.sh (Misc): Add selinux-h.
---
 ChangeLog                                |   23 ++++++++
 MODULES.html.sh                          |    1 +
 doc/glibc-functions/fgetfilecon.texi     |    5 ++
 doc/glibc-functions/getfilecon-desc.texi |   27 +++++++++
 doc/glibc-functions/getfilecon.texi      |    5 ++
 doc/glibc-functions/lgetfilecon.texi     |    5 ++
 doc/gnulib.texi                          |   15 +++++
 lib/getfilecon.c                         |   87 ++++++++++++++++++++++++++++++
 lib/se-selinux.in.h                      |   39 +++++++++----
 m4/selinux-selinux-h.m4                  |   20 ++++++--
 modules/selinux-h                        |   10 +++-
 11 files changed, 219 insertions(+), 18 deletions(-)
 create mode 100644 doc/glibc-functions/fgetfilecon.texi
 create mode 100644 doc/glibc-functions/getfilecon-desc.texi
 create mode 100644 doc/glibc-functions/getfilecon.texi
 create mode 100644 doc/glibc-functions/lgetfilecon.texi
 create mode 100644 lib/getfilecon.c

diff --git a/ChangeLog b/ChangeLog
index f374647..7ad1a66 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2009-10-09  Jim Meyering  <address@hidden>
+
+       selinux-h: always use getfilecon wrappers
+       * lib/getfilecon.c: New file.
+       * lib/se-selinux.in.h: Use a better inclusion guard symbol name.
+       [HAVE_SELINUX_SELINUX_H]: Include-next <selinux/selinux.h>.
+       [!HAVE_SELINUX_SELINUX_H]: Use better parameter names.
+       (fgetfilecon): Provide a stub.
+       * m4/selinux-selinux-h.m4 (gl_HEADERS_SELINUX_SELINUX_H): Don't
+       AC_SUBST SELINUX_SELINUX_H, since now we're generating that
+       file unconditionally.
+       When <selinux/selinux.h> is found, arrange to use wrappers.
+       * modules/selinux-h (Files): Add getfilecon.c.
+       (Makefile.am): Substitute include-next-related bits
+       into the now-always-generated selinux/selinux.h file.
+       * doc/glibc-functions/lgetfilecon.texi: New file.
+       * doc/glibc-functions/fgetfilecon.texi: New file.
+       * doc/glibc-functions/getfilecon.texi: New file.
+       * doc/glibc-functions/getfilecon-desc.texi: New file.
+       * doc/gnulib.texi (Glibc selinux/selinux.h): New section, by
+       which to pull in the new files.
+       * MODULES.html.sh (Misc): Add selinux-h.
+
 2009-10-08  Jim Meyering  <address@hidden>

        unistd: fix comment typo
diff --git a/MODULES.html.sh b/MODULES.html.sh
index 0d2c3cb..53b0b5d 100755
--- a/MODULES.html.sh
+++ b/MODULES.html.sh
@@ -3142,6 +3142,7 @@ func_all_modules ()
   func_module quote
   func_module readutmp
   func_module random_r
+  func_module selinux-h
   func_module selinux-at
   func_module sysexits
   func_module u64
diff --git a/doc/glibc-functions/fgetfilecon.texi 
b/doc/glibc-functions/fgetfilecon.texi
new file mode 100644
index 0000000..b2cf7e8
--- /dev/null
+++ b/doc/glibc-functions/fgetfilecon.texi
@@ -0,0 +1,5 @@
address@hidden fgetfilecon
address@hidden @code{fgetfilecon}
address@hidden fgetfilecon
+
address@hidden
diff --git a/doc/glibc-functions/getfilecon-desc.texi 
b/doc/glibc-functions/getfilecon-desc.texi
new file mode 100644
index 0000000..fb661a7
--- /dev/null
+++ b/doc/glibc-functions/getfilecon-desc.texi
@@ -0,0 +1,27 @@
address@hidden getfileconDesc{fn}
+Gnulib module: selinux-h
+
+Portability problems fixed by Gnulib:
address@hidden
address@hidden
+This function is missing on some platforms:
+MacOS X 10.3, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, 
mingw, Interix 3.5, BeOS.
+On those platforms, this module provides a stub that always sets
address@hidden to @code{ENOTSUP} and returns @samp{-1}.
address@hidden
+On systems with SELinux support, this module provides a wrapper for the
address@hidden function that insulates the caller from API-nonconforming 
behavior.
+Without this wrapper, @code{\fn\} can return @samp{0} and set
+the @code{context} pointer to NULL, and in another scenario can return
address@hidden and set the @code{context} pointer to @samp{unlabeled}.
+This wrapper returns @samp{-1} in each case and sets @code{errno} to
address@hidden and @code{ENODATA} respectively.
+While the conditions that can provoke such behavior are rare, the
+average caller does not handle them because the possibility of such
+behavior is not documented.
address@hidden itemize
+
+Portability problems not fixed by Gnulib:
address@hidden
address@hidden itemize
address@hidden macro
diff --git a/doc/glibc-functions/getfilecon.texi 
b/doc/glibc-functions/getfilecon.texi
new file mode 100644
index 0000000..d7afcb9
--- /dev/null
+++ b/doc/glibc-functions/getfilecon.texi
@@ -0,0 +1,5 @@
address@hidden getfilecon
address@hidden @code{getfilecon}
address@hidden getfilecon
+
address@hidden
diff --git a/doc/glibc-functions/lgetfilecon.texi 
b/doc/glibc-functions/lgetfilecon.texi
new file mode 100644
index 0000000..7de1bb2
--- /dev/null
+++ b/doc/glibc-functions/lgetfilecon.texi
@@ -0,0 +1,5 @@
address@hidden lgetfilecon
address@hidden @code{lgetfilecon}
address@hidden lgetfilecon
+
address@hidden
diff --git a/doc/gnulib.texi b/doc/gnulib.texi
index 37cec41..b3085d4 100644
--- a/doc/gnulib.texi
+++ b/doc/gnulib.texi
@@ -3290,6 +3290,7 @@ Glibc Function Substitutes
 * Glibc rpcsvc/ypupd.h::
 * Glibc sched.h::
 * Glibc search.h::
+* Glibc selinux/selinux.h::
 * Glibc shadow.h::
 * Glibc signal.h::
 * Glibc stdio.h::
@@ -4906,6 +4907,20 @@ Glibc search.h
 @include glibc-functions/hsearch_r.texi
 @include glibc-functions/tdestroy.texi

address@hidden Glibc selinux/selinux.h
address@hidden Glibc Extensions to @code{<selinux/selinux.h>}
+
address@hidden
+* fgetfilecon::
+* getfilecon::
+* lgetfilecon::
address@hidden menu
+
address@hidden glibc-functions/getfilecon-desc.texi
address@hidden glibc-functions/fgetfilecon.texi
address@hidden glibc-functions/getfilecon.texi
address@hidden glibc-functions/lgetfilecon.texi
+
 @c @node Glibc semaphore.h
 @c @section Glibc Extensions to @code{<semaphore.h>}

diff --git a/lib/getfilecon.c b/lib/getfilecon.c
new file mode 100644
index 0000000..d712307
--- /dev/null
+++ b/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 <config.h>
+
+#include <selinux/selinux.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <string.h>
+
+/* 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/lib/se-selinux.in.h b/lib/se-selinux.in.h
index 25cbaae..c09aebd 100644
--- a/lib/se-selinux.in.h
+++ b/lib/se-selinux.in.h
@@ -1,12 +1,22 @@
-#ifndef SELINUX_SELINUX_H
-# define SELINUX_SELINUX_H
+#ifndef _GL_SELINUX_SELINUX_H
+# define _GL_SELINUX_SELINUX_H

-# include <sys/types.h>
-# include <errno.h>
+# if __GNUC__ >= 3
address@hidden@
+# endif
+
+# if HAVE_SELINUX_SELINUX_H
+
address@hidden@ @NEXT_SELINUX_SELINUX_H@
+
+# else
+
+#  include <sys/types.h>
+#  include <errno.h>

 typedef unsigned short security_class_t;
-# define security_context_t char*
-# define is_selinux_enabled() 0
+#  define security_context_t char*
+#  define is_selinux_enabled() 0

 static inline int getcon (security_context_t *con _UNUSED_PARAMETER_)
   { errno = ENOTSUP; return -1; }
@@ -17,20 +27,23 @@ 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 *s _UNUSED_PARAMETER_,
+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 *s _UNUSED_PARAMETER_,
+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 *s _UNUSED_PARAMETER_,
+static inline int lgetfilecon (char const *file _UNUSED_PARAMETER_,
                               security_context_t *con _UNUSED_PARAMETER_)
   { errno = ENOTSUP; return -1; }
-static inline int setfilecon (char const *s _UNUSED_PARAMETER_,
+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 *s _UNUSED_PARAMETER_,
+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_,
@@ -55,4 +68,6 @@ static inline int matchpathcon_init_prefix
     (char const *path _UNUSED_PARAMETER_,
      char const *prefix _UNUSED_PARAMETER_)
   { errno = ENOTSUP; return -1; }
-#endif
+
+# endif
+#endif /* _GL_SELINUX_SELINUX_H */
diff --git a/m4/selinux-selinux-h.m4 b/m4/selinux-selinux-h.m4
index 20dc77c..767c4f7 100644
--- a/m4/selinux-selinux-h.m4
+++ b/m4/selinux-selinux-h.m4
@@ -6,14 +6,26 @@

 # From Jim Meyering
 # Provide <selinux/selinux.h>, 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],
-                  [SELINUX_SELINUX_H=],
-                  [SELINUX_SELINUX_H=selinux/selinux.h])
-  AC_SUBST([SELINUX_SELINUX_H])
+  AC_CHECK_HEADERS([selinux/selinux.h])
+
+  if test "$ac_cv_header_selinux_selinux_h" = yes; then
+    # We do have <selinux/selinux.h>, 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
diff --git a/modules/selinux-h b/modules/selinux-h
index c9a5a04..fd01241 100644
--- a/modules/selinux-h
+++ b/modules/selinux-h
@@ -2,6 +2,7 @@ Description:
 SELinux-related headers for systems that lack them.

 Files:
+lib/getfilecon.c
 lib/se-context.in.h
 lib/se-selinux.in.h
 m4/selinux-context-h.m4
@@ -18,11 +19,16 @@ AC_REQUIRE([AC_C_INLINE])
 Makefile.am:
 lib_SOURCES += se-context.in.h se-selinux.in.h

-BUILT_SOURCES += $(SELINUX_SELINUX_H)
+BUILT_SOURCES += selinux/selinux.h
 selinux/selinux.h: se-selinux.in.h
        $(AM_V_at)$(MKDIR_P) selinux
        $(AM_V_GEN)rm -f address@hidden $@ && \
-       cp $(srcdir)/se-selinux.in.h address@hidden && \
+       { 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; \
+       } > address@hidden && \
        chmod a-x address@hidden && \
        mv address@hidden $@
 MOSTLYCLEANFILES += selinux/selinux.h selinux/selinux.h-t
--
1.6.5.rc3.193.gdf7a




reply via email to

[Prev in Thread] Current Thread [Next in Thread]