diff --git a/0002-fix-CVE-2024-53920.patch b/0002-fix-CVE-2024-53920.patch new file mode 100644 index 0000000000000000000000000000000000000000..c2027681aaaa84a0ae2fe4b4f47a3d16b2162179 --- /dev/null +++ b/0002-fix-CVE-2024-53920.patch @@ -0,0 +1,171 @@ +From b5158bd191422e46273c4d9412f2bf097e2da2e0 Mon Sep 17 00:00:00 2001 +From: Stefan Monnier +Date: Tue, 10 Dec 2024 16:26:31 -0500 +Subject: elisp-mode.el: Disable Flymake byte-compile backend in untrusted + files + +To address serious security issues (CVE-2024-53920), disable +`elisp-flymake-byte-compile` except in those files explicitly +specified as "trusted". + +For that introduce a new custom var `trusted-files` and new +function `trusted-content-p`. + +While at it, similarly skip the implicit macroexpansion done during +completion if the current file is not trusted. + +* lisp/files.el (trusted-files): New variable. +(trusted-content-p): New function. + +* lisp/progmodes/elisp-mode.el (elisp--safe-macroexpand-all): +New function, extracted from `elisp--local-variables`. +Use `trusted-content-p`. +(elisp--local-variables): Use it. +(elisp-flymake-byte-compile): Disable according to `trusted-content-p`. +--- + lisp/files.el | 49 ++++++++++++++++++++++++++++++++ + lisp/progmodes/elisp-mode.el | 54 +++++++++++++++++++++++++----------- + 2 files changed, 87 insertions(+), 16 deletions(-) + +diff --git a/lisp/files.el b/lisp/files.el +index 5536af0..017f989 100644 +--- a/lisp/files.el ++++ b/lisp/files.el +@@ -703,6 +703,55 @@ buffer contents as untrusted. + This variable might be subject to change without notice.") + (put 'untrusted-content 'permanent-local t) + ++(defcustom trusted-files nil ++ "List of files and directories whose content we trust. ++Be extra careful here since trusting means that Emacs might execute the ++code contained within those files and directories without an explicit ++request by the user. ++One important case when this might happen is when `flymake-mode' is ++enabled (for example, when it is added to a mode hook). ++Each element of the list should be a string: ++- If it ends in \"/\", it is considered as a directory name and means that ++ Emacs should trust all the files whose name has this directory as a prefix. ++- else it is considered as a file name. ++Use abbreviated file names. For example, an entry \"~/mycode\" means ++that Emacs will trust all the files in your directory \"mycode\". ++This variable can also be set to `:all', in which case Emacs will trust ++all files, which opens a gaping security hole." ++ :type '(choice (repeat :tag "List" file) ++ (const :tag "Trust everything (DANGEROUS!)" :all)) ++ :version "30.1") ++(put 'trusted-files 'risky-local-variable t) ++ ++(defun trusted-content-p () ++ "Return non-nil if we trust the contents of the current buffer. ++Here, \"trust\" means that we are willing to run code found inside of it. ++See also `trusted-files'." ++ ;; We compare with `buffer-file-truename' i.s.o `buffer-file-name' ++ ;; to try and avoid marking as trusted a file that's merely accessed ++ ;; via a symlink that happens to be inside a trusted dir. ++ (and (not untrusted-content) ++ buffer-file-truename ++ (with-demoted-errors "trusted-content-p: %S" ++ (let ((exists (file-exists-p buffer-file-truename))) ++ (or ++ (eq trusted-files :all) ++ ;; We can't avoid trusting the user's init file. ++ (if (and exists user-init-file) ++ (file-equal-p buffer-file-truename user-init-file) ++ (equal buffer-file-truename user-init-file)) ++ (let ((file (abbreviate-file-name buffer-file-truename)) ++ (trusted nil)) ++ (dolist (tf trusted-files) ++ (when (or (if exists (file-equal-p tf file) (equal tf file)) ++ ;; We don't use `file-in-directory-p' here, because ++ ;; we want to err on the conservative side: "guilty ++ ;; until proven innocent". ++ (and (string-suffix-p "/" tf) ++ (string-prefix-p tf file))) ++ (setq trusted t))) ++ trusted)))))) ++ + ;; This is an odd variable IMO. + ;; You might wonder why it is needed, when we could just do: + ;; (setq-local enable-local-variables nil) +diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el +index 7436fe7..853428a 100644 +--- a/lisp/progmodes/elisp-mode.el ++++ b/lisp/progmodes/elisp-mode.el +@@ -430,6 +430,34 @@ be used instead. + + (defvar warning-minimum-log-level) + ++(defvar elisp--macroexpand-untrusted-warning t) ++ ++(defun elisp--safe-macroexpand-all (sexp) ++ (if (not (trusted-content-p)) ++ ;; FIXME: We should try and do better here, either using a notion ++ ;; of "safe" macros, or with `bwrap', or ... ++ (progn ++ (when elisp--macroexpand-untrusted-warning ++ (setq-local elisp--macroexpand-untrusted-warning nil) ;Don't spam! ++ (message "Completion of local vars is disabled in %s (untrusted content)" ++ (buffer-name))) ++ sexp) ++ (let ((macroexpand-advice ++ (lambda (expander form &rest args) ++ (condition-case err ++ (apply expander form args) ++ (error ++ (message "Ignoring macroexpansion error: %S" err) form))))) ++ (unwind-protect ++ ;; Silence any macro expansion errors when ++ ;; attempting completion at point (bug#58148). ++ (let ((inhibit-message t) ++ (macroexp-inhibit-compiler-macros t) ++ (warning-minimum-log-level :emergency)) ++ (advice-add 'macroexpand-1 :around macroexpand-advice) ++ (macroexpand-all sexp elisp--local-macroenv)) ++ (advice-remove 'macroexpand-1 macroexpand-advice))))) ++ + (defun elisp--local-variables () + "Return a list of locally let-bound variables at point." + (save-excursion +@@ -445,22 +473,8 @@ be used instead. + (car (read-from-string + (concat txt "elisp--witness--lisp" closer))) + ((invalid-read-syntax end-of-file) nil))) +- (macroexpand-advice (lambda (expander form &rest args) +- (condition-case nil +- (apply expander form args) +- (error form)))) +- (sexp +- (unwind-protect +- ;; Silence any macro expansion errors when +- ;; attempting completion at point (bug#58148). +- (let ((inhibit-message t) +- (warning-minimum-log-level :emergency)) +- (advice-add 'macroexpand :around macroexpand-advice) +- (condition-case nil +- (macroexpand-all sexp) +- (error sexp))) +- (advice-remove 'macroexpand macroexpand-advice))) +- (vars (elisp--local-variables-1 nil sexp))) ++ (vars (elisp--local-variables-1 ++ nil (elisp--safe-macroexpand-all sexp)))) + (delq nil + (mapcar (lambda (var) + (and (symbolp var) +@@ -2164,6 +2178,14 @@ directory of the buffer being compiled, and nothing else.") + "A Flymake backend for elisp byte compilation. + Spawn an Emacs process that byte-compiles a file representing the + current buffer state and calls REPORT-FN when done." ++ (unless (trusted-content-p) ++ ;; FIXME: Use `bwrap' and friends to compile untrusted content. ++ ;; FIXME: We emit a message *and* signal an error, because by default ++ ;; Flymake doesn't display the warning it puts into "*flmake log*". ++ (message "Disabling elisp-flymake-byte-compile in %s (untrusted content)" ++ (buffer-name)) ++ (error "Disabling elisp-flymake-byte-compile in %s (untrusted content)" ++ (buffer-name))) + (when elisp-flymake--byte-compile-process + (when (process-live-p elisp-flymake--byte-compile-process) + (kill-process elisp-flymake--byte-compile-process))) +-- +2.43.5 + diff --git a/emacs.spec b/emacs.spec index 4782e97f2fad4a0e3b32585fa4dd5adfa2a10b88..aca35283a18e9ef95615a478493db8e6a4997b45 100644 --- a/emacs.spec +++ b/emacs.spec @@ -1,4 +1,4 @@ -%define anolis_release 2 +%define anolis_release 3 %global _hardened_build 1 # This file is encoded in UTF-8. -*- coding: utf-8 -*- @@ -19,6 +19,7 @@ Patch1: emacs-spellchecker.patch Patch2: emacs-system-crypto-policies.patch Patch3: emacs-libdir-vs-systemd.patch Patch4: 0001-Fix-man.el-shell-injection-vulnerability.patch +Patch5: 0002-fix-CVE-2024-53920.patch BuildRequires: gcc BuildRequires: atk-devel @@ -512,6 +513,9 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/*.desktop %{_includedir}/emacs-module.h %changelog +* Thu May 15 2025 Cheng Yang - 1:29.4-3 +- Fix CVE-2024-53920 + * Wed Mar 05 2025 yangjinlin01 - 1:29.4-2 - fix the CVE-2025-1244