Skip to content

Commit

Permalink
Make any temporary decryptions run through /dev/shm when available
Browse files Browse the repository at this point in the history
Apparently epg runs temporary decryption through whatever the
temporary-file-directory is set to. This is /tmp by default and
that is not ideal, to say the least. This means that Emacs gpg
decryptions litter the /tmp directory with plaintext copies of
your gpg files (during a small window when opening or saving).

It does this with a predicatable pattern gpg-output* or gpg-input*
since age.el is a port of epg functionality, it has the same
weakness.

As a stopgap, age.el will run these operations through /dev/shm
when and where it is available. I'll think about how we can do a
buffer-only operation, since in our threat model limiting our
plaintext exposure to emacs memory contents is the best we can
hope for. While someone that has user privileges to monitor e.g.
/dev/shm for file creations can obviously also dump memory from
the emacs process, this would be a more annoying proposition than
placing a filewatch and harvesting plaintext copies of decrypted
files out of a temporary directory.

Making these intermediate writes at least remain memory resident
as opposed to disk resident when /dev/shm is an option is a
reasonable first step I reckon.

I'll note that memory contents can/will be flushed to disk
in a variety of scenarios, but I don't like the idea of such a
simple harvesting mechanism being available by default.

I think I should be able to just rework it such that everything runs
over process stdio as opposed to intermediate plaintext files.
  • Loading branch information
anticomputer committed Dec 31, 2022
1 parent 640e8c9 commit 63e9b15
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions age.el
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,14 @@ or higher is installed."

;;;; Context Methods

(cl-defmacro age-with-dev-shm (&body body)
"Bind temporary-file-directory to /dev/shm if it exists."
`(let ((temporary-file-directory
(if (file-directory-p "/dev/shm/")
"/dev/shm/"
,temporary-file-directory)))
,@body))

;; This is not an alias, just so we can mark it as autoloaded.
;;;###autoload
(defun age-make-context (&optional protocol armor)
Expand Down Expand Up @@ -592,7 +600,7 @@ If PLAIN is nil, it returns the result as a string."
(unwind-protect
(progn
(setf (age-context-output-file context)
(or plain (make-temp-file "age-output")))
(or plain (age-with-dev-shm (make-temp-file "age-output"))))
(age-start-decrypt context (age-make-data-from-file cipher))
(age-wait-for-completion context)
(age--check-error-for-decrypt context)
Expand All @@ -604,13 +612,13 @@ If PLAIN is nil, it returns the result as a string."

(defun age-decrypt-string (context cipher)
"Decrypt a string CIPHER and return the plain text."
(let ((input-file (make-temp-file "age-input"))
(let ((input-file (age-with-dev-shm (make-temp-file "age-input")))
(coding-system-for-write 'binary))
(unwind-protect
(progn
(write-region cipher nil input-file nil 'quiet)
(setf (age-context-output-file context)
(make-temp-file "age-output"))
(age-with-dev-shm (make-temp-file "age-output")))
(age-start-decrypt context (age-make-data-from-file input-file))
(age-wait-for-completion context)
(age--check-error-for-decrypt context)
Expand Down Expand Up @@ -678,7 +686,7 @@ If RECIPIENTS is nil, it performs symmetric encryption."
(unwind-protect
(progn
(setf (age-context-output-file context)
(or cipher (make-temp-file "age-output")))
(or cipher (age-with-dev-shm (make-temp-file "age-output"))))
(age-start-encrypt context (age-make-data-from-file plain) recipients)
(age-wait-for-completion context)
(let ((errors (age-context-result-for context 'error)))
Expand All @@ -697,12 +705,12 @@ If RECIPIENTS is nil, it performs symmetric encryption."
(let ((input-file
;; XXX: this is always true, but keep the protocol flexibility for now
(when (eq (age-context-protocol context) 'Age)
(make-temp-file "age-input")))
(age-with-dev-shm (make-temp-file "age-input"))))
(coding-system-for-write 'binary))
(unwind-protect
(progn
(setf (age-context-output-file context)
(make-temp-file "age-output"))
(age-with-dev-shm (make-temp-file "age-output")))
(if input-file
(write-region plain nil input-file nil 'quiet))
(age-start-encrypt context
Expand Down

0 comments on commit 63e9b15

Please sign in to comment.