From: lux <lx@shellcodes.org>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 61709@debbugs.gnu.org
Subject: bug#61709: [PATCH] Security hardening: safely invoke `shell-command*' function.
Date: Thu, 23 Feb 2023 21:17:12 +0800 [thread overview]
Message-ID: <tencent_84BAE1E5C1009C08331835C035527704F208@qq.com> (raw)
In-Reply-To: <83y1opra5o.fsf@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 2700 bytes --]
On Wed, 2023-02-22 at 17:29 +0200, Eli Zaretskii wrote:
> > Cc: Xi Lu <lx@shellcodes.org>
> > From: Xi Lu <lx@shellcodes.org>
> > Date: Wed, 22 Feb 2023 22:35:54 +0800
> >
> > (defun filesets-which-command-p (cmd)
> > "Call \"which CMD\" and return non-nil if the command was
> > found."
> > @@ -1264,9 +1265,11 @@ filesets-spawn-external-viewer
> > (funcall vwr file)
> > nil)
> > (co-flag
> > - (shell-command-to-string (format "%s %s" vwr
> > args)))
> > + (shell-command-to-string (shell-quote-argument
> > + (format "%s %s" vwr
> > args))))
> > (t
> > - (shell-command (format "%s %s&" vwr args))
> > + (shell-command (shell-quote-argument
> > + (format "%s %s&" vwr args)))
> > nil))))
>
> These two cannot be right: you are quoting several separate
> command-line arguments.
>
> > (if co-flag
> > (progn
> > @@ -1578,7 +1581,7 @@ filesets-run-cmd
> > " "))
> > (cmd (concat fn " " args)))
> > (filesets-cmd-show-result
> > - cmd (shell-command-to-string cmd))))
> > + cmd (shell-command-to-string (shell-
> > quote-argument cmd)))))
> > ((symbolp fn)
> > (apply fn
> > (mapcan (lambda (this)
>
> I think this is also wrong: cmd is not a single word.
>
> In general, you cannot quote arbitrary parts of a shell command, you
> can only quote each command-line argument separately.
>
>
>
You're right, thank you. I rewrited this patch.
Let me briefly explain this patch:
1. I think `filesets-select-command' not need fixed, because it not
used, and I cleaned up relevant old comments in `filesets-external-
viewers'.
2. Using `shell-quote-argument' to replace `filesets-quote' and
`(format "%S" ...)'. Because in the shell, double quotation marks can
still execute unexpected code, such as $(), `command` and $var.
[-- Attachment #2: 0001-Security-hardening-safely-invoke-shell-command-funct.patch --]
[-- Type: text/x-patch, Size: 3960 bytes --]
From 6b85abb2de545094a3725d003a4ddb744b1e1eec Mon Sep 17 00:00:00 2001
From: Xi Lu <lx@shellcodes.org>
Date: Thu, 23 Feb 2023 20:58:00 +0800
Subject: [PATCH] Security hardening: safely invoke `shell-command*' function.
* lisp/filesets.el:
(filesets-select-command, filesets-quote): Remove unused function.
(filesets-external-viewers): Remove old comments.
(filesets-which-command, filesets-get-quoted-selection,
filesets-spawn-external-viewer): Add `shell-quote-argument'.
---
lisp/filesets.el | 40 +++++++++-------------------------------
1 file changed, 9 insertions(+), 31 deletions(-)
diff --git a/lisp/filesets.el b/lisp/filesets.el
index 1b7e6ffa81f..c4d51ccaf4a 100644
--- a/lisp/filesets.el
+++ b/lisp/filesets.el
@@ -161,18 +161,9 @@ 'filesets-some
(define-obsolete-function-alias 'filesets-member #'cl-member "28.1")
(define-obsolete-function-alias 'filesets-sublist #'seq-subseq "28.1")
-(defun filesets-select-command (cmd-list)
- "Select one command from CMD-LIST -- a string with space separated names."
- (let ((this (shell-command-to-string
- (format "which --skip-alias %s 2> %s | head -n 1"
- cmd-list null-device))))
- (if (equal this "")
- nil
- (file-name-nondirectory (substring this 0 (- (length this) 1))))))
-
(defun filesets-which-command (cmd)
"Call \"which CMD\"."
- (shell-command-to-string (format "which %s" cmd)))
+ (shell-command-to-string (format "which %s" (shell-quote-argument cmd))))
(defun filesets-which-command-p (cmd)
"Call \"which CMD\" and return non-nil if the command was found."
@@ -551,16 +542,6 @@ filesets-commands
(defcustom filesets-external-viewers
(let
- ;; ((ps-cmd (or (and (boundp 'my-ps-viewer) my-ps-viewer)
- ;; (filesets-select-command "ggv gv")))
- ;; (pdf-cmd (or (and (boundp 'my-ps-viewer) my-pdf-viewer)
- ;; (filesets-select-command "xpdf acroread")))
- ;; (dvi-cmd (or (and (boundp 'my-ps-viewer) my-dvi-viewer)
- ;; (filesets-select-command "xdvi tkdvi")))
- ;; (doc-cmd (or (and (boundp 'my-ps-viewer) my-doc-viewer)
- ;; (filesets-select-command "antiword")))
- ;; (pic-cmd (or (and (boundp 'my-ps-viewer) my-pic-viewer)
- ;; (filesets-select-command "gqview ee display"))))
((ps-cmd "ggv")
(pdf-cmd "xpdf")
(dvi-cmd "xdvi")
@@ -1089,10 +1070,6 @@ filesets-directory-files
(t
(error "Filesets: %s does not exist" dir))))
-(defun filesets-quote (txt)
- "Return TXT in quotes."
- (concat "\"" txt "\""))
-
(defun filesets-get-selection ()
"Get the text between mark and point -- i.e. the selection or region."
(let ((m (mark))
@@ -1103,7 +1080,7 @@ filesets-get-selection
(defun filesets-get-quoted-selection ()
"Return the currently selected text in quotes."
- (filesets-quote (filesets-get-selection)))
+ (shell-quote-argument (filesets-get-selection)))
(defun filesets-get-shortcut (n)
"Create menu shortcuts based on number N."
@@ -1250,12 +1227,13 @@ filesets-spawn-external-viewer
(if fmt
(mapconcat
(lambda (this)
- (if (stringp this) (format this file)
- (format "%S" (if (functionp this)
- (funcall this)
- this))))
+ (if (stringp this)
+ (format this (shell-quote-argument file))
+ (shell-quote-argument (if (functionp this)
+ (funcall this)
+ this))))
fmt "")
- (format "%S" file))))
+ (shell-quote-argument file))))
(output
(cond
((and (functionp vwr) co-flag)
@@ -1264,7 +1242,7 @@ filesets-spawn-external-viewer
(funcall vwr file)
nil)
(co-flag
- (shell-command-to-string (format "%s %s" vwr args)))
+ (shell-command-to-string (format "%s %s" vwr args)))
(t
(shell-command (format "%s %s&" vwr args))
nil))))
--
2.39.2
next prev parent reply other threads:[~2023-02-23 13:17 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-22 14:35 bug#61709: [PATCH] Security hardening: safely invoke `shell-command*' function Xi Lu
2023-02-22 15:29 ` Eli Zaretskii
2023-02-23 13:17 ` lux [this message]
2023-02-23 15:58 ` Eli Zaretskii
2024-02-05 7:29 ` Stefan Kangas
2024-02-05 6:13 ` lux
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tencent_84BAE1E5C1009C08331835C035527704F208@qq.com \
--to=lx@shellcodes.org \
--cc=61709@debbugs.gnu.org \
--cc=eliz@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).