1 |
ulm 12/01/09 11:09:29 |
2 |
|
3 |
Added: cedet-1.0-ede_security_fix.patch |
4 |
Log: |
5 |
Fix security flaw in EDE, bug 398227. Update ebuild to EAPI 4. |
6 |
|
7 |
(Portage version: 2.1.10.44/cvs/Linux x86_64) |
8 |
|
9 |
Revision Changes Path |
10 |
1.1 app-emacs/cedet/files/cedet-1.0-ede_security_fix.patch |
11 |
|
12 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/app-emacs/cedet/files/cedet-1.0-ede_security_fix.patch?rev=1.1&view=markup |
13 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/app-emacs/cedet/files/cedet-1.0-ede_security_fix.patch?rev=1.1&content-type=text/plain |
14 |
|
15 |
Index: cedet-1.0-ede_security_fix.patch |
16 |
=================================================================== |
17 |
http://lists.gnu.org/archive/html/emacs-devel/2012-01/msg00387.html |
18 |
https://bugs.gentoo.org/398227 |
19 |
|
20 |
--- cedet-1.0-orig/ede/ede-auto.el |
21 |
+++ cedet-1.0/ede/ede-auto.el |
22 |
@@ -57,6 +57,13 @@ |
23 |
:initform t |
24 |
:documentation |
25 |
"Non-nil if this is an option when a user creates a project.") |
26 |
+ (safe-p :initarg :safe-p |
27 |
+ :initform t |
28 |
+ :documentation |
29 |
+ "Non-nil if the project load files are \"safe\". |
30 |
+An unsafe project is one that loads project variables via Emacs |
31 |
+Lisp code. A safe project is one that loads project variables by |
32 |
+scanning files without loading Lisp code from them.") |
33 |
) |
34 |
"Class representing minimal knowledge set to run preliminary EDE functions. |
35 |
When more advanced functionality is needed from a project type, that projects |
36 |
@@ -68,13 +75,15 @@ |
37 |
:name "Make" :file 'ede-proj |
38 |
:proj-file "Project.ede" |
39 |
:load-type 'ede-proj-load |
40 |
- :class-sym 'ede-proj-project) |
41 |
+ :class-sym 'ede-proj-project |
42 |
+ :safe-p nil) |
43 |
(ede-project-autoload "edeproject-automake" |
44 |
:name "Automake" :file 'ede-proj |
45 |
:proj-file "Project.ede" |
46 |
:initializers '(:makefile-type Makefile.am) |
47 |
:load-type 'ede-proj-load |
48 |
- :class-sym 'ede-proj-project) |
49 |
+ :class-sym 'ede-proj-project |
50 |
+ :safe-p nil) |
51 |
(ede-project-autoload "automake" |
52 |
:name "automake" :file 'project-am |
53 |
:proj-file "Makefile.am" |
54 |
@@ -84,6 +93,8 @@ |
55 |
) |
56 |
"List of vectors defining how to determine what type of projects exist.") |
57 |
|
58 |
+(put 'ede-project-class-files 'risky-local-variable t) |
59 |
+ |
60 |
;;; EDE project-autoload methods |
61 |
;; |
62 |
(defmethod ede-project-root ((this ede-project-autoload)) |
63 |
@@ -122,6 +133,19 @@ |
64 |
(when (and f (file-exists-p f)) |
65 |
f))) |
66 |
|
67 |
+(defmethod ede-auto-load-project ((this ede-project-autoload) dir) |
68 |
+ "Load in the project associated with THIS project autoload description. |
69 |
+THIS project description should be valid for DIR, where the project will |
70 |
+be loaded." |
71 |
+ ;; Last line of defense: don't load unsafe projects. |
72 |
+ (when (not (or (oref this :safe-p) |
73 |
+ (ede-directory-safe-p dir))) |
74 |
+ (error "Attempt to load an unsafe project (bug elsewhere in EDE)")) |
75 |
+ ;; Things are good - so load the project. |
76 |
+ (let ((o (funcall (oref this load-type) dir))) |
77 |
+ (when (not o) |
78 |
+ (error "Project type error: :load-type failed to create a project")) |
79 |
+ (ede-add-project-to-global-list o))) |
80 |
|
81 |
(provide 'ede-auto) |
82 |
|
83 |
--- cedet-1.0-orig/ede/ede-simple.el |
84 |
+++ cedet-1.0/ede/ede-simple.el |
85 |
@@ -51,7 +51,8 @@ |
86 |
:name "Simple" :file 'ede-simple |
87 |
:proj-file 'ede-simple-projectfile-for-dir |
88 |
:load-type 'ede-simple-load |
89 |
- :class-sym 'ede-simple-project) |
90 |
+ :class-sym 'ede-simple-project |
91 |
+ :safe-p nil) |
92 |
t) |
93 |
|
94 |
(defcustom ede-simple-save-directory "~/.ede" |
95 |
--- cedet-1.0-orig/ede/ede.el |
96 |
+++ cedet-1.0/ede/ede.el |
97 |
@@ -81,6 +81,42 @@ |
98 |
(require 'ede-auto) |
99 |
(require 'ede-base) |
100 |
|
101 |
+(defcustom ede-project-directories nil |
102 |
+ "Directories in which EDE may search for project files. |
103 |
+If the value is t, EDE may search in any directory. |
104 |
+ |
105 |
+If the value is a function, EDE calls that function with one |
106 |
+argument, the directory name; the function should return t iff |
107 |
+EDE should look for project files in the directory. |
108 |
+ |
109 |
+Otherwise, the value should be a list of fully-expanded directory |
110 |
+names. EDE searches for project files only in those directories. |
111 |
+If you invoke the commands \\[ede] or \\[ede-new] on a directory |
112 |
+that is not listed, Emacs will offer to add it to the list. |
113 |
+ |
114 |
+Any other value disables searching for EDE project files." |
115 |
+ :group 'ede |
116 |
+ :type '(choice (const :tag "Any directory" t) |
117 |
+ (repeat :tag "List of directories" |
118 |
+ (directory)) |
119 |
+ (function :tag "Predicate")) |
120 |
+ :version "23.4" |
121 |
+ :risky t) |
122 |
+ |
123 |
+(defun ede-directory-safe-p (dir) |
124 |
+ "Return non-nil if DIR is a safe directory to load projects from. |
125 |
+Projects that do not load a project definition as Emacs Lisp code |
126 |
+are safe, and can be loaded automatically. Other project types, |
127 |
+such as those created with Project.ede files, are safe only if |
128 |
+specified by `ede-project-directories'." |
129 |
+ (setq dir (directory-file-name (expand-file-name dir))) |
130 |
+ ;; Load only if allowed by `ede-project-directories'. |
131 |
+ (or (eq ede-project-directories t) |
132 |
+ (and (functionp ede-project-directories) |
133 |
+ (funcall ede-project-directories dir)) |
134 |
+ (and (listp ede-project-directories) |
135 |
+ (member dir ede-project-directories)))) |
136 |
+ |
137 |
|
138 |
;;; Management variables |
139 |
;; |
140 |
@@ -408,24 +444,42 @@ |
141 |
Sets buffer local variables for EDE." |
142 |
(let* ((ROOT nil) |
143 |
(proj (ede-directory-get-open-project default-directory |
144 |
- 'ROOT))) |
145 |
+ 'ROOT)) |
146 |
+ (projauto nil)) |
147 |
+ |
148 |
(when (or proj ROOT |
149 |
- (ede-directory-project-p default-directory t)) |
150 |
+ ;; If there is no open project, look up the project |
151 |
+ ;; autoloader to see if we should initialize. |
152 |
+ (setq projauto (ede-directory-project-p default-directory t))) |
153 |
+ |
154 |
+ (when (and (not proj) projauto) |
155 |
+ |
156 |
+ ;; No project was loaded, but we have a project description |
157 |
+ ;; object. This means that we can check if it is a safe |
158 |
+ ;; project to load before requesting it to be loaded. |
159 |
+ |
160 |
+ (when (or (oref projauto safe-p) |
161 |
+ ;; The project style is not safe, so check if it is |
162 |
+ ;; in `ede-project-directories'. |
163 |
+ (let ((top (ede-toplevel-project default-directory))) |
164 |
+ (ede-directory-safe-p top))) |
165 |
+ |
166 |
+ ;; The project is safe, so load it in. |
167 |
+ (setq proj (ede-load-project-file default-directory 'ROOT)))) |
168 |
|
169 |
- (when (not proj) |
170 |
- ;; @todo - this could be wasteful. |
171 |
- (setq proj (ede-load-project-file default-directory 'ROOT))) |
172 |
+ ;; Only initialize EDE state in this buffer if we found a project. |
173 |
+ (when proj |
174 |
|
175 |
- (setq ede-object (ede-buffer-object (current-buffer) |
176 |
+ (setq ede-object (ede-buffer-object (current-buffer) |
177 |
'ede-object-project)) |
178 |
|
179 |
- (setq ede-object-root-project |
180 |
- (or ROOT (ede-project-root ede-object-project))) |
181 |
+ (setq ede-object-root-project |
182 |
+ (or ROOT (ede-project-root ede-object-project))) |
183 |
|
184 |
- (if (and (not ede-object) ede-object-project) |
185 |
- (ede-auto-add-to-target)) |
186 |
+ (if (and (not ede-object) ede-object-project) |
187 |
+ (ede-auto-add-to-target)) |
188 |
|
189 |
- (ede-apply-target-options)))) |
190 |
+ (ede-apply-target-options))))) |
191 |
|
192 |
(defun ede-reset-all-buffers (onoff) |
193 |
"Reset all the buffers due to change in EDE. |
194 |
@@ -534,13 +588,73 @@ |
195 |
|
196 |
;;; Interactive method invocations |
197 |
;; |
198 |
-(defun ede (file) |
199 |
- "Start up EDE on something. |
200 |
-Argument FILE is the file or directory to load a project from." |
201 |
- (interactive "fProject File: ") |
202 |
- (if (not (file-exists-p file)) |
203 |
- (ede-new file) |
204 |
- (ede-load-project-file (file-name-directory file)))) |
205 |
+(defun ede (dir) |
206 |
+ "Start up EDE for directory DIR. |
207 |
+If DIR has an existing project file, load it. |
208 |
+Otherwise, create a new project for DIR." |
209 |
+ (interactive |
210 |
+ ;; When choosing a directory to turn on, and we see some directory here, |
211 |
+ ;; provide that as the default. |
212 |
+ (let* ((top (ede-toplevel-project default-directory)) |
213 |
+ (promptdflt (or top default-directory))) |
214 |
+ (list (read-directory-name "Project directory: " |
215 |
+ promptdflt promptdflt t)))) |
216 |
+ (unless (file-directory-p dir) |
217 |
+ (error "%s is not a directory" dir)) |
218 |
+ (when (ede-directory-get-open-project dir) |
219 |
+ (error "%s already has an open project associated with it" dir)) |
220 |
+ |
221 |
+ ;; Check if the directory has been added to the list of safe |
222 |
+ ;; directories. It can also add the directory to the safe list if |
223 |
+ ;; the user chooses. |
224 |
+ (if (ede-check-project-directory dir) |
225 |
+ (progn |
226 |
+ ;; If there is a project in DIR, load it, otherwise do |
227 |
+ ;; nothing. |
228 |
+ (ede-load-project-file dir) |
229 |
+ |
230 |
+ ;; Check if we loaded anything on the previous line. |
231 |
+ (if (ede-current-project dir) |
232 |
+ |
233 |
+ ;; We successfully opened an existing project. Some open |
234 |
+ ;; buffers may also be referring to this project. |
235 |
+ ;; Resetting all the buffers will get them to also point |
236 |
+ ;; at this new open project. |
237 |
+ (ede-reset-all-buffers 1) |
238 |
+ |
239 |
+ ;; ELSE |
240 |
+ ;; There was no project, so switch to `ede-new' which is how |
241 |
+ ;; a user can select a new kind of project to create. |
242 |
+ (let ((default-directory (expand-file-name dir))) |
243 |
+ (call-interactively 'ede-new)))) |
244 |
+ |
245 |
+ ;; If the proposed directory isn't safe, then say so. |
246 |
+ (error "%s is not an allowed project directory in `ede-project-directories'" |
247 |
+ dir))) |
248 |
+ |
249 |
+(defun ede-check-project-directory (dir) |
250 |
+ "Check if DIR should be in `ede-project-directories'. |
251 |
+If it is not, try asking the user if it should be added; if so, |
252 |
+add it and save `ede-project-directories' via Customize. |
253 |
+Return nil iff DIR should not be in `ede-project-directories'." |
254 |
+ (setq dir (directory-file-name (expand-file-name dir))) ; strip trailing / |
255 |
+ (or (eq ede-project-directories t) |
256 |
+ (and (functionp ede-project-directories) |
257 |
+ (funcall ede-project-directories dir)) |
258 |
+ ;; If `ede-project-directories' is a list, maybe add it. |
259 |
+ (when (listp ede-project-directories) |
260 |
+ (or (member dir ede-project-directories) |
261 |
+ (when (y-or-n-p (format "`%s' is not listed in `ede-project-directories'. |
262 |
+Add it to the list of allowed project directories? " |
263 |
+ dir)) |
264 |
+ (push dir ede-project-directories) |
265 |
+ ;; If possible, save `ede-project-directories'. |
266 |
+ (if (or custom-file user-init-file) |
267 |
+ (let ((coding-system-for-read nil)) |
268 |
+ (customize-save-variable |
269 |
+ 'ede-project-directories |
270 |
+ ede-project-directories))) |
271 |
+ t))))) |
272 |
|
273 |
(defun ede-new (type &optional name) |
274 |
"Create a new project starting of project type TYPE. |
275 |
@@ -574,6 +688,11 @@ |
276 |
(error "Cannot create project in non-existent directory %s" default-directory)) |
277 |
(when (not (file-writable-p default-directory)) |
278 |
(error "No write permissions for %s" default-directory)) |
279 |
+ (unless (ede-check-project-directory default-directory) |
280 |
+ (error "%s is not an allowed project directory in `ede-project-directories'" |
281 |
+ default-directory)) |
282 |
+ ;; Make sure the project directory is loadable in the future. |
283 |
+ (ede-check-project-directory default-directory) |
284 |
;; Create the project |
285 |
(let* ((obj (object-assoc type 'name ede-project-class-files)) |
286 |
(nobj (let ((f (oref obj file)) |
287 |
@@ -607,6 +726,10 @@ |
288 |
(ede-add-subproject pp nobj) |
289 |
(ede-commit-project pp))) |
290 |
(ede-commit-project nobj)) |
291 |
+ ;; Once the project is created, load it again. This used to happen |
292 |
+ ;; lazily, but with project loading occurring less often and with |
293 |
+ ;; security in mind, this is now the safe time to reload. |
294 |
+ (ede-load-project-file default-directory) |
295 |
;; Have the menu appear |
296 |
(setq ede-minor-mode t) |
297 |
;; Allert the user |
298 |
@@ -629,11 +752,16 @@ |
299 |
(defun ede-rescan-toplevel () |
300 |
"Rescan all project files." |
301 |
(interactive) |
302 |
- (let ((toppath (ede-toplevel-project default-directory)) |
303 |
- (ede-deep-rescan t)) |
304 |
- (project-rescan (ede-load-project-file toppath)) |
305 |
- (ede-reset-all-buffers 1) |
306 |
- )) |
307 |
+ (if (not (ede-directory-get-open-project default-directory)) |
308 |
+ ;; This directory isn't open. Can't rescan. |
309 |
+ (error "Attempt to rescan a project that isn't open") |
310 |
+ |
311 |
+ ;; Continue |
312 |
+ (let ((toppath (ede-toplevel-project default-directory)) |
313 |
+ (ede-deep-rescan t)) |
314 |
+ |
315 |
+ (project-rescan (ede-load-project-file toppath)) |
316 |
+ (ede-reset-all-buffers 1)))) |
317 |
|
318 |
(defun ede-new-target (&rest args) |
319 |
"Create a new target specific to this type of project file. |
320 |
@@ -877,7 +1005,7 @@ |
321 |
;; Do the load |
322 |
;;(message "EDE LOAD : %S" file) |
323 |
(let* ((file dir) |
324 |
- (path (expand-file-name (file-name-directory file))) |
325 |
+ (path (file-name-as-directory (expand-file-name dir))) |
326 |
(pfc (ede-directory-project-p path)) |
327 |
(toppath nil) |
328 |
(o nil)) |
329 |
@@ -906,13 +1034,11 @@ |
330 |
;; See if its been loaded before |
331 |
(setq o (object-assoc (ede-dir-to-projectfile pfc toppath) 'file |
332 |
ede-projects)) |
333 |
- (if (not o) |
334 |
- ;; If not, get it now. |
335 |
- (let ((ede-constructing pfc)) |
336 |
- (setq o (funcall (oref pfc load-type) toppath)) |
337 |
- (when (not o) |
338 |
- (error "Project type error: :load-type failed to create a project")) |
339 |
- (ede-add-project-to-global-list o))) |
340 |
+ |
341 |
+ ;; If not open yet, load it. |
342 |
+ (unless o |
343 |
+ (let ((ede-constructing pfc)) |
344 |
+ (setq o (ede-auto-load-project pfc toppath)))) |
345 |
|
346 |
;; Return the found root project. |
347 |
(when rootreturn (set rootreturn o)) |
348 |
@@ -967,13 +1093,7 @@ |
349 |
(and root |
350 |
(ede-find-subproject-for-directory root updir)) |
351 |
;; Try the all structure based search. |
352 |
- (ede-directory-get-open-project updir) |
353 |
- ;; Load up the project file as a last resort. |
354 |
- ;; Last resort since it uses file-truename, and other |
355 |
- ;; slow features. |
356 |
- (and (ede-directory-project-p updir) |
357 |
- (ede-load-project-file |
358 |
- (file-name-as-directory updir)))))))))) |
359 |
+ (ede-directory-get-open-project updir)))))))) |
360 |
|
361 |
(defun ede-current-project (&optional dir) |
362 |
"Return the current project file. |
363 |
@@ -987,11 +1107,7 @@ |
364 |
;; No current project. |
365 |
(when (not ans) |
366 |
(let* ((ldir (or dir default-directory))) |
367 |
- (setq ans (ede-directory-get-open-project ldir)) |
368 |
- (or ans |
369 |
- ;; No open project, if this dir pass project-p, then load. |
370 |
- (when (ede-directory-project-p ldir) |
371 |
- (setq ans (ede-load-project-file ldir)))))) |
372 |
+ (setq ans (ede-directory-get-open-project ldir)))) |
373 |
;; Return what we found. |
374 |
ans)) |
375 |
|
376 |
@@ -1047,12 +1163,13 @@ |
377 |
"Return the project which is the parent of TARGET. |
378 |
It is recommended you track the project a different way as this function |
379 |
could become slow in time." |
380 |
- ;; @todo - use ede-object-project as a starting point. |
381 |
- (let ((ans nil) (projs ede-projects)) |
382 |
- (while (and (not ans) projs) |
383 |
- (setq ans (ede-target-in-project-p (car projs) target) |
384 |
- projs (cdr projs))) |
385 |
- ans)) |
386 |
+ (or ede-object-project |
387 |
+ ;; If not cached, derive it from the current directory of the target. |
388 |
+ (let ((ans nil) (projs ede-projects)) |
389 |
+ (while (and (not ans) projs) |
390 |
+ (setq ans (ede-target-in-project-p (car projs) target) |
391 |
+ projs (cdr projs))) |
392 |
+ ans))) |
393 |
|
394 |
(defmethod ede-find-target ((proj ede-project) buffer) |
395 |
"Fetch the target in PROJ belonging to BUFFER or nil." |