diff --git a/emacs-ede-cve-2012-0035.patch b/emacs-ede-cve-2012-0035.patch new file mode 100644 index 0000000..df39d54 --- /dev/null +++ b/emacs-ede-cve-2012-0035.patch @@ -0,0 +1,483 @@ +diff -r -c emacs-23.3-old/lisp/cedet/ede/auto.el emacs-23.3/lisp/cedet/ede/auto.el +*** emacs-23.3-old/lisp/cedet/ede/auto.el 2011-01-09 01:45:14.000000000 +0800 +--- emacs-23.3/lisp/cedet/ede/auto.el 2012-01-09 13:20:12.410502713 +0800 +*************** +*** 58,63 **** +--- 58,70 ---- + :initform t + :documentation + "Non-nil if this is an option when a user creates a project.") ++ (safe-p :initarg :safe-p ++ :initform t ++ :documentation ++ "Non-nil if the project load files are \"safe\". ++ An unsafe project is one that loads project variables via Emacs ++ Lisp code. A safe project is one that loads project variables by ++ scanning files without loading Lisp code from them.") + ) + "Class representing minimal knowledge set to run preliminary EDE functions. + When more advanced functionality is needed from a project type, that projects +*************** +*** 69,81 **** + :name "Make" :file 'ede/proj + :proj-file "Project.ede" + :load-type 'ede-proj-load +! :class-sym 'ede-proj-project) + (ede-project-autoload "edeproject-automake" + :name "Automake" :file 'ede/proj + :proj-file "Project.ede" + :initializers '(:makefile-type Makefile.am) + :load-type 'ede-proj-load +! :class-sym 'ede-proj-project) + (ede-project-autoload "automake" + :name "automake" :file 'ede/project-am + :proj-file "Makefile.am" +--- 76,90 ---- + :name "Make" :file 'ede/proj + :proj-file "Project.ede" + :load-type 'ede-proj-load +! :class-sym 'ede-proj-project +! :safe-p nil) + (ede-project-autoload "edeproject-automake" + :name "Automake" :file 'ede/proj + :proj-file "Project.ede" + :initializers '(:makefile-type Makefile.am) + :load-type 'ede-proj-load +! :class-sym 'ede-proj-project +! :safe-p nil) + (ede-project-autoload "automake" + :name "automake" :file 'ede/project-am + :proj-file "Makefile.am" +*************** +*** 84,89 **** +--- 93,100 ---- + :new-p nil)) + "List of vectors defining how to determine what type of projects exist.") + ++ (put 'ede-project-class-files 'risky-local-variable t) ++ + ;;; EDE project-autoload methods + ;; + (defmethod ede-project-root ((this ede-project-autoload)) +*************** +*** 122,127 **** +--- 133,151 ---- + (when (and f (file-exists-p f)) + f))) + ++ (defmethod ede-auto-load-project ((this ede-project-autoload) dir) ++ "Load in the project associated with THIS project autoload description. ++ THIS project description should be valid for DIR, where the project will ++ be loaded." ++ ;; Last line of defense: don't load unsafe projects. ++ (when (not (or (oref this :safe-p) ++ (ede-directory-safe-p dir))) ++ (error "Attempt to load an unsafe project (bug elsewhere in EDE)")) ++ ;; Things are good - so load the project. ++ (let ((o (funcall (oref this load-type) dir))) ++ (when (not o) ++ (error "Project type error: :load-type failed to create a project")) ++ (ede-add-project-to-global-list o))) + + (provide 'ede/auto) + +diff -r -c emacs-23.3-old/lisp/cedet/ede/simple.el emacs-23.3/lisp/cedet/ede/simple.el +*** emacs-23.3-old/lisp/cedet/ede/simple.el 2011-01-09 01:45:14.000000000 +0800 +--- emacs-23.3/lisp/cedet/ede/simple.el 2012-01-09 13:17:20.010502312 +0800 +*************** +*** 50,56 **** + :name "Simple" :file 'ede/simple + :proj-file 'ede-simple-projectfile-for-dir + :load-type 'ede-simple-load +! :class-sym 'ede-simple-project) + t) + + (defcustom ede-simple-save-directory "~/.ede" +--- 50,57 ---- + :name "Simple" :file 'ede/simple + :proj-file 'ede-simple-projectfile-for-dir + :load-type 'ede-simple-load +! :class-sym 'ede-simple-project +! :safe-p nil) + t) + + (defcustom ede-simple-save-directory "~/.ede" +diff -r -c emacs-23.3-old/lisp/cedet/ede.el emacs-23.3/lisp/cedet/ede.el +*** emacs-23.3-old/lisp/cedet/ede.el 2011-01-09 01:45:14.000000000 +0800 +--- emacs-23.3/lisp/cedet/ede.el 2012-01-09 13:24:44.854503349 +0800 +*************** +*** 94,99 **** +--- 94,135 ---- + :group 'ede + :type 'sexp) ; make this be a list of options some day + ++ (defcustom ede-project-directories nil ++ "Directories in which EDE may search for project files. ++ If the value is t, EDE may search in any directory. ++ ++ If the value is a function, EDE calls that function with one ++ argument, the directory name; the function should return t iff ++ EDE should look for project files in the directory. ++ ++ Otherwise, the value should be a list of fully-expanded directory ++ names. EDE searches for project files only in those directories. ++ If you invoke the commands \\[ede] or \\[ede-new] on a directory ++ that is not listed, Emacs will offer to add it to the list. ++ ++ Any other value disables searching for EDE project files." ++ :group 'ede ++ :type '(choice (const :tag "Any directory" t) ++ (repeat :tag "List of directories" ++ (directory)) ++ (function :tag "Predicate")) ++ :version "23.4" ++ :risky t) ++ ++ (defun ede-directory-safe-p (dir) ++ "Return non-nil if DIR is a safe directory to load projects from. ++ Projects that do not load a project definition as Emacs Lisp code ++ are safe, and can be loaded automatically. Other project types, ++ such as those created with Project.ede files, are safe only if ++ specified by `ede-project-directories'." ++ (setq dir (directory-file-name (expand-file-name dir))) ++ ;; Load only if allowed by `ede-project-directories'. ++ (or (eq ede-project-directories t) ++ (and (functionp ede-project-directories) ++ (funcall ede-project-directories dir)) ++ (and (listp ede-project-directories) ++ (member dir ede-project-directories)))) ++ + + ;;; Management variables + +*************** +*** 419,442 **** + Sets buffer local variables for EDE." + (let* ((ROOT nil) + (proj (ede-directory-get-open-project default-directory +! 'ROOT))) + (when (or proj ROOT +! (ede-directory-project-p default-directory t)) + +! (when (not proj) +! ;; @todo - this could be wasteful. +! (setq proj (ede-load-project-file default-directory 'ROOT))) + +! (setq ede-object (ede-buffer-object (current-buffer) + 'ede-object-project)) + +! (setq ede-object-root-project +! (or ROOT (ede-project-root ede-object-project))) + +! (if (and (not ede-object) ede-object-project) +! (ede-auto-add-to-target)) + +! (ede-apply-target-options)))) + + (defun ede-reset-all-buffers (onoff) + "Reset all the buffers due to change in EDE. +--- 455,496 ---- + Sets buffer local variables for EDE." + (let* ((ROOT nil) + (proj (ede-directory-get-open-project default-directory +! 'ROOT)) +! (projauto nil)) +! + (when (or proj ROOT +! ;; If there is no open project, look up the project +! ;; autoloader to see if we should initialize. +! (setq projauto (ede-directory-project-p default-directory t))) +! +! (when (and (not proj) projauto) +! +! ;; No project was loaded, but we have a project description +! ;; object. This means that we can check if it is a safe +! ;; project to load before requesting it to be loaded. +! +! (when (or (oref projauto safe-p) +! ;; The project style is not safe, so check if it is +! ;; in `ede-project-directories'. +! (let ((top (ede-toplevel-project default-directory))) +! (ede-directory-safe-p top))) + +! ;; The project is safe, so load it in. +! (setq proj (ede-load-project-file default-directory 'ROOT)))) + +! ;; Only initialize EDE state in this buffer if we found a project. +! (when proj +! +! (setq ede-object (ede-buffer-object (current-buffer) + 'ede-object-project)) + +! (setq ede-object-root-project +! (or ROOT (ede-project-root ede-object-project))) + +! (if (and (not ede-object) ede-object-project) +! (ede-auto-add-to-target)) + +! (ede-apply-target-options))))) + + (defun ede-reset-all-buffers (onoff) + "Reset all the buffers due to change in EDE. +*************** +*** 555,567 **** + + ;;; Interactive method invocations + ;; +! (defun ede (file) +! "Start up EDE on something. +! Argument FILE is the file or directory to load a project from." +! (interactive "fProject File: ") +! (if (not (file-exists-p file)) +! (ede-new file) +! (ede-load-project-file (file-name-directory file)))) + + (defun ede-new (type &optional name) + "Create a new project starting of project type TYPE. +--- 609,681 ---- + + ;;; Interactive method invocations + ;; +! (defun ede (dir) +! "Start up EDE for directory DIR. +! If DIR has an existing project file, load it. +! Otherwise, create a new project for DIR." +! (interactive +! ;; When choosing a directory to turn on, and we see some directory here, +! ;; provide that as the default. +! (let* ((top (ede-toplevel-project default-directory)) +! (promptdflt (or top default-directory))) +! (list (read-directory-name "Project directory: " +! promptdflt promptdflt t)))) +! (unless (file-directory-p dir) +! (error "%s is not a directory" dir)) +! (when (ede-directory-get-open-project dir) +! (error "%s already has an open project associated with it" dir)) +! +! ;; Check if the directory has been added to the list of safe +! ;; directories. It can also add the directory to the safe list if +! ;; the user chooses. +! (if (ede-check-project-directory dir) +! (progn +! ;; If there is a project in DIR, load it, otherwise do +! ;; nothing. +! (ede-load-project-file dir) +! +! ;; Check if we loaded anything on the previous line. +! (if (ede-current-project dir) +! +! ;; We successfully opened an existing project. Some open +! ;; buffers may also be referring to this project. +! ;; Resetting all the buffers will get them to also point +! ;; at this new open project. +! (ede-reset-all-buffers 1) +! +! ;; ELSE +! ;; There was no project, so switch to `ede-new' which is how +! ;; a user can select a new kind of project to create. +! (let ((default-directory (expand-file-name dir))) +! (call-interactively 'ede-new)))) +! +! ;; If the proposed directory isn't safe, then say so. +! (error "%s is not an allowed project directory in `ede-project-directories'" +! dir))) +! +! (defun ede-check-project-directory (dir) +! "Check if DIR should be in `ede-project-directories'. +! If it is not, try asking the user if it should be added; if so, +! add it and save `ede-project-directories' via Customize. +! Return nil iff DIR should not be in `ede-project-directories'." +! (setq dir (directory-file-name (expand-file-name dir))) ; strip trailing / +! (or (eq ede-project-directories t) +! (and (functionp ede-project-directories) +! (funcall ede-project-directories dir)) +! ;; If `ede-project-directories' is a list, maybe add it. +! (when (listp ede-project-directories) +! (or (member dir ede-project-directories) +! (when (y-or-n-p (format "`%s' is not listed in `ede-project-directories'. +! Add it to the list of allowed project directories? " +! dir)) +! (push dir ede-project-directories) +! ;; If possible, save `ede-project-directories'. +! (if (or custom-file user-init-file) +! (let ((coding-system-for-read nil)) +! (customize-save-variable +! 'ede-project-directories +! ede-project-directories))) +! t))))) + + (defun ede-new (type &optional name) + "Create a new project starting of project type TYPE. +*************** +*** 596,601 **** +--- 710,720 ---- + (error "Cannot create project in non-existent directory %s" default-directory)) + (when (not (file-writable-p default-directory)) + (error "No write permissions for %s" default-directory)) ++ (unless (ede-check-project-directory default-directory) ++ (error "%s is not an allowed project directory in `ede-project-directories'" ++ default-directory)) ++ ;; Make sure the project directory is loadable in the future. ++ (ede-check-project-directory default-directory) + ;; Create the project + (let* ((obj (object-assoc type 'name ede-project-class-files)) + (nobj (let ((f (oref obj file)) +*************** +*** 629,634 **** +--- 748,757 ---- + (ede-add-subproject pp nobj) + (ede-commit-project pp))) + (ede-commit-project nobj)) ++ ;; Once the project is created, load it again. This used to happen ++ ;; lazily, but with project loading occurring less often and with ++ ;; security in mind, this is now the safe time to reload. ++ (ede-load-project-file default-directory) + ;; Have the menu appear + (setq ede-minor-mode t) + ;; Allert the user +*************** +*** 651,661 **** + (defun ede-rescan-toplevel () + "Rescan all project files." + (interactive) +! (let ((toppath (ede-toplevel-project default-directory)) +! (ede-deep-rescan t)) +! (project-rescan (ede-load-project-file toppath)) +! (ede-reset-all-buffers 1) +! )) + + (defun ede-new-target (&rest args) + "Create a new target specific to this type of project file. +--- 774,789 ---- + (defun ede-rescan-toplevel () + "Rescan all project files." + (interactive) +! (if (not (ede-directory-get-open-project default-directory)) +! ;; This directory isn't open. Can't rescan. +! (error "Attempt to rescan a project that isn't open") +! +! ;; Continue +! (let ((toppath (ede-toplevel-project default-directory)) +! (ede-deep-rescan t)) +! +! (project-rescan (ede-load-project-file toppath)) +! (ede-reset-all-buffers 1)))) + + (defun ede-new-target (&rest args) + "Create a new target specific to this type of project file. +*************** +*** 891,897 **** + ;; Do the load + ;;(message "EDE LOAD : %S" file) + (let* ((file dir) +! (path (expand-file-name (file-name-directory file))) + (pfc (ede-directory-project-p path)) + (toppath nil) + (o nil)) +--- 1019,1025 ---- + ;; Do the load + ;;(message "EDE LOAD : %S" file) + (let* ((file dir) +! (path (file-name-as-directory (expand-file-name dir))) + (pfc (ede-directory-project-p path)) + (toppath nil) + (o nil)) +*************** +*** 920,932 **** + ;; See if it's been loaded before + (setq o (object-assoc (ede-dir-to-projectfile pfc toppath) 'file + ede-projects)) +! (if (not o) +! ;; If not, get it now. +! (let ((ede-constructing pfc)) +! (setq o (funcall (oref pfc load-type) toppath)) +! (when (not o) +! (error "Project type error: :load-type failed to create a project")) +! (ede-add-project-to-global-list o))) + + ;; Return the found root project. + (when rootreturn (set rootreturn o)) +--- 1048,1058 ---- + ;; See if it's been loaded before + (setq o (object-assoc (ede-dir-to-projectfile pfc toppath) 'file + ede-projects)) +! +! ;; If not open yet, load it. +! (unless o +! (let ((ede-constructing pfc)) +! (setq o (ede-auto-load-project pfc toppath)))) + + ;; Return the found root project. + (when rootreturn (set rootreturn o)) +*************** +*** 980,992 **** + (and root + (ede-find-subproject-for-directory root updir)) + ;; Try the all structure based search. +! (ede-directory-get-open-project updir) +! ;; Load up the project file as a last resort. +! ;; Last resort since it uses file-truename, and other +! ;; slow features. +! (and (ede-directory-project-p updir) +! (ede-load-project-file +! (file-name-as-directory updir)))))))))) + + (defun ede-current-project (&optional dir) + "Return the current project file. +--- 1106,1112 ---- + (and root + (ede-find-subproject-for-directory root updir)) + ;; Try the all structure based search. +! (ede-directory-get-open-project updir)))))))) + + (defun ede-current-project (&optional dir) + "Return the current project file. +*************** +*** 1000,1010 **** + ;; No current project. + (when (not ans) + (let* ((ldir (or dir default-directory))) +! (setq ans (ede-directory-get-open-project ldir)) +! (or ans +! ;; No open project, if this dir pass project-p, then load. +! (when (ede-directory-project-p ldir) +! (setq ans (ede-load-project-file ldir)))))) + ;; Return what we found. + ans)) + +--- 1120,1126 ---- + ;; No current project. + (when (not ans) + (let* ((ldir (or dir default-directory))) +! (setq ans (ede-directory-get-open-project ldir)))) + ;; Return what we found. + ans)) + +*************** +*** 1059,1070 **** + "Return the project which is the parent of TARGET. + It is recommended you track the project a different way as this function + could become slow in time." +! ;; @todo - use ede-object-project as a starting point. +! (let ((ans nil) (projs ede-projects)) +! (while (and (not ans) projs) +! (setq ans (ede-target-in-project-p (car projs) target) +! projs (cdr projs))) +! ans)) + + (defmethod ede-find-target ((proj ede-project) buffer) + "Fetch the target in PROJ belonging to BUFFER or nil." +--- 1175,1187 ---- + "Return the project which is the parent of TARGET. + It is recommended you track the project a different way as this function + could become slow in time." +! (or ede-object-project +! ;; If not cached, derive it from the current directory of the target. +! (let ((ans nil) (projs ede-projects)) +! (while (and (not ans) projs) +! (setq ans (ede-target-in-project-p (car projs) target) +! projs (cdr projs))) +! ans))) + + (defmethod ede-find-target ((proj ede-project) buffer) + "Fetch the target in PROJ belonging to BUFFER or nil." diff --git a/emacs.spec b/emacs.spec index de51ef1..4a991af 100644 --- a/emacs.spec +++ b/emacs.spec @@ -3,7 +3,7 @@ Summary: GNU Emacs text editor Name: emacs Epoch: 1 Version: 23.3 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ URL: http://www.gnu.org/software/emacs/ Group: Applications/Editors @@ -34,6 +34,9 @@ Patch6: emacs-23.2-hideshow-comment.patch # rhbz#711739 # http://bzr.savannah.gnu.org/lh/emacs/trunk/revision/106247 Patch7: emacs-wm-state-hidden.patch +# http://lists.gnu.org/archive/html/emacs-devel/2012-01/msg00387.html +Patch8: emacs-ede-cve-2012-0035.patch + BuildRequires: atk-devel, cairo-devel, freetype-devel, fontconfig-devel, dbus-devel, giflib-devel, glibc-devel, gtk2-devel, libpng-devel BuildRequires: libjpeg-devel, libtiff-devel, libX11-devel, libXau-devel, libXdmcp-devel, libXrender-devel, libXt-devel BuildRequires: libXpm-devel, ncurses-devel, xorg-x11-proto-devel, zlib-devel @@ -154,6 +157,7 @@ packages that add functionality to Emacs. %patch4 -p1 -b .xdg %patch6 -p0 -b .hideshow-comment %patch7 -p1 -b .wm-state-hidden +%patch8 -p1 -b .ede-cve-2012-0035 # Install site-lisp files cp %SOURCE7 %SOURCE9 %SOURCE10 site-lisp @@ -430,6 +434,9 @@ update-desktop-database &> /dev/null || : %dir %{_datadir}/emacs/site-lisp/site-start.d %changelog +* Thu Jan 12 2012 Karel Klíč - 1:23.3-9 +- Added patch to handle CVE-2012-0035: CEDET global-ede-mode file loading vulnerability (rhbz#773024) + * Wed Nov 23 2011 Karel Klíč - 1:23.3-8 - Check for _NET_WM_STATE_HIDDEN (rhbz#711739)