changeset 5788:410ef4f1a3d2 v7.4.238

updated for version 7.4.238 Problem: Vim does not support the smack library. Solution: Add smack support (Jose Bollo)
author Bram Moolenaar <bram@vim.org>
date Wed, 02 Apr 2014 14:05:38 +0200
parents 3a368abed51c
children 29dd99f4945d
files src/auto/configure src/config.h.in src/configure.in src/fileio.c src/memfile.c src/os_unix.c src/undo.c src/version.c
diffstat 8 files changed, 218 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -782,6 +782,7 @@ with_ex_name
 with_view_name
 with_global_runtime
 with_modified_by
+enable_smack
 enable_selinux
 with_features
 with_compiledby
@@ -1453,7 +1454,8 @@ Optional Features:
   --enable-fail-if-missing    Fail if dependencies on additional features
      specified on the command line are missing.
   --disable-darwin        Disable Darwin (Mac OS X) support.
-  --disable-selinux	  Don't check for SELinux support.
+  --disable-smack	  Do not check for Smack support.
+  --disable-selinux	  Do not check for SELinux support.
   --disable-xsmp          Disable XSMP session management
   --disable-xsmp-interact Disable XSMP interaction
   --enable-luainterp=OPTS     Include Lua interpreter.  default=no OPTS=no/yes/dynamic
@@ -4588,19 +4590,90 @@ fi
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking --disable-selinux argument" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking --disable-smack argument" >&5
+$as_echo_n "checking --disable-smack argument... " >&6; }
+# Check whether --enable-smack was given.
+if test "${enable_smack+set}" = set; then :
+  enableval=$enable_smack;
+else
+  enable_smack="yes"
+fi
+
+if test "$enable_smack" = "yes"; then
+  ac_fn_c_check_header_mongrel "$LINENO" "linux/xattr.h" "ac_cv_header_linux_xattr_h" "$ac_includes_default"
+if test "x$ac_cv_header_linux_xattr_h" = xyes; then :
+  true
+else
+  enable_smack="no"
+fi
+
+
+fi
+if test "$enable_smack" = "yes"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for llistxattr in -lattr" >&5
+$as_echo_n "checking for llistxattr in -lattr... " >&6; }
+if ${ac_cv_lib_attr_llistxattr+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lattr  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char llistxattr ();
+int
+main ()
+{
+return llistxattr ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_attr_llistxattr=yes
+else
+  ac_cv_lib_attr_llistxattr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_attr_llistxattr" >&5
+$as_echo "$ac_cv_lib_attr_llistxattr" >&6; }
+if test "x$ac_cv_lib_attr_llistxattr" = xyes; then :
+  LIBS="$LIBS -lattr"
+	   found_smack="yes"
+	   $as_echo "#define HAVE_SMACK 1" >>confdefs.h
+
+fi
+
+else
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+
+if test "x$found_smack" = "x"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking --disable-selinux argument" >&5
 $as_echo_n "checking --disable-selinux argument... " >&6; }
-# Check whether --enable-selinux was given.
+  # Check whether --enable-selinux was given.
 if test "${enable_selinux+set}" = set; then :
   enableval=$enable_selinux;
 else
   enable_selinux="yes"
 fi
 
-if test "$enable_selinux" = "yes"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_selinux_enabled in -lselinux" >&5
+  if test "$enable_selinux" = "yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_selinux_enabled in -lselinux" >&5
 $as_echo_n "checking for is_selinux_enabled in -lselinux... " >&6; }
 if ${ac_cv_lib_selinux_is_selinux_enabled+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4638,13 +4711,14 @@ fi
 $as_echo "$ac_cv_lib_selinux_is_selinux_enabled" >&6; }
 if test "x$ac_cv_lib_selinux_is_selinux_enabled" = xyes; then :
   LIBS="$LIBS -lselinux"
-	   $as_echo "#define HAVE_SELINUX 1" >>confdefs.h
-
-fi
-
-else
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+	     $as_echo "#define HAVE_SELINUX 1" >>confdefs.h
+
+fi
+
+  else
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
+  fi
 fi
 
 
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -191,6 +191,7 @@
 #undef HAVE_SIGSETJMP
 #undef HAVE_SIGSTACK
 #undef HAVE_SIGVEC
+#undef HAVE_SMACK
 #undef HAVE_STRCASECMP
 #undef HAVE_STRERROR
 #undef HAVE_STRFTIME
--- a/src/configure.in
+++ b/src/configure.in
@@ -387,20 +387,41 @@ fi
 AC_SUBST(QUOTESED)
 
 
-dnl Link with -lselinux for SELinux stuff; if not found
-AC_MSG_CHECKING(--disable-selinux argument)
-AC_ARG_ENABLE(selinux,
-	[  --disable-selinux	  Don't check for SELinux support.],
-	, enable_selinux="yes")
-if test "$enable_selinux" = "yes"; then
+dnl Link with -lsmack for Smack stuff; if not found
+AC_MSG_CHECKING(--disable-smack argument)
+AC_ARG_ENABLE(smack,
+	[  --disable-smack	  Do not check for Smack support.],
+	, enable_smack="yes")
+if test "$enable_smack" = "yes"; then
+  AC_CHECK_HEADER([linux/xattr.h], true, enable_smack="no")
+fi
+if test "$enable_smack" = "yes"; then
   AC_MSG_RESULT(no)
-  AC_CHECK_LIB(selinux, is_selinux_enabled,
-	  [LIBS="$LIBS -lselinux"
-	   AC_DEFINE(HAVE_SELINUX)])
+  AC_CHECK_LIB(attr, llistxattr,
+	  [LIBS="$LIBS -lattr"
+	   found_smack="yes"
+	   AC_DEFINE(HAVE_SMACK)])
 else
    AC_MSG_RESULT(yes)
 fi
 
+dnl When smack was found don't search for SELinux
+if test "x$found_smack" = "x"; then
+  dnl Link with -lselinux for SELinux stuff; if not found
+  AC_MSG_CHECKING(--disable-selinux argument)
+  AC_ARG_ENABLE(selinux,
+	  [  --disable-selinux	  Do not check for SELinux support.],
+	  , enable_selinux="yes")
+  if test "$enable_selinux" = "yes"; then
+    AC_MSG_RESULT(no)
+    AC_CHECK_LIB(selinux, is_selinux_enabled,
+	    [LIBS="$LIBS -lselinux"
+	     AC_DEFINE(HAVE_SELINUX)])
+  else
+     AC_MSG_RESULT(yes)
+  fi
+fi
+
 dnl Check user requested features.
 
 AC_MSG_CHECKING(--with-features argument)
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4030,7 +4030,7 @@ buf_write(buf, fname, sfname, start, end
 						)
 			    mch_setperm(backup,
 					  (perm & 0707) | ((perm & 07) << 3));
-# ifdef HAVE_SELINUX
+# if defined(HAVE_SELINUX) || defined(HAVE_SMACK)
 			mch_copy_sec(fname, backup);
 # endif
 #endif
@@ -4069,7 +4069,7 @@ buf_write(buf, fname, sfname, start, end
 #ifdef HAVE_ACL
 			mch_set_acl(backup, acl);
 #endif
-#ifdef HAVE_SELINUX
+#if defined(HAVE_SELINUX) || defined(HAVE_SMACK)
 			mch_copy_sec(fname, backup);
 #endif
 			break;
@@ -4718,7 +4718,7 @@ restore_backup:
     }
 #endif
 
-#ifdef HAVE_SELINUX
+#if defined(HAVE_SELINUX) || defined(HAVE_SMACK)
     /* Probably need to set the security context. */
     if (!backup_copy)
 	mch_copy_sec(backup, wfname);
@@ -6707,7 +6707,7 @@ vim_rename(from, to)
     mch_set_acl(to, acl);
     mch_free_acl(acl);
 #endif
-#ifdef HAVE_SELINUX
+#if defined(HAVE_SELINUX) || defined(HAVE_SMACK)
     mch_copy_sec(from, to);
 #endif
     if (errmsg != NULL)
--- a/src/memfile.c
+++ b/src/memfile.c
@@ -1358,7 +1358,7 @@ mf_do_open(mfp, fname, flags)
 	if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
 	    fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
 #endif
-#ifdef HAVE_SELINUX
+#if defined(HAVE_SELINUX) || defined(HAVE_SMACK)
 	mch_copy_sec(fname, mfp->mf_fname);
 #endif
 	mch_hide(mfp->mf_fname);    /* try setting the 'hidden' flag */
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -46,6 +46,14 @@
 static int selinux_enabled = -1;
 #endif
 
+#ifdef HAVE_SMACK
+# include <attr/xattr.h>
+# include <linux/xattr.h>
+# ifndef SMACK_LABEL_LEN
+#  define SMACK_LABEL_LEN 1024
+# endif
+#endif
+
 /*
  * Use this prototype for select, some include files have a wrong prototype
  */
@@ -2798,6 +2806,90 @@ mch_copy_sec(from_file, to_file)
 }
 #endif /* HAVE_SELINUX */
 
+#if defined(HAVE_SMACK) && !defined(PROTO)
+/*
+ * Copy security info from "from_file" to "to_file".
+ */
+    void
+mch_copy_sec(from_file, to_file)
+    char_u	*from_file;
+    char_u	*to_file;
+{
+    static const char const *smack_copied_attributes[] =
+	{
+	    XATTR_NAME_SMACK,
+	    XATTR_NAME_SMACKEXEC,
+	    XATTR_NAME_SMACKMMAP
+	};
+
+    char	buffer[SMACK_LABEL_LEN];
+    const char	*name;
+    int		index;
+    int		ret;
+    ssize_t	size;
+
+    if (from_file == NULL)
+	return;
+
+    for (index = 0 ; index < (int)(sizeof(smack_copied_attributes)
+			      / sizeof(smack_copied_attributes)[0]) ; index++)
+    {
+	/* get the name of the attribute to copy */
+	name = smack_copied_attributes[index];
+
+	/* get the value of the attribute in buffer */
+	size = getxattr((char*)from_file, name, buffer, sizeof(buffer));
+	if (size >= 0)
+	{
+	    /* copy the attribute value of buffer */
+	    ret = setxattr((char*)to_file, name, buffer, (size_t)size, 0);
+	    if (ret < 0)
+	    {
+		MSG_PUTS(_("Could not set security context "));
+		MSG_PUTS(name);
+		MSG_PUTS(_(" for "));
+		msg_outtrans(to_file);
+		msg_putchar('\n');
+	    }
+	}
+	else
+	{
+	    /* what reason of not having the attribute value? */
+	    switch (errno)
+	    {
+		case ENOTSUP:
+		    /* extended attributes aren't supported or enabled */
+		    /* should a message be echoed? not sure... */
+		    return; /* leave because it isn't usefull to continue */
+
+		case ERANGE:
+		default:
+		    /* no enough size OR unexpected error */
+		    MSG_PUTS(_("Could not get security context "));
+		    MSG_PUTS(name);
+		    MSG_PUTS(_(" for "));
+		    msg_outtrans(from_file);
+		    MSG_PUTS(_(". Removing it!\n"));
+		    /* FALLTHROUGH to remove the attribute */
+
+		case ENODATA:
+		    /* no attribute of this name */
+		    ret = removexattr((char*)to_file, name);
+		    if (ret < 0 && errno != ENODATA)
+		    {
+			MSG_PUTS(_("Could not remove security context "));
+			MSG_PUTS(name);
+			MSG_PUTS(_(" for "));
+			msg_outtrans(to_file);
+			msg_putchar('\n');
+		    }
+		    break;
+	    }
+	}
+    }
+}
+#endif /* HAVE_SMACK */
+
 /*
  * Return a pointer to the ACL of file "fname" in allocated memory.
  * Return NULL if the ACL is not available for whatever reason.
--- a/src/undo.c
+++ b/src/undo.c
@@ -1455,7 +1455,7 @@ u_write_undo(name, forceit, buf, hash)
 # endif
        )
 	mch_setperm(file_name, (perm & 0707) | ((perm & 07) << 3));
-# ifdef HAVE_SELINUX
+# if defined(HAVE_SELINUX) || defined(HAVE_SMACK)
     if (buf->b_ffname != NULL)
 	mch_copy_sec(buf->b_ffname, file_name);
 # endif
--- a/src/version.c
+++ b/src/version.c
@@ -735,6 +735,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    238,
+/**/
     237,
 /**/
     236,