* [PATCH] SELinux support @ 2010-03-02 19:36 Karel Klic 2010-03-17 2:18 ` Glenn Morris 0 siblings, 1 reply; 13+ messages in thread From: Karel Klic @ 2010-03-02 19:36 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1065 bytes --] Hi, I have created patches that add basic SELinux support into Emacs. Currently, if you have SELinux enabled, and you edit a file and then store it, the backup file (with the tilde) gets the proper SELinux context but the real file loses it. That is caused by "backup by renaming". If you set "backup-by-copying" variable to non-nil, the file you edited preserves the correct context after saving, but the backup file gets the default context (it should get the context of the original file). This causes a lot of problems when editing config files on machines with SELinux enabled. The attached patches modify Emacs so that it preserves SELinux context of edited files. - emacs-1-selinux-config changes the build system to support libselinux - emacs-2-selinux-get-set-context-fun adds two new functions file-selinux-context and set-file-selinux-context - emacs-3-selinux-backups-on-save modifies the buffer saving functions to handle SELinux context The patch can be applied against a recent version of the repository. Best regards, Karel Klic [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: emacs-1-selinux-config.patch --] [-- Type: text/x-patch; name="emacs-1-selinux-config.patch", Size: 4611 bytes --] diff -U0 emacs-23.1.92/ChangeLog.selinux-config emacs-23.1.92/ChangeLog --- emacs-23.1.92/ChangeLog.selinux-config 2010-02-23 17:09:23.230149718 +0100 +++ emacs-23.1.92/ChangeLog 2010-02-23 17:12:42.016030415 +0100 @@ -0,0 +1,5 @@ +2010-02-23 Karel Klíč <kklic@redhat.com> + + * configure.in: New option: --with(out)-selinux. + Set HAVE_LIBSELINUX if we find libselinux. + diff -up emacs-23.1.92/configure.in.selinux-config emacs-23.1.92/configure.in --- emacs-23.1.92/configure.in.selinux-config 2010-01-30 02:48:36.000000000 +0100 +++ emacs-23.1.92/configure.in 2010-02-23 16:27:35.402024775 +0100 @@ -145,6 +145,7 @@ OPTION_DEFAULT_OFF([ns],[use nextstep (C OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console]) OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support]) OPTION_DEFAULT_ON([gconf],[don't compile with GConf support]) +OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support]) ## For the times when you want to build Emacs but don't have ## a suitable makeinfo, and can live without the manuals. @@ -1763,6 +1764,15 @@ if test "${HAVE_X11}" = "yes" && test "$ fi fi +dnl SELinux is available for GNU/Linux only. +HAVE_LIBSELINUX=no +if test "${with_selinux}" = "yes"; then + PKG_CHECK_MODULES(LIBSELINUX, libselinux, HAVE_LIBSELINUX=yes, HAVE_LIBSELINUX=no) + if test "$HAVE_LIBSELINUX" = yes; then + AC_DEFINE(HAVE_LIBSELINUX, 1, [Define to 1 if using SELinux.]) + fi +fi + dnl Do not put whitespace before the #include statements below. dnl Older compilers (eg sunos4 cc) choke on it. HAVE_XAW3D=no @@ -3015,6 +3025,7 @@ echo " Does Emacs use -lrsvg-2? echo " Does Emacs use -lgpm? ${HAVE_GPM}" echo " Does Emacs use -ldbus? ${HAVE_DBUS}" echo " Does Emacs use -lgconf? ${HAVE_GCONF}" +echo " Does Emacs use -lselinux? ${HAVE_LIBSELINUX}" echo " Does Emacs use -lfreetype? ${HAVE_FREETYPE}" echo " Does Emacs use -lm17n-flt? ${HAVE_M17N_FLT}" diff -U0 emacs-23.1.92/src/ChangeLog.selinux-config emacs-23.1.92/src/ChangeLog --- emacs-23.1.92/src/ChangeLog.selinux-config 2010-02-23 16:54:05.815149660 +0100 +++ emacs-23.1.92/src/ChangeLog 2010-02-23 17:08:32.077024278 +0100 @@ -0,0 +1,4 @@ +2010-02-23 Karel Klíč <kklic@redhat.com> + + * Makefile.in: Added libselinux CFLAGS and LIBS. + diff -up emacs-23.1.92/src/Makefile.in.selinux-config emacs-23.1.92/src/Makefile.in --- emacs-23.1.92/src/Makefile.in.selinux-config 2010-01-16 18:35:57.000000000 +0100 +++ emacs-23.1.92/src/Makefile.in 2010-02-23 16:27:35.403024401 +0100 @@ -253,6 +253,11 @@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ #endif +#ifdef HAVE_LIBSELINUX +LIBSELINUX_CFLAGS = @LIBSELINUX_CFLAGS@ +LIBSELINUX_LIBS = @LIBSELINUX_LIBS@ +#endif + /* DO NOT use -R. There is a special hack described in lastfile.c which is used instead. Some initialized data areas are modified at initial startup, then labeled as part of the text area when @@ -266,7 +271,7 @@ GCONF_LIBS = @GCONF_LIBS@ /* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM since it may have -I options that should override those two. */ -ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${GCONF_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ${DEPFLAGS} +ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${GCONF_CFLAGS} ${LIBSELINUX_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ${DEPFLAGS} ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@ .SUFFIXES: .m @@ -911,7 +916,7 @@ SOME_MACHINE_LISP = ../lisp/mouse.elc \ LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) $(DBUS_LIBS) \ LIBGPM LIBRESOLV LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \ - LIBS_DEBUG $(GETLOADAVG_LIBS) ${GCONF_LIBS} \ + LIBS_DEBUG $(GETLOADAVG_LIBS) ${GCONF_LIBS} ${LIBSELINUX_LIBS} \ @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@ @M17N_FLT_LIBS@ \ $(GNULIB_VAR) LIB_MATH LIB_STANDARD $(GNULIB_VAR) [-- Attachment #3: emacs-2-selinux-get-set-context-fun.patch --] [-- Type: text/x-patch, Size: 6554 bytes --] diff -U0 emacs-23.1.92/src/ChangeLog.selinux-get-set-context-fun emacs-23.1.92/src/ChangeLog --- emacs-23.1.92/src/ChangeLog.selinux-get-set-context-fun 2010-02-23 17:20:22.866024852 +0100 +++ emacs-23.1.92/src/ChangeLog 2010-02-23 17:22:35.408149531 +0100 @@ -2,0 +3,3 @@ + * fileio.c (Ffile_selinux_context): New function. + (Fset_file_selinux_context): New function. + diff -up emacs-23.1.92/src/fileio.c.selinux-get-set-context-fun emacs-23.1.92/src/fileio.c --- emacs-23.1.92/src/fileio.c.selinux-get-set-context-fun 2010-01-28 18:45:49.000000000 +0100 +++ emacs-23.1.92/src/fileio.c 2010-02-23 16:27:53.899149817 +0100 @@ -59,6 +59,11 @@ extern int errno; #endif #endif +#ifdef HAVE_LIBSELINUX +#include <selinux/selinux.h> +#include <selinux/context.h> +#endif + #include "lisp.h" #include "intervals.h" #include "buffer.h" @@ -339,6 +344,8 @@ Lisp_Object Qfile_accessible_directory_p Lisp_Object Qfile_modes; Lisp_Object Qset_file_modes; Lisp_Object Qset_file_times; +Lisp_Object Qfile_selinux_context; +Lisp_Object Qset_file_selinux_context; Lisp_Object Qfile_newer_than_file_p; Lisp_Object Qinsert_file_contents; Lisp_Object Qwrite_region; @@ -2857,6 +2864,136 @@ See `file-symlink-p' to distinguish syml #endif } \f +DEFUN ("file-selinux-context", Ffile_selinux_context, + Sfile_selinux_context, 1, 1, 0, + doc: /* Return SELinux context of file named FILENAME, +as a list ("user", "role", "type", "range"). Return (nil, nil, nil, nil) +if file does not exist, is not accessible, or SELinux is disabled */) + (filename) + Lisp_Object filename; +{ + Lisp_Object absname; + Lisp_Object values[4]; + Lisp_Object handler; +#if HAVE_LIBSELINUX + security_context_t con; + int conlength; + context_t context; +#endif + + absname = expand_and_dir_to_file (filename, current_buffer->directory); + + /* If the file name has special constructs in it, + call the corresponding file handler. */ + handler = Ffind_file_name_handler (absname, Qfile_selinux_context); + if (!NILP (handler)) + return call2 (handler, Qfile_selinux_context, absname); + + absname = ENCODE_FILE (absname); + + values[0] = Qnil; + values[1] = Qnil; + values[2] = Qnil; + values[3] = Qnil; +#if HAVE_LIBSELINUX + if (is_selinux_enabled ()) + { + conlength = lgetfilecon (SDATA (absname), &con); + if (conlength > 0) + { + context = context_new (con); + values[0] = build_string (context_user_get (context)); + values[1] = build_string (context_role_get (context)); + values[2] = build_string (context_type_get (context)); + values[3] = build_string (context_range_get (context)); + context_free (context); + } + if (con) + freecon (con); + } +#endif + + return Flist (sizeof(values) / sizeof(values[0]), values); +} +\f +DEFUN ("set-file-selinux-context", Fset_file_selinux_context, + Sset_file_selinux_context, 2, 2, 0, + doc: /* Set SELinux context of file named FILENAME to CONTEXT +as a list ("user", "role", "type", "range"). Has no effect if SELinux +is disabled. */) + (filename, context) + Lisp_Object filename, context; +{ + Lisp_Object absname, encoded_absname; + Lisp_Object handler; + Lisp_Object user = CAR_SAFE (context); + Lisp_Object role = CAR_SAFE (CDR_SAFE (context)); + Lisp_Object type = CAR_SAFE (CDR_SAFE (CDR_SAFE (context))); + Lisp_Object range = CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (context)))); +#if HAVE_LIBSELINUX + security_context_t con; + int fail, conlength; + context_t parsed_con; +#endif + + absname = Fexpand_file_name (filename, current_buffer->directory); + + /* If the file name has special constructs in it, + call the corresponding file handler. */ + handler = Ffind_file_name_handler (absname, Qset_file_selinux_context); + if (!NILP (handler)) + return call3 (handler, Qset_file_selinux_context, absname, context); + + encoded_absname = ENCODE_FILE (absname); + +#if HAVE_LIBSELINUX + if (is_selinux_enabled ()) + { + /* Get current file context. */ + conlength = lgetfilecon (SDATA (encoded_absname), &con); + if (conlength > 0) + { + parsed_con = context_new (con); + /* Change the parts defined in the parameter.*/ + if (STRINGP (user)) + { + if (context_user_set (parsed_con, SDATA (user))) + error ("Doing context_user_set"); + } + if (STRINGP (role)) + { + if (context_role_set (parsed_con, SDATA (role))) + error ("Doing context_role_set"); + } + if (STRINGP (type)) + { + if (context_type_set (parsed_con, SDATA (type))) + error ("Doing context_type_set"); + } + if (STRINGP (range)) + { + if (context_range_set (parsed_con, SDATA (range))) + error ("Doing context_range_set"); + } + + /* Set the modified context back to the file. */ + fail = lsetfilecon (SDATA (encoded_absname), context_str (parsed_con)); + if (fail) + report_file_error ("Doing lsetfilecon", Fcons (absname, Qnil)); + + context_free (parsed_con); + } + else + report_file_error("Doing lgetfilecon", Fcons (absname, Qnil)); + + if (con) + freecon (con); + } +#endif + + return Qnil; +} +\f DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0, doc: /* Return mode bits of file named FILENAME, as an integer. Return nil, if file does not exist or is not accessible. */) @@ -5509,6 +5646,8 @@ syms_of_fileio () Qfile_modes = intern_c_string ("file-modes"); Qset_file_modes = intern_c_string ("set-file-modes"); Qset_file_times = intern_c_string ("set-file-times"); + Qfile_selinux_context = intern_c_string("file-selinux-context"); + Qset_file_selinux_context = intern_c_string("set-file-selinux-context"); Qfile_newer_than_file_p = intern_c_string ("file-newer-than-file-p"); Qinsert_file_contents = intern_c_string ("insert-file-contents"); Qwrite_region = intern_c_string ("write-region"); @@ -5544,6 +5683,8 @@ syms_of_fileio () staticpro (&Qfile_modes); staticpro (&Qset_file_modes); staticpro (&Qset_file_times); + staticpro (&Qfile_selinux_context); + staticpro (&Qset_file_selinux_context); staticpro (&Qfile_newer_than_file_p); staticpro (&Qinsert_file_contents); staticpro (&Qwrite_region); @@ -5777,6 +5918,8 @@ When non-nil, the function `move-file-to defsubr (&Sfile_modes); defsubr (&Sset_file_modes); defsubr (&Sset_file_times); + defsubr (&Sfile_selinux_context); + defsubr (&Sset_file_selinux_context); defsubr (&Sset_default_file_modes); defsubr (&Sdefault_file_modes); defsubr (&Sfile_newer_than_file_p); [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: emacs-3-selinux-backups-on-save.patch --] [-- Type: text/x-patch; name="emacs-3-selinux-backups-on-save.patch", Size: 7132 bytes --] diff -U0 emacs-23.1.92/lisp/ChangeLog.selinux-backups-on-save emacs-23.1.92/lisp/ChangeLog --- emacs-23.1.92/lisp/ChangeLog.selinux-backups-on-save 2010-02-24 11:22:02.961149752 +0100 +++ emacs-23.1.92/lisp/ChangeLog 2010-02-24 11:34:23.555149599 +0100 @@ -0,0 +1,9 @@ +2010-02-24 Karel Klíč <kklic@redhat.com> + + * files.el (backup-buffer): Handle SELinux context, and return it + if a backup was made by renaming. + (backup-buffer-copy): Set SELinux context to the target file. + (basic-save-buffer): Set SELinux context of the newly written file. + (basic-save-buffer-1): Mention it also returns SELinux context. + (basic-save-buffer-2): Set SELinux context of the newly created file. + diff -up emacs-23.1.92/lisp/files.el.selinux-backups-on-save emacs-23.1.92/lisp/files.el --- emacs-23.1.92/lisp/files.el.selinux-backups-on-save 2010-01-27 04:35:37.000000000 +0100 +++ emacs-23.1.92/lisp/files.el 2010-02-23 16:35:56.598149543 +0100 @@ -3616,10 +3616,13 @@ variable `make-backup-files'. If it's d no longer accessible under its old name. The value is non-nil after a backup was made by renaming. -It has the form (MODES . BACKUPNAME). +It has the form (MODES SELINUXCONTEXT BACKUPNAME). MODES is the result of `file-modes' on the original file; this means that the caller, after saving the buffer, should change the modes of the new file to agree with the old modes. +SELINUXCONTEXT is the result of `file-selinux-context' on the original +file; this means that the caller, after saving the buffer, should change +the SELinux context of the new file to agree with the old context. BACKUPNAME is the backup file name, which is the old file renamed." (if (and make-backup-files (not backup-inhibited) (not buffer-backed-up) @@ -3647,7 +3650,8 @@ BACKUPNAME is the backup file name, whic (or delete-old-versions (y-or-n-p (format "Delete excess backup versions of %s? " real-file-name))))) - (modes (file-modes buffer-file-name))) + (modes (file-modes buffer-file-name)) + (context (file-selinux-context buffer-file-name))) ;; Actually write the back up file. (condition-case () (if (or file-precious-flag @@ -3667,10 +3671,10 @@ BACKUPNAME is the backup file name, whic (<= (nth 2 attr) backup-by-copying-when-privileged-mismatch))) (or (nth 9 attr) (not (file-ownership-preserved-p real-file-name))))))) - (backup-buffer-copy real-file-name backupname modes) + (backup-buffer-copy real-file-name backupname modes context) ;; rename-file should delete old backup. (rename-file real-file-name backupname t) - (setq setmodes (cons modes backupname))) + (setq setmodes (list modes context backupname))) (file-error ;; If trouble writing the backup, write it in ~. (setq backupname (expand-file-name @@ -3679,7 +3683,7 @@ BACKUPNAME is the backup file name, whic (message "Cannot write backup file; backing up in %s" backupname) (sleep-for 1) - (backup-buffer-copy real-file-name backupname modes))) + (backup-buffer-copy real-file-name backupname modes context))) (setq buffer-backed-up t) ;; Now delete the old versions, if desired. (if delete-old-versions @@ -3691,7 +3695,7 @@ BACKUPNAME is the backup file name, whic setmodes) (file-error nil)))))) -(defun backup-buffer-copy (from-name to-name modes) +(defun backup-buffer-copy (from-name to-name modes context) (let ((umask (default-file-modes))) (unwind-protect (progn @@ -3718,7 +3722,9 @@ BACKUPNAME is the backup file name, whic ;; Reset the umask. (set-default-file-modes umask))) (and modes - (set-file-modes to-name (logand modes #o1777)))) + (set-file-modes to-name (logand modes #o1777))) + (and context + (set-file-selinux-context to-name context))) (defun file-name-sans-versions (name &optional keep-backup-version) "Return file NAME sans backup versions or strings. @@ -4248,7 +4254,9 @@ Before and after saving the buffer, this (nthcdr 10 (file-attributes buffer-file-name))) (if setmodes (condition-case () - (set-file-modes buffer-file-name (car setmodes)) + (progn + (set-file-modes buffer-file-name (car setmodes)) + (set-file-selinux-context buffer-file-name (nth 1 setmodes))) (error nil)))) ;; If the auto-save file was recent before this command, ;; delete it now. @@ -4261,7 +4269,7 @@ Before and after saving the buffer, this ;; This does the "real job" of writing a buffer into its visited file ;; and making a backup file. This is what is normally done ;; but inhibited if one of write-file-functions returns non-nil. -;; It returns a value (MODES . BACKUPNAME), like backup-buffer. +;; It returns a value (MODES SELINUXCONTEXT BACKUPNAME), like backup-buffer. (defun basic-save-buffer-1 () (prog1 (if save-buffer-coding-system @@ -4273,7 +4281,7 @@ Before and after saving the buffer, this (setq buffer-file-coding-system-explicit (cons last-coding-system-used nil))))) -;; This returns a value (MODES . BACKUPNAME), like backup-buffer. +;; This returns a value (MODES SELINUXCONTEXT BACKUPNAME), like backup-buffer. (defun basic-save-buffer-2 () (let (tempsetmodes setmodes) (if (not (file-writable-p buffer-file-name)) @@ -4344,8 +4352,9 @@ Before and after saving the buffer, this ;; Since we have created an entirely new file, ;; make sure it gets the right permission bits set. (setq setmodes (or setmodes - (cons (or (file-modes buffer-file-name) + (list (or (file-modes buffer-file-name) (logand ?\666 umask)) + (file-selinux-context buffer-file-name) buffer-file-name))) ;; We succeeded in writing the temp file, ;; so rename it. @@ -4356,8 +4365,11 @@ Before and after saving the buffer, this ;; (setmodes is set) because that says we're superseding. (cond ((and tempsetmodes (not setmodes)) ;; Change the mode back, after writing. - (setq setmodes (cons (file-modes buffer-file-name) buffer-file-name)) - (set-file-modes buffer-file-name (logior (car setmodes) 128)))) + (setq setmodes (list (file-modes buffer-file-name) + (file-selinux-context buffer-file-name) + buffer-file-name)) + (set-file-modes buffer-file-name (logior (car setmodes) 128)) + (set-file-selinux-context buffer-file-name (nth 1 setmodes))))) (let (success) (unwind-protect (progn @@ -4371,8 +4383,8 @@ Before and after saving the buffer, this ;; the backup by renaming, undo the backing-up. (and setmodes (not success) (progn - (rename-file (cdr setmodes) buffer-file-name t) - (setq buffer-backed-up nil))))))) + (rename-file (nth 2 setmodes) buffer-file-name t) + (setq buffer-backed-up nil)))))) setmodes)) (defun diff-buffer-with-file (&optional buffer) ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-03-02 19:36 [PATCH] SELinux support Karel Klic @ 2010-03-17 2:18 ` Glenn Morris 2010-03-18 0:10 ` Glenn Morris 0 siblings, 1 reply; 13+ messages in thread From: Glenn Morris @ 2010-03-17 2:18 UTC (permalink / raw) To: emacs-devel; +Cc: Karel Klic Karel Klic wrote: > I have created patches that add basic SELinux support into Emacs. This seems like a thorough patch, has anyone tried it out? All I can say is that it seems to work fine on a non-SELinux enabled system, ie doesn't break anything. :) On RHEL5.4, I have both libselinux and libselinux-devel installed, but SELinux is deactivated. However, nothing seems to provide a pkg-config file libselinux.pc, so the configure test fails to even find SELinux. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-03-17 2:18 ` Glenn Morris @ 2010-03-18 0:10 ` Glenn Morris 2010-03-18 13:33 ` Karel Klic 0 siblings, 1 reply; 13+ messages in thread From: Glenn Morris @ 2010-03-18 0:10 UTC (permalink / raw) To: Karel Klic; +Cc: emacs-devel I tried it on a (virtual) Fedora 12 installation, and it doesn't seem to work. file-selinux-context always returns nil. (Disclaimer: I know nothing about SELinux.) /usr/sbin/getenforce -> Enforcing checking for libselinux... yes checking LIBSELINUX_LIBS... -lselinux Does Emacs use -lselinux? yes ldd emacs | grep selinux -> libselinux.so.1 => /lib64/libselinux.so.1 ls -l --context /etc/printcap -rw-r--r--. root root system_u:object_r:cupsd_rw_etc_t:s0 /etc/printcap (file-selinux-context "/etc/printcap") -> (nil nil nil nil) ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-03-18 0:10 ` Glenn Morris @ 2010-03-18 13:33 ` Karel Klic 2010-03-19 2:46 ` Glenn Morris 0 siblings, 1 reply; 13+ messages in thread From: Karel Klic @ 2010-03-18 13:33 UTC (permalink / raw) To: Glenn Morris; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1579 bytes --] Hi Glenn, On 03/18/2010 01:10 AM, Glenn Morris wrote: > > I tried it on a (virtual) Fedora 12 installation, and it doesn't seem > to work. file-selinux-context always returns nil. (Disclaimer: I know > nothing about SELinux.) > > /usr/sbin/getenforce -> Enforcing > > checking for libselinux... yes > checking LIBSELINUX_LIBS... -lselinux > Does Emacs use -lselinux? yes > > ldd emacs | grep selinux -> libselinux.so.1 => /lib64/libselinux.so.1 > > ls -l --context /etc/printcap > -rw-r--r--. root root system_u:object_r:cupsd_rw_etc_t:s0 /etc/printcap > > (file-selinux-context "/etc/printcap") -> (nil nil nil nil) That is strange, it works well here on Fedora 12. The only difference is in i686 / x86_64 architecture. I'll try x86_64 tomorrow. I just modified emacs-1-selinux-config.patch (attached) to apply cleanly on the most recent bzr. Here is my story: $ getenforce Enforcing $ bzr clone http://bzr.savannah.gnu.org/r/emacs/trunk/ emacs-bzr-cur $ cd emacs-bzr-cur $ patch -p1 -b -z .selinux-config <emacs-1-selinux-config.patch $ patch -p1 -b -z .selinux-get-set-context-fun <emacs-2-selinux-get-set-context-fun.patch $ patch -p1 -b -z .selinux-backups-on-save <emacs-3-selinux-backups-on-save.patch $ autoreconf $ ./configure Does Emacs use -lselinux? yes $ make $ cd src $ ldd ./emacs | grep selinux libselinux.so.1 => /lib/libselinux.so.1 (0x0061e000) $ ./emacs --batch --eval "(prin1 (file-selinux-context \"/etc/printcap\"))" ("system_u" "object_r" "cupsd_rw_etc_t" "s0") Karel [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: emacs-1-selinux-config.patch --] [-- Type: text/x-patch; name="emacs-1-selinux-config.patch", Size: 4423 bytes --] diff -U0 ./ChangeLog.selinux-config ./ChangeLog --- ./ChangeLog.selinux-config 2010-03-18 11:58:51.539761413 +0100 +++ ./ChangeLog 2010-03-18 12:01:16.057886634 +0100 @@ -0,0 +1,5 @@ +2010-02-23 Karel Klíč <kklic@redhat.com> + + * configure.in: New option: --with(out)-selinux. + Set HAVE_LIBSELINUX if we find libselinux. + diff -up ./configure.in.selinux-config ./configure.in --- ./configure.in.selinux-config 2010-03-18 11:58:51.770761262 +0100 +++ ./configure.in 2010-03-18 12:01:16.058886899 +0100 @@ -161,6 +161,7 @@ OPTION_DEFAULT_OFF([ns],[use nextstep (C OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console]) OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support]) OPTION_DEFAULT_ON([gconf],[don't compile with GConf support]) +OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support]) ## For the times when you want to build Emacs but don't have ## a suitable makeinfo, and can live without the manuals. @@ -1779,6 +1780,15 @@ if test "${HAVE_X11}" = "yes" && test "$ fi fi +dnl SELinux is available for GNU/Linux only. +HAVE_LIBSELINUX=no +if test "${with_selinux}" = "yes"; then + PKG_CHECK_MODULES(LIBSELINUX, libselinux, HAVE_LIBSELINUX=yes, HAVE_LIBSELINUX=no) + if test "$HAVE_LIBSELINUX" = yes; then + AC_DEFINE(HAVE_LIBSELINUX, 1, [Define to 1 if using SELinux.]) + fi +fi + dnl Do not put whitespace before the #include statements below. dnl Older compilers (eg sunos4 cc) choke on it. HAVE_XAW3D=no @@ -3121,6 +3131,7 @@ echo " Does Emacs use -lrsvg-2? echo " Does Emacs use -lgpm? ${HAVE_GPM}" echo " Does Emacs use -ldbus? ${HAVE_DBUS}" echo " Does Emacs use -lgconf? ${HAVE_GCONF}" +echo " Does Emacs use -lselinux? ${HAVE_LIBSELINUX}" echo " Does Emacs use -lfreetype? ${HAVE_FREETYPE}" echo " Does Emacs use -lm17n-flt? ${HAVE_M17N_FLT}" diff -U0 ./src/ChangeLog.selinux-config ./src/ChangeLog --- ./src/ChangeLog.selinux-config 2010-03-18 11:58:51.528762063 +0100 +++ ./src/ChangeLog 2010-03-18 12:01:16.065886521 +0100 @@ -0,0 +1,4 @@ +2010-02-23 Karel Klíč <kklic@redhat.com> + + * Makefile.in: Added libselinux CFLAGS and LIBS. + diff -up ./src/Makefile.in.selinux-config ./src/Makefile.in --- ./src/Makefile.in.selinux-config 2010-03-18 11:58:52.578886447 +0100 +++ ./src/Makefile.in 2010-03-18 12:02:23.359767558 +0100 @@ -253,6 +253,11 @@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ #endif +#ifdef HAVE_LIBSELINUX +LIBSELINUX_CFLAGS = @LIBSELINUX_CFLAGS@ +LIBSELINUX_LIBS = @LIBSELINUX_LIBS@ +#endif + /* DO NOT use -R. There is a special hack described in lastfile.c which is used instead. Some initialized data areas are modified at initial startup, then labeled as part of the text area when @@ -266,7 +271,7 @@ GCONF_LIBS = @GCONF_LIBS@ /* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM since it may have -I options that should override those two. */ -ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${GCONF_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ${DEPFLAGS} +ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${GCONF_CFLAGS} ${LIBSELINUX_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ${DEPFLAGS} ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@ .SUFFIXES: .m @@ -849,7 +854,7 @@ SOME_MACHINE_LISP = ../lisp/mouse.elc \ LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) $(DBUS_LIBS) \ @LIBGPM@ @LIBRESOLV@ LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \ - LIBS_DEBUG $(GETLOADAVG_LIBS) ${GCONF_LIBS} \ + LIBS_DEBUG $(GETLOADAVG_LIBS) ${GCONF_LIBS} ${LIBSELINUX_LIBS} \ @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@ @M17N_FLT_LIBS@ \ $(GNULIB_VAR) LIB_MATH LIB_STANDARD $(GNULIB_VAR) ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-03-18 13:33 ` Karel Klic @ 2010-03-19 2:46 ` Glenn Morris 2010-03-22 14:53 ` Karel Klic 2010-03-29 13:53 ` Karel Klic 0 siblings, 2 replies; 13+ messages in thread From: Glenn Morris @ 2010-03-19 2:46 UTC (permalink / raw) To: Karel Klic; +Cc: emacs-devel Ack, sorry, I forgot to run autoheader. It works fine. This looks like a good patch to me. If no-one else comments in a week or so, I suggest we just get on with it. Some comments: It would need some copyright paperwork before we could install it. With regards to RHEL apparently not providing a libselinux.pc file, maybe the configure.in stuff could be changed to use AC_CHECK_LIB instead of PKG_CHECK_MODULES? It seems that -lselinux is all that is needed (?). It might be nice to extend copy-file to optionally preserve the context as well. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-03-19 2:46 ` Glenn Morris @ 2010-03-22 14:53 ` Karel Klic 2010-03-22 16:01 ` Tom Tromey 2010-03-29 13:53 ` Karel Klic 1 sibling, 1 reply; 13+ messages in thread From: Karel Klic @ 2010-03-22 14:53 UTC (permalink / raw) To: Glenn Morris; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 715 bytes --] Hi Glenn, On 03/19/2010 03:46 AM, Glenn Morris wrote: > Some comments: > > It would need some copyright paperwork before we could install it. I'm sending the copyright assignment paper to the FSF today. > > With regards to RHEL apparently not providing a libselinux.pc > file, maybe the configure.in stuff could be changed to use > AC_CHECK_LIB instead of PKG_CHECK_MODULES? It seems that > -lselinux is all that is needed (?). Agreed. The emacs-1-* attached patch now uses AC_CHECK_LIB. -lselinux should suffice. > > It might be nice to extend copy-file to optionally preserve the > context as well. Agreed. The emacs-2-* attached patch now extends the copy-file function. Thank you for the suggestions. Karel [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: emacs-1-selinux-config.patch --] [-- Type: text/x-patch; name="emacs-1-selinux-config.patch", Size: 4627 bytes --] diff -U0 emacs-bzr-cur/ChangeLog.selinux-config emacs-bzr-cur/ChangeLog --- emacs-bzr-cur/ChangeLog.selinux-config 2010-03-22 11:14:54.197886373 +0100 +++ emacs-bzr-cur/ChangeLog 2010-03-22 11:17:27.282886847 +0100 @@ -0,0 +1,5 @@ +2010-02-23 Karel Klíč <kklic@redhat.com> + + * configure.in: New option: --with(out)-selinux. + Set HAVE_LIBSELINUX if we find libselinux. + diff -up emacs-bzr-cur/configure.in.selinux-config emacs-bzr-cur/configure.in --- emacs-bzr-cur/configure.in.selinux-config 2010-03-22 11:14:54.435886553 +0100 +++ emacs-bzr-cur/configure.in 2010-03-22 11:27:57.131766948 +0100 @@ -161,6 +161,7 @@ OPTION_DEFAULT_OFF([ns],[use nextstep (C OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console]) OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support]) OPTION_DEFAULT_ON([gconf],[don't compile with GConf support]) +OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support]) ## For the times when you want to build Emacs but don't have ## a suitable makeinfo, and can live without the manuals. @@ -1738,6 +1739,17 @@ if test "${HAVE_X11}" = "yes" && test "$ fi fi +dnl SELinux is available for GNU/Linux only. +HAVE_LIBSELINUX=no +if test "${with_selinux}" = "yes"; then + AC_CHECK_LIB([selinux], [lgetfilecon], HAVE_LIBSELINUX=yes, HAVE_LIBSELINUX=no) + if test "$HAVE_LIBSELINUX" = yes; then + AC_DEFINE(HAVE_LIBSELINUX, 1, [Define to 1 if using SELinux.]) + LIBSELINUX_LIBS=-lselinux + AC_SUBST(LIBSELINUX_LIBS) + fi +fi + dnl Do not put whitespace before the #include statements below. dnl Older compilers (eg sunos4 cc) choke on it. HAVE_XAW3D=no @@ -3090,6 +3102,7 @@ echo " Does Emacs use -lrsvg-2? echo " Does Emacs use -lgpm? ${HAVE_GPM}" echo " Does Emacs use -ldbus? ${HAVE_DBUS}" echo " Does Emacs use -lgconf? ${HAVE_GCONF}" +echo " Does Emacs use -lselinux? ${HAVE_LIBSELINUX}" echo " Does Emacs use -lfreetype? ${HAVE_FREETYPE}" echo " Does Emacs use -lm17n-flt? ${HAVE_M17N_FLT}" diff -U0 emacs-bzr-cur/src/ChangeLog.selinux-config emacs-bzr-cur/src/ChangeLog --- emacs-bzr-cur/src/ChangeLog.selinux-config 2010-03-22 11:14:54.186886485 +0100 +++ emacs-bzr-cur/src/ChangeLog 2010-03-22 14:01:43.595886038 +0100 @@ -0,0 +1,4 @@ +2010-03-22 Karel Klíč <kklic@redhat.com> + + * Makefile.in: Added libselinux LIBS. + diff -up emacs-bzr-cur/src/Makefile.in.selinux-config emacs-bzr-cur/src/Makefile.in --- emacs-bzr-cur/src/Makefile.in.selinux-config 2010-03-22 11:14:55.288761407 +0100 +++ emacs-bzr-cur/src/Makefile.in 2010-03-22 11:28:30.212886766 +0100 @@ -254,6 +254,10 @@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ #endif +#ifdef HAVE_LIBSELINUX +LIBSELINUX_LIBS = @LIBSELINUX_LIBS@ +#endif + /* DO NOT use -R. There is a special hack described in lastfile.c which is used instead. Some initialized data areas are modified at initial startup, then labeled as part of the text area when @@ -267,7 +271,7 @@ GCONF_LIBS = @GCONF_LIBS@ /* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM since it may have -I options that should override those two. */ -ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${GCONF_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ${DEPFLAGS} +ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${GCONF_CFLAGS} ${LIBSELINUX_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ${DEPFLAGS} ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@ .SUFFIXES: .m @@ -850,7 +854,7 @@ SOME_MACHINE_LISP = ../lisp/mouse.elc \ LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) $(DBUS_LIBS) \ @LIBGPM@ @LIBRESOLV@ LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \ - LIBS_DEBUG $(GETLOADAVG_LIBS) ${GCONF_LIBS} \ + LIBS_DEBUG $(GETLOADAVG_LIBS) ${GCONF_LIBS} ${LIBSELINUX_LIBS} \ @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@ @M17N_FLT_LIBS@ \ $(GNULIB_VAR) LIB_MATH LIB_STANDARD $(GNULIB_VAR) [-- Attachment #3: emacs-2-selinux-context-fun.patch --] [-- Type: text/x-patch, Size: 12012 bytes --] diff -U0 emacs-bzr/src/ChangeLog.selinux-context-fun emacs-bzr/src/ChangeLog --- emacs-bzr/src/ChangeLog.selinux-context-fun 2010-03-22 14:30:57.235887665 +0100 +++ emacs-bzr/src/ChangeLog 2010-03-22 15:05:20.936885923 +0100 @@ -2,0 +3,8 @@ + * eval.c, lisp.h (call7): New function. + + * fileio.c (Ffile_selinux_context): New function. + (Fset_file_selinux_context): New function. + (Fcopy_file): New parameter preserve-selinux-context. + (Frename_file): Preserve selinux context when renaming + by copy-file. + diff -up emacs-bzr/src/eval.c.selinux-context-fun emacs-bzr/src/eval.c --- emacs-bzr/src/eval.c.selinux-context-fun 2010-03-22 14:41:29.485760685 +0100 +++ emacs-bzr/src/eval.c 2010-03-22 14:57:18.547767559 +0100 @@ -2930,6 +2930,33 @@ call6 (fn, arg1, arg2, arg3, arg4, arg5, #endif /* not NO_ARG_ARRAY */ } +/* Call function fn with 7 arguments arg1, arg2, arg3, arg4, arg5, arg6, arg7 */ +/* ARGSUSED */ +Lisp_Object +call7 (fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + Lisp_Object fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7; +{ + struct gcpro gcpro1; +#ifdef NO_ARG_ARRAY + Lisp_Object args[8]; + args[0] = fn; + args[1] = arg1; + args[2] = arg2; + args[3] = arg3; + args[4] = arg4; + args[5] = arg5; + args[6] = arg6; + args[7] = arg7; + GCPRO1 (args[0]); + gcpro1.nvars = 8; + RETURN_UNGCPRO (Ffuncall (8, args)); +#else /* not NO_ARG_ARRAY */ + GCPRO1 (fn); + gcpro1.nvars = 8; + RETURN_UNGCPRO (Ffuncall (8, &fn)); +#endif /* not NO_ARG_ARRAY */ +} + /* The caller should GCPRO all the elements of ARGS. */ DEFUN ("funcall", Ffuncall, Sfuncall, 1, MANY, 0, diff -up emacs-bzr/src/fileio.c.selinux-context-fun emacs-bzr/src/fileio.c --- emacs-bzr/src/fileio.c.selinux-context-fun 2010-03-22 14:23:18.370761463 +0100 +++ emacs-bzr/src/fileio.c 2010-03-22 15:51:00.238886093 +0100 @@ -59,6 +59,11 @@ extern int errno; #endif #endif +#ifdef HAVE_LIBSELINUX +#include <selinux/selinux.h> +#include <selinux/context.h> +#endif + #include "lisp.h" #include "intervals.h" #include "buffer.h" @@ -339,6 +344,8 @@ Lisp_Object Qfile_accessible_directory_p Lisp_Object Qfile_modes; Lisp_Object Qset_file_modes; Lisp_Object Qset_file_times; +Lisp_Object Qfile_selinux_context; +Lisp_Object Qset_file_selinux_context; Lisp_Object Qfile_newer_than_file_p; Lisp_Object Qinsert_file_contents; Lisp_Object Qwrite_region; @@ -1902,7 +1909,7 @@ barf_or_query_if_file_exists (absname, q return; } -DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 5, +DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 6, "fCopy file: \nGCopy %s to file: \np\nP", doc: /* Copy FILE to NEWNAME. Both args must be strings. If NEWNAME names a directory, copy FILE there. @@ -1924,10 +1931,13 @@ last-modified time as the old one. (Thi A prefix arg makes KEEP-TIME non-nil. If PRESERVE-UID-GID is non-nil, we try to transfer the -uid and gid of FILE to NEWNAME. */) - (file, newname, ok_if_already_exists, keep_time, preserve_uid_gid) +uid and gid of FILE to NEWNAME. + +If PRESERVE-SELINUX-CONTEXT is non-nil and SELinux is enabled +on the system, we copy the SELinux context of FILE to NEWNAME. */) + (file, newname, ok_if_already_exists, keep_time, preserve_uid_gid, preserve_selinux_context) Lisp_Object file, newname, ok_if_already_exists, keep_time; - Lisp_Object preserve_uid_gid; + Lisp_Object preserve_uid_gid, preserve_selinux_context; { int ifd, ofd, n; char buf[16 * 1024]; @@ -1937,6 +1947,10 @@ uid and gid of FILE to NEWNAME. */) int count = SPECPDL_INDEX (); int input_file_statable_p; Lisp_Object encoded_file, encoded_newname; +#if HAVE_LIBSELINUX + security_context_t con; + int fail, conlength = 0; +#endif encoded_file = encoded_newname = Qnil; GCPRO4 (file, newname, encoded_file, encoded_newname); @@ -1957,8 +1971,9 @@ uid and gid of FILE to NEWNAME. */) if (NILP (handler)) handler = Ffind_file_name_handler (newname, Qcopy_file); if (!NILP (handler)) - RETURN_UNGCPRO (call6 (handler, Qcopy_file, file, newname, - ok_if_already_exists, keep_time, preserve_uid_gid)); + RETURN_UNGCPRO (call7 (handler, Qcopy_file, file, newname, + ok_if_already_exists, keep_time, preserve_uid_gid, + preserve_selinux_context)); encoded_file = ENCODE_FILE (file); encoded_newname = ENCODE_FILE (newname); @@ -2012,6 +2027,15 @@ uid and gid of FILE to NEWNAME. */) copyable by us. */ input_file_statable_p = (fstat (ifd, &st) >= 0); +#if HAVE_LIBSELINUX + if (!NILP (preserve_selinux_context) && is_selinux_enabled ()) + { + conlength = fgetfilecon (ifd, &con); + if (conlength == -1) + report_file_error ("Doing fgetfilecon", Fcons (file, Qnil)); + } +#endif + #if !defined (MSDOS) || __DJGPP__ > 1 if (out_st.st_mode != 0 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino) @@ -2071,6 +2095,18 @@ uid and gid of FILE to NEWNAME. */) } #endif /* not MSDOS */ +#if HAVE_LIBSELINUX + if (conlength > 0) + { + /* Set the modified context back to the file. */ + fail = fsetfilecon (ofd, con); + if (fail) + report_file_error ("Doing fsetfilecon", Fcons (newname, Qnil)); + + freecon (con); + } +#endif + /* Closing the output clobbers the file times on some systems. */ if (emacs_close (ofd) < 0) report_file_error ("I/O error", Fcons (newname, Qnil)); @@ -2297,7 +2333,7 @@ This is what happens in interactive use have copy-file prompt again. */ Fcopy_file (file, newname, NILP (ok_if_already_exists) ? Qnil : Qt, - Qt, Qt); + Qt, Qt, Qt); count = SPECPDL_INDEX (); specbind (Qdelete_by_moving_to_trash, Qnil); @@ -2863,6 +2899,136 @@ See `file-symlink-p' to distinguish syml #endif } \f +DEFUN ("file-selinux-context", Ffile_selinux_context, + Sfile_selinux_context, 1, 1, 0, + doc: /* Return SELinux context of file named FILENAME, +as a list ("user", "role", "type", "range"). Return (nil, nil, nil, nil) +if file does not exist, is not accessible, or SELinux is disabled */) + (filename) + Lisp_Object filename; +{ + Lisp_Object absname; + Lisp_Object values[4]; + Lisp_Object handler; +#if HAVE_LIBSELINUX + security_context_t con; + int conlength; + context_t context; +#endif + + absname = expand_and_dir_to_file (filename, current_buffer->directory); + + /* If the file name has special constructs in it, + call the corresponding file handler. */ + handler = Ffind_file_name_handler (absname, Qfile_selinux_context); + if (!NILP (handler)) + return call2 (handler, Qfile_selinux_context, absname); + + absname = ENCODE_FILE (absname); + + values[0] = Qnil; + values[1] = Qnil; + values[2] = Qnil; + values[3] = Qnil; +#if HAVE_LIBSELINUX + if (is_selinux_enabled ()) + { + conlength = lgetfilecon (SDATA (absname), &con); + if (conlength > 0) + { + context = context_new (con); + values[0] = build_string (context_user_get (context)); + values[1] = build_string (context_role_get (context)); + values[2] = build_string (context_type_get (context)); + values[3] = build_string (context_range_get (context)); + context_free (context); + } + if (con) + freecon (con); + } +#endif + + return Flist (sizeof(values) / sizeof(values[0]), values); +} +\f +DEFUN ("set-file-selinux-context", Fset_file_selinux_context, + Sset_file_selinux_context, 2, 2, 0, + doc: /* Set SELinux context of file named FILENAME to CONTEXT +as a list ("user", "role", "type", "range"). Has no effect if SELinux +is disabled. */) + (filename, context) + Lisp_Object filename, context; +{ + Lisp_Object absname, encoded_absname; + Lisp_Object handler; + Lisp_Object user = CAR_SAFE (context); + Lisp_Object role = CAR_SAFE (CDR_SAFE (context)); + Lisp_Object type = CAR_SAFE (CDR_SAFE (CDR_SAFE (context))); + Lisp_Object range = CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (context)))); +#if HAVE_LIBSELINUX + security_context_t con; + int fail, conlength; + context_t parsed_con; +#endif + + absname = Fexpand_file_name (filename, current_buffer->directory); + + /* If the file name has special constructs in it, + call the corresponding file handler. */ + handler = Ffind_file_name_handler (absname, Qset_file_selinux_context); + if (!NILP (handler)) + return call3 (handler, Qset_file_selinux_context, absname, context); + + encoded_absname = ENCODE_FILE (absname); + +#if HAVE_LIBSELINUX + if (is_selinux_enabled ()) + { + /* Get current file context. */ + conlength = lgetfilecon (SDATA (encoded_absname), &con); + if (conlength > 0) + { + parsed_con = context_new (con); + /* Change the parts defined in the parameter.*/ + if (STRINGP (user)) + { + if (context_user_set (parsed_con, SDATA (user))) + error ("Doing context_user_set"); + } + if (STRINGP (role)) + { + if (context_role_set (parsed_con, SDATA (role))) + error ("Doing context_role_set"); + } + if (STRINGP (type)) + { + if (context_type_set (parsed_con, SDATA (type))) + error ("Doing context_type_set"); + } + if (STRINGP (range)) + { + if (context_range_set (parsed_con, SDATA (range))) + error ("Doing context_range_set"); + } + + /* Set the modified context back to the file. */ + fail = lsetfilecon (SDATA (encoded_absname), context_str (parsed_con)); + if (fail) + report_file_error ("Doing lsetfilecon", Fcons (absname, Qnil)); + + context_free (parsed_con); + } + else + report_file_error("Doing lgetfilecon", Fcons (absname, Qnil)); + + if (con) + freecon (con); + } +#endif + + return Qnil; +} +\f DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0, doc: /* Return mode bits of file named FILENAME, as an integer. Return nil, if file does not exist or is not accessible. */) @@ -5515,6 +5681,8 @@ syms_of_fileio () Qfile_modes = intern_c_string ("file-modes"); Qset_file_modes = intern_c_string ("set-file-modes"); Qset_file_times = intern_c_string ("set-file-times"); + Qfile_selinux_context = intern_c_string("file-selinux-context"); + Qset_file_selinux_context = intern_c_string("set-file-selinux-context"); Qfile_newer_than_file_p = intern_c_string ("file-newer-than-file-p"); Qinsert_file_contents = intern_c_string ("insert-file-contents"); Qwrite_region = intern_c_string ("write-region"); @@ -5550,6 +5718,8 @@ syms_of_fileio () staticpro (&Qfile_modes); staticpro (&Qset_file_modes); staticpro (&Qset_file_times); + staticpro (&Qfile_selinux_context); + staticpro (&Qset_file_selinux_context); staticpro (&Qfile_newer_than_file_p); staticpro (&Qinsert_file_contents); staticpro (&Qwrite_region); @@ -5783,6 +5953,8 @@ When non-nil, the function `move-file-to defsubr (&Sfile_modes); defsubr (&Sset_file_modes); defsubr (&Sset_file_times); + defsubr (&Sfile_selinux_context); + defsubr (&Sset_file_selinux_context); defsubr (&Sset_default_file_modes); defsubr (&Sdefault_file_modes); defsubr (&Sfile_newer_than_file_p); diff -up emacs-bzr/src/lisp.h.selinux-context-fun emacs-bzr/src/lisp.h --- emacs-bzr/src/lisp.h.selinux-context-fun 2010-03-22 14:43:16.637768779 +0100 +++ emacs-bzr/src/lisp.h 2010-03-22 14:39:25.416761387 +0100 @@ -2855,6 +2855,7 @@ extern Lisp_Object call3 P_ ((Lisp_Objec extern Lisp_Object call4 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)); extern Lisp_Object call5 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)); extern Lisp_Object call6 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)); +extern Lisp_Object call7 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)); EXFUN (Fdo_auto_save, 2); extern Lisp_Object apply_lambda P_ ((Lisp_Object, Lisp_Object, int)); extern Lisp_Object internal_catch P_ ((Lisp_Object, Lisp_Object (*) (Lisp_Object), Lisp_Object)); [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: emacs-3-selinux-backups-on-save.patch --] [-- Type: text/x-patch; name="emacs-3-selinux-backups-on-save.patch", Size: 7132 bytes --] diff -U0 emacs-23.1.92/lisp/ChangeLog.selinux-backups-on-save emacs-23.1.92/lisp/ChangeLog --- emacs-23.1.92/lisp/ChangeLog.selinux-backups-on-save 2010-02-24 11:22:02.961149752 +0100 +++ emacs-23.1.92/lisp/ChangeLog 2010-02-24 11:34:23.555149599 +0100 @@ -0,0 +1,9 @@ +2010-02-24 Karel Klíč <kklic@redhat.com> + + * files.el (backup-buffer): Handle SELinux context, and return it + if a backup was made by renaming. + (backup-buffer-copy): Set SELinux context to the target file. + (basic-save-buffer): Set SELinux context of the newly written file. + (basic-save-buffer-1): Mention it also returns SELinux context. + (basic-save-buffer-2): Set SELinux context of the newly created file. + diff -up emacs-23.1.92/lisp/files.el.selinux-backups-on-save emacs-23.1.92/lisp/files.el --- emacs-23.1.92/lisp/files.el.selinux-backups-on-save 2010-01-27 04:35:37.000000000 +0100 +++ emacs-23.1.92/lisp/files.el 2010-02-23 16:35:56.598149543 +0100 @@ -3616,10 +3616,13 @@ variable `make-backup-files'. If it's d no longer accessible under its old name. The value is non-nil after a backup was made by renaming. -It has the form (MODES . BACKUPNAME). +It has the form (MODES SELINUXCONTEXT BACKUPNAME). MODES is the result of `file-modes' on the original file; this means that the caller, after saving the buffer, should change the modes of the new file to agree with the old modes. +SELINUXCONTEXT is the result of `file-selinux-context' on the original +file; this means that the caller, after saving the buffer, should change +the SELinux context of the new file to agree with the old context. BACKUPNAME is the backup file name, which is the old file renamed." (if (and make-backup-files (not backup-inhibited) (not buffer-backed-up) @@ -3647,7 +3650,8 @@ BACKUPNAME is the backup file name, whic (or delete-old-versions (y-or-n-p (format "Delete excess backup versions of %s? " real-file-name))))) - (modes (file-modes buffer-file-name))) + (modes (file-modes buffer-file-name)) + (context (file-selinux-context buffer-file-name))) ;; Actually write the back up file. (condition-case () (if (or file-precious-flag @@ -3667,10 +3671,10 @@ BACKUPNAME is the backup file name, whic (<= (nth 2 attr) backup-by-copying-when-privileged-mismatch))) (or (nth 9 attr) (not (file-ownership-preserved-p real-file-name))))))) - (backup-buffer-copy real-file-name backupname modes) + (backup-buffer-copy real-file-name backupname modes context) ;; rename-file should delete old backup. (rename-file real-file-name backupname t) - (setq setmodes (cons modes backupname))) + (setq setmodes (list modes context backupname))) (file-error ;; If trouble writing the backup, write it in ~. (setq backupname (expand-file-name @@ -3679,7 +3683,7 @@ BACKUPNAME is the backup file name, whic (message "Cannot write backup file; backing up in %s" backupname) (sleep-for 1) - (backup-buffer-copy real-file-name backupname modes))) + (backup-buffer-copy real-file-name backupname modes context))) (setq buffer-backed-up t) ;; Now delete the old versions, if desired. (if delete-old-versions @@ -3691,7 +3695,7 @@ BACKUPNAME is the backup file name, whic setmodes) (file-error nil)))))) -(defun backup-buffer-copy (from-name to-name modes) +(defun backup-buffer-copy (from-name to-name modes context) (let ((umask (default-file-modes))) (unwind-protect (progn @@ -3718,7 +3722,9 @@ BACKUPNAME is the backup file name, whic ;; Reset the umask. (set-default-file-modes umask))) (and modes - (set-file-modes to-name (logand modes #o1777)))) + (set-file-modes to-name (logand modes #o1777))) + (and context + (set-file-selinux-context to-name context))) (defun file-name-sans-versions (name &optional keep-backup-version) "Return file NAME sans backup versions or strings. @@ -4248,7 +4254,9 @@ Before and after saving the buffer, this (nthcdr 10 (file-attributes buffer-file-name))) (if setmodes (condition-case () - (set-file-modes buffer-file-name (car setmodes)) + (progn + (set-file-modes buffer-file-name (car setmodes)) + (set-file-selinux-context buffer-file-name (nth 1 setmodes))) (error nil)))) ;; If the auto-save file was recent before this command, ;; delete it now. @@ -4261,7 +4269,7 @@ Before and after saving the buffer, this ;; This does the "real job" of writing a buffer into its visited file ;; and making a backup file. This is what is normally done ;; but inhibited if one of write-file-functions returns non-nil. -;; It returns a value (MODES . BACKUPNAME), like backup-buffer. +;; It returns a value (MODES SELINUXCONTEXT BACKUPNAME), like backup-buffer. (defun basic-save-buffer-1 () (prog1 (if save-buffer-coding-system @@ -4273,7 +4281,7 @@ Before and after saving the buffer, this (setq buffer-file-coding-system-explicit (cons last-coding-system-used nil))))) -;; This returns a value (MODES . BACKUPNAME), like backup-buffer. +;; This returns a value (MODES SELINUXCONTEXT BACKUPNAME), like backup-buffer. (defun basic-save-buffer-2 () (let (tempsetmodes setmodes) (if (not (file-writable-p buffer-file-name)) @@ -4344,8 +4352,9 @@ Before and after saving the buffer, this ;; Since we have created an entirely new file, ;; make sure it gets the right permission bits set. (setq setmodes (or setmodes - (cons (or (file-modes buffer-file-name) + (list (or (file-modes buffer-file-name) (logand ?\666 umask)) + (file-selinux-context buffer-file-name) buffer-file-name))) ;; We succeeded in writing the temp file, ;; so rename it. @@ -4356,8 +4365,11 @@ Before and after saving the buffer, this ;; (setmodes is set) because that says we're superseding. (cond ((and tempsetmodes (not setmodes)) ;; Change the mode back, after writing. - (setq setmodes (cons (file-modes buffer-file-name) buffer-file-name)) - (set-file-modes buffer-file-name (logior (car setmodes) 128)))) + (setq setmodes (list (file-modes buffer-file-name) + (file-selinux-context buffer-file-name) + buffer-file-name)) + (set-file-modes buffer-file-name (logior (car setmodes) 128)) + (set-file-selinux-context buffer-file-name (nth 1 setmodes))))) (let (success) (unwind-protect (progn @@ -4371,8 +4383,8 @@ Before and after saving the buffer, this ;; the backup by renaming, undo the backing-up. (and setmodes (not success) (progn - (rename-file (cdr setmodes) buffer-file-name t) - (setq buffer-backed-up nil))))))) + (rename-file (nth 2 setmodes) buffer-file-name t) + (setq buffer-backed-up nil)))))) setmodes)) (defun diff-buffer-with-file (&optional buffer) ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-03-22 14:53 ` Karel Klic @ 2010-03-22 16:01 ` Tom Tromey 2010-03-22 18:13 ` Glenn Morris 0 siblings, 1 reply; 13+ messages in thread From: Tom Tromey @ 2010-03-22 16:01 UTC (permalink / raw) To: Karel Klic; +Cc: emacs-devel >>>>> "Karel" == Karel Klic <kklic@redhat.com> writes: >> It would need some copyright paperwork before we could install it. Karel> I'm sending the copyright assignment paper to the FSF today. I think Red Hat has a blanket assignment with the FSF. Tom ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-03-22 16:01 ` Tom Tromey @ 2010-03-22 18:13 ` Glenn Morris 0 siblings, 0 replies; 13+ messages in thread From: Glenn Morris @ 2010-03-22 18:13 UTC (permalink / raw) To: Tom Tromey; +Cc: Karel Klic, emacs-devel Tom Tromey wrote: >>> It would need some copyright paperwork before we could install it. > > Karel> I'm sending the copyright assignment paper to the FSF today. > > I think Red Hat has a blanket assignment with the FSF. That's true, but AFAIK that just takes care of the bit on the assignment form that says "Do you have an employer who might have a basis to claim to own your changes"; it doesn't remove the need for individual authors to complete their own assignments. But I confess I don't really know, that's just how I assume it works. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-03-19 2:46 ` Glenn Morris 2010-03-22 14:53 ` Karel Klic @ 2010-03-29 13:53 ` Karel Klic 2010-03-29 19:00 ` Glenn Morris ` (2 more replies) 1 sibling, 3 replies; 13+ messages in thread From: Karel Klic @ 2010-03-29 13:53 UTC (permalink / raw) To: Glenn Morris; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 243 bytes --] Glenn Morris wrote: > This looks like a good patch to me. If no-one else comments in a week > or so, I suggest we just get on with it. The attached patch fixes file save operation using Tramp package with the SELinux patches applied. Karel [-- Attachment #2: emacs-selinux-tramp.patch --] [-- Type: text/x-patch, Size: 731 bytes --] diff -up emacs-23.1.92/lisp/net/tramp.el.selinux-tramp emacs-23.1.92/lisp/net/tramp.el --- emacs-23.1.92/lisp/net/tramp.el.selinux-tramp 2010-03-29 15:38:31.292916891 +0200 +++ emacs-23.1.92/lisp/net/tramp.el 2010-03-29 15:38:56.583163324 +0200 @@ -5268,7 +5268,7 @@ ARGS are the arguments OPERATION has bee 'dired-compress-file 'dired-uncache 'file-accessible-directory-p 'file-attributes 'file-directory-p 'file-executable-p 'file-exists-p - 'file-local-copy 'file-remote-p 'file-modes + 'file-local-copy 'file-remote-p 'file-modes 'file-selinux-context 'file-name-as-directory 'file-name-directory 'file-name-nondirectory 'file-name-sans-versions 'file-ownership-preserved-p 'file-readable-p ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-03-29 13:53 ` Karel Klic @ 2010-03-29 19:00 ` Glenn Morris 2010-04-21 3:55 ` Glenn Morris 2010-04-23 14:23 ` Michael Albinus 2 siblings, 0 replies; 13+ messages in thread From: Glenn Morris @ 2010-03-29 19:00 UTC (permalink / raw) To: Karel Klic; +Cc: emacs-devel Thanks. If you hear that your copyright papers have been processed, please let me know (I should find out eventually, but you may hear sooner), and I'll get all this installed. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-03-29 13:53 ` Karel Klic 2010-03-29 19:00 ` Glenn Morris @ 2010-04-21 3:55 ` Glenn Morris 2010-04-23 14:23 ` Michael Albinus 2 siblings, 0 replies; 13+ messages in thread From: Glenn Morris @ 2010-04-21 3:55 UTC (permalink / raw) To: Karel Klic; +Cc: emacs-devel Your papers arrived and I have installed your patches. Thank you very much for your contribution! ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-03-29 13:53 ` Karel Klic 2010-03-29 19:00 ` Glenn Morris 2010-04-21 3:55 ` Glenn Morris @ 2010-04-23 14:23 ` Michael Albinus 2010-04-30 6:43 ` Karel Klic 2 siblings, 1 reply; 13+ messages in thread From: Michael Albinus @ 2010-04-23 14:23 UTC (permalink / raw) To: Karel Klic; +Cc: emacs-devel Karel Klic <kklic@redhat.com> writes: Hi Karel, > The attached patch fixes file save operation using Tramp package with > the SELinux patches applied. I have committed a patch, which adds Tramp handlers for SELinux. I don't know whether you use Tramp - if yes, it would be great if you could test it. > Karel Best regards, Michael. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] SELinux support 2010-04-23 14:23 ` Michael Albinus @ 2010-04-30 6:43 ` Karel Klic 0 siblings, 0 replies; 13+ messages in thread From: Karel Klic @ 2010-04-30 6:43 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel Hi Michael, I'll test it. I'm updating my Emacs installation today. My apology for late response, I was not on-line for the last week or so. Karel Dne 23.4.2010 16:23, Michael Albinus napsal(a): > Karel Klic<kklic@redhat.com> writes: > > Hi Karel, > >> The attached patch fixes file save operation using Tramp package with >> the SELinux patches applied. > > I have committed a patch, which adds Tramp handlers for SELinux. I don't > know whether you use Tramp - if yes, it would be great if you could test it. > >> Karel > > Best regards, Michael. ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2010-04-30 6:43 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-03-02 19:36 [PATCH] SELinux support Karel Klic 2010-03-17 2:18 ` Glenn Morris 2010-03-18 0:10 ` Glenn Morris 2010-03-18 13:33 ` Karel Klic 2010-03-19 2:46 ` Glenn Morris 2010-03-22 14:53 ` Karel Klic 2010-03-22 16:01 ` Tom Tromey 2010-03-22 18:13 ` Glenn Morris 2010-03-29 13:53 ` Karel Klic 2010-03-29 19:00 ` Glenn Morris 2010-04-21 3:55 ` Glenn Morris 2010-04-23 14:23 ` Michael Albinus 2010-04-30 6:43 ` Karel Klic
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).