Skip to content

Commit e6983fd

Browse files
[AUTO-CHERRYPICK] [2.0] Resolve emacs CVE-2024-53920 [Critical] - branch main (#13011)
Co-authored-by: Henry Li <69694695+henryli001@users.noreply.github.com>
1 parent 7a790e9 commit e6983fd

2 files changed

Lines changed: 142 additions & 1 deletion

File tree

SPECS/emacs/CVE-2024-53920.patch

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
diff --git a/lisp/files.el b/lisp/files.el
2+
index 5536af0..5e0d44d 100644
3+
--- a/lisp/files.el
4+
+++ b/lisp/files.el
5+
@@ -702,6 +702,54 @@ buffer contents as untrusted.
6+
7+
This variable might be subject to change without notice.")
8+
(put 'untrusted-content 'permanent-local t)
9+
+(defcustom trusted-files nil
10+
+ "List of files and directories whose content we trust.
11+
+Be extra careful here since trusting means that Emacs might execute the
12+
+code contained within those files and directories without an explicit
13+
+request by the user.
14+
+One important case when this might happen is when `flymake-mode' is
15+
+enabled (for example, when it is added to a mode hook).
16+
+Each element of the list should be a string:
17+
+- If it ends in \"/\", it is considered as a directory name and means that
18+
+ Emacs should trust all the files whose name has this directory as a prefix.
19+
+- else it is considered as a file name.
20+
+Use abbreviated file names. For example, an entry \"~/mycode\" means
21+
+that Emacs will trust all the files in your directory \"mycode\".
22+
+This variable can also be set to `:all', in which case Emacs will trust
23+
+all files, which opens a gaping security hole."
24+
+ :type '(choice (repeat :tag "List" file)
25+
+ (const :tag "Trust everything (DANGEROUS!)" :all))
26+
+ :version "30.1")
27+
+(put 'trusted-files 'risky-local-variable t)
28+
+
29+
+(defun trusted-content-p ()
30+
+ "Return non-nil if we trust the contents of the current buffer.
31+
+Here, \"trust\" means that we are willing to run code found inside of it.
32+
+See also `trusted-files'."
33+
+ ;; We compare with `buffer-file-truename' i.s.o `buffer-file-name'
34+
+ ;; to try and avoid marking as trusted a file that's merely accessed
35+
+ ;; via a symlink that happens to be inside a trusted dir.
36+
+ (and (not untrusted-content)
37+
+ buffer-file-truename
38+
+ (with-demoted-errors "trusted-content-p: %S"
39+
+ (let ((exists (file-exists-p buffer-file-truename)))
40+
+ (or
41+
+ (eq trusted-files :all)
42+
+ ;; We can't avoid trusting the user's init file.
43+
+ (if (and exists user-init-file)
44+
+ (file-equal-p buffer-file-truename user-init-file)
45+
+ (equal buffer-file-truename user-init-file))
46+
+ (let ((file (abbreviate-file-name buffer-file-truename))
47+
+ (trusted nil))
48+
+ (dolist (tf trusted-files)
49+
+ (when (or (if exists (file-equal-p tf file) (equal tf file))
50+
+ ;; We don't use `file-in-directory-p' here, because
51+
+ ;; we want to err on the conservative side: "guilty
52+
+ ;; until proven innocent".
53+
+ (and (string-suffix-p "/" tf)
54+
+ (string-prefix-p tf file)))
55+
+ (setq trusted t)))
56+
+ trusted))))))
57+
58+
;; This is an odd variable IMO.
59+
;; You might wonder why it is needed, when we could just do:
60+
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
61+
index 7436fe7..230992f 100644
62+
--- a/lisp/progmodes/elisp-mode.el
63+
+++ b/lisp/progmodes/elisp-mode.el
64+
@@ -430,6 +430,34 @@ be used instead.
65+
66+
(defvar warning-minimum-log-level)
67+
68+
+(defvar elisp--macroexpand-untrusted-warning t)
69+
+
70+
+(defun elisp--safe-macroexpand-all (sexp)
71+
+ (if (not (trusted-content-p))
72+
+ ;; FIXME: We should try and do better here, either using a notion
73+
+ ;; of "safe" macros, or with `bwrap', or ...
74+
+ (progn
75+
+ (when elisp--macroexpand-untrusted-warning
76+
+ (setq-local elisp--macroexpand-untrusted-warning nil) ;Don't spam!
77+
+ (message "Completion of local vars is disabled in %s (untrusted content)"
78+
+ (buffer-name)))
79+
+ sexp)
80+
+ (let ((macroexpand-advice
81+
+ (lambda (expander form &rest args)
82+
+ (condition-case err
83+
+ (apply expander form args)
84+
+ (error
85+
+ (message "Ignoring macroexpansion error: %S" err) form)))))
86+
+ (unwind-protect
87+
+ ;; Silence any macro expansion errors when
88+
+ ;; attempting completion at point (bug#58148).
89+
+ (let ((inhibit-message t)
90+
+ (macroexp-inhibit-compiler-macros t)
91+
+ (warning-minimum-log-level :emergency))
92+
+ (advice-add 'macroexpand-1 :around macroexpand-advice)
93+
+ (macroexpand-all sexp elisp--local-macroenv))
94+
+ (advice-remove 'macroexpand-1 macroexpand-advice)))))
95+
+
96+
(defun elisp--local-variables ()
97+
"Return a list of locally let-bound variables at point."
98+
(save-excursion
99+
@@ -445,22 +473,7 @@ be used instead.
100+
(car (read-from-string
101+
(concat txt "elisp--witness--lisp" closer)))
102+
((invalid-read-syntax end-of-file) nil)))
103+
- (macroexpand-advice (lambda (expander form &rest args)
104+
- (condition-case nil
105+
- (apply expander form args)
106+
- (error form))))
107+
- (sexp
108+
- (unwind-protect
109+
- ;; Silence any macro expansion errors when
110+
- ;; attempting completion at point (bug#58148).
111+
- (let ((inhibit-message t)
112+
- (warning-minimum-log-level :emergency))
113+
- (advice-add 'macroexpand :around macroexpand-advice)
114+
- (condition-case nil
115+
- (macroexpand-all sexp)
116+
- (error sexp)))
117+
- (advice-remove 'macroexpand macroexpand-advice)))
118+
- (vars (elisp--local-variables-1 nil sexp)))
119+
+ (vars (elisp--local-variables-1 nil (elisp--safe-macroexpand-all sexp))))
120+
(delq nil
121+
(mapcar (lambda (var)
122+
(and (symbolp var)
123+
@@ -2164,6 +2177,14 @@ directory of the buffer being compiled, and nothing else.")
124+
"A Flymake backend for elisp byte compilation.
125+
Spawn an Emacs process that byte-compiles a file representing the
126+
current buffer state and calls REPORT-FN when done."
127+
+ (unless (trusted-content-p)
128+
+ ;; FIXME: Use `bwrap' and friends to compile untrusted content.
129+
+ ;; FIXME: We emit a message *and* signal an error, because by default
130+
+ ;; Flymake doesn't display the warning it puts into "*flmake log*".
131+
+ (message "Disabling elisp-flymake-byte-compile in %s (untrusted content)"
132+
+ (buffer-name))
133+
+ (error "Disabling elisp-flymake-byte-compile in %s (untrusted content)"
134+
+ (buffer-name)))
135+
(when elisp-flymake--byte-compile-process
136+
(when (process-live-p elisp-flymake--byte-compile-process)
137+
(kill-process elisp-flymake--byte-compile-process)))

SPECS/emacs/emacs.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
Summary: GNU Emacs text editor
22
Name: emacs
33
Version: 29.4
4-
Release: 2%{?dist}
4+
Release: 3%{?dist}
55
License: GPLv3+ AND CC0-1.0
66
Vendor: Microsoft Corporation
77
Distribution: Mariner
88
Group: Applications/Editors
99
URL: https://www.gnu.org/software/emacs/
1010
Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz
1111
Patch0: CVE-2025-1244.patch
12+
Patch1: CVE-2024-53920.patch
1213
BuildRequires: gcc
1314
BuildRequires: glibc-devel
1415
BuildRequires: gnutls-devel
@@ -85,6 +86,9 @@ mkdir -p %{buildroot}%{_datadir}/emacs/site-lisp/site-start.d
8586
%dir %{_datadir}/emacs/site-lisp/site-start.d
8687

8788
%changelog
89+
* Mon Mar 17 2025 Henry Li <lihl@microsoft.com> - 29.4-3
90+
- Add patch to resolve CVE-2024-53920
91+
8892
* Sun Feb 16 2025 Kanishk Bansal <kanbansal@microsoft.com> - 29.4-2
8993
- Apply upstream patch to fix CVE-2025-1244
9094

0 commit comments

Comments
 (0)