9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] Bug: CVE-2018-16509 affecting 9front ghostscript
@ 2019-05-23  0:35 Jacob Moody
  0 siblings, 0 replies; 2+ messages in thread
From: Jacob Moody @ 2019-05-23  0:35 UTC (permalink / raw)
  To: 9front

[-- Attachment #1: Type: text/plain, Size: 7009 bytes --]

All,

I found that CVE-2018-16509 can be used to get arbitrary code execution on
9front with the following input:
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: -0 -0 100 100

/lock
userdict /setpagedevice undef
legal
{ null restore } stopped { pop } if
legal
mark /OutputFile (%pipe%window) currentdevice putdeviceprops

Running that through page executes the command passed to %pipe%.
I've isolated the upstream changes that fix this specific bug, here's the
diff for it:

diff -r 13cc4ad135d6 sys/src/cmd/gs/lib/gs_init.ps
--- a/sys/src/cmd/gs/lib/gs_init.ps    Fri May 17 01:53:27 2019 +0200
+++ b/sys/src/cmd/gs/lib/gs_init.ps    Wed May 22 19:25:31 2019 -0500
@@ -1992,6 +1992,18 @@
 % If we are running in SAFER mode, lock things down
 SAFER { .setsafe } if

+/UndefinePostScriptOperators {
+[
+/condition /currentcontext /detach /.fork /join /.localfork /lock /monitor
/notify
+/wait /yield /.currentscreenphase /.setscreenphase /.image2 /eoviewclip
/initviewclip
+/viewclip /viewclippath /defineusername
+/currentalpha /setalpha /.alphaimage /composite /compositerect /dissolve
/sizeimagebox /.sizeimageparams
+]
+{systemdict exch .forceundef} forall
+
+//systemdict /UndefinePostScriptOperators .forceundef
+} bind def
+
 % If we delayed binding, make it possible to do it later.
 /.bindnow {
   currentuserparams /IdiomRecognition .knownget {
@@ -2005,6 +2017,7 @@
   //systemdict /.delaybind {} .forceput    % reclaim the space
   //systemdict /.bindnow .forceundef    % ditto
   put
+  //systemdict /UndefinePostScriptOperators get exec
   //systemdict /.forcedef .forceundef        % remove temptation
   //systemdict /.forceput .forceundef        % ditto
   //systemdict /.forceundef .forceundef        % ditto
diff -r 13cc4ad135d6 sys/src/cmd/gs/src/gsdevice.c
--- a/sys/src/cmd/gs/src/gsdevice.c    Fri May 17 01:53:27 2019 +0200
+++ b/sys/src/cmd/gs/src/gsdevice.c    Wed May 22 19:25:31 2019 -0500
@@ -480,19 +480,29 @@
 int
 gs_nulldevice(gs_state * pgs)
 {
+    int code = 0;
+
+    int saveLockSafety = false;
     if (pgs->device == 0 || !gx_device_is_null(pgs->device)) {
     gx_device *ndev;
-    int code = gs_copydevice(&ndev, (const gx_device *)&gs_null_device,
-                 pgs->memory);
+    code = gs_copydevice(&ndev, (const gx_device *)&gs_null_device,
+           pgs->memory);

     if (code < 0)
         return code;
+
+    if (gs_currentdevice_inline(pgs) != NULL)
+        saveLockSafety = gs_currentdevice_inline(pgs)->LockSafetyParams;
+
     /*
      * Internal devices have a reference count of 0, not 1,
      * aside from references from graphics states.
      */
     rc_init(ndev, pgs->memory, 0);
-    return gs_setdevice_no_erase(pgs, ndev);
+
+    if ((code = gs_setdevice_no_erase(pgs, ndev)) < 0)
+        gs_free_object(pgs->memory, ndev, "gs_copydevice(device)");
+    gs_currentdevice_inline(pgs)->LockSafetyParams = saveLockSafety;
     }
     return 0;
 }
diff -r 13cc4ad135d6 sys/src/cmd/gs/src/isave.h
--- a/sys/src/cmd/gs/src/isave.h    Fri May 17 01:53:27 2019 +0200
+++ b/sys/src/cmd/gs/src/isave.h    Wed May 22 19:25:31 2019 -0500
@@ -116,4 +116,8 @@
 /* Remove entries from font and character caches. */
 void font_restore(const alloc_save_t * save);

+int restore_check_save(i_ctx_t *i_ctx_p, alloc_save_t **asave);
+
+int dorestore(i_ctx_t *i_ctx_p, alloc_save_t *asave);
+
 #endif /* isave_INCLUDED */
diff -r 13cc4ad135d6 sys/src/cmd/gs/src/zdevice2.c
--- a/sys/src/cmd/gs/src/zdevice2.c    Fri May 17 01:53:27 2019 +0200
+++ b/sys/src/cmd/gs/src/zdevice2.c    Wed May 22 19:25:31 2019 -0500
@@ -27,6 +27,7 @@
 #include "igstate.h"
 #include "iname.h"
 #include "iutil.h"
+#include "isave.h"
 #include "store.h"
 #include "gxdevice.h"
 #include "gsstate.h"
@@ -312,6 +313,12 @@
 private int
 z2restore(i_ctx_t *i_ctx_p)
 {
+    alloc_save_t *asave;
+    bool saveLockSafety = gs_currentdevice_inline(igs)->LockSafetyParams;
+    int code = restore_check_save(i_ctx_p, &asave);
+
+    if (code < 0) return code;
+
     while (gs_state_saved(gs_state_saved(igs))) {
     if (restore_page_device(igs, gs_state_saved(igs)))
         return push_callout(i_ctx_p, "%restore1pagedevice");
@@ -319,7 +326,13 @@
     }
     if (restore_page_device(igs, gs_state_saved(igs)))
     return push_callout(i_ctx_p, "%restorepagedevice");
-    return zrestore(i_ctx_p);
+
+    code = dorestore(i_ctx_p, asave);
+
+    if (code < 0)
+        gs_currentdevice_inline(igs)->LockSafetyParams = saveLockSafety;
+
+    return code;
 }

 /* <gstate> setgstate - */
diff -r 13cc4ad135d6 sys/src/cmd/gs/src/zvmem.c
--- a/sys/src/cmd/gs/src/zvmem.c    Fri May 17 01:53:27 2019 +0200
+++ b/sys/src/cmd/gs/src/zvmem.c    Wed May 22 19:25:31 2019 -0500
@@ -102,35 +102,46 @@
 private int restore_check_operand(os_ptr, alloc_save_t **,
gs_dual_memory_t *);
 private int restore_check_stack(const ref_stack_t *, const alloc_save_t *,
bool);
 private void restore_fix_stack(ref_stack_t *, const alloc_save_t *, bool);
+
 int
-zrestore(i_ctx_t *i_ctx_p)
+restore_check_save(i_ctx_t *i_ctx_p, alloc_save_t **asave)
 {
     os_ptr op = osp;
-    alloc_save_t *asave;
-    bool last;
-    vm_save_t *vmsave;
-    int code = restore_check_operand(op, &asave, idmemory);
+    int code = restore_check_operand(op, asave, idmemory);

     if (code < 0)
-    return code;
+        return code;
     if_debug2('u', "[u]vmrestore 0x%lx, id = %lu\n",
-          (ulong) alloc_save_client_data(asave),
+          (ulong) alloc_save_client_data(*asave),
           (ulong) op->value.saveid);
     if (I_VALIDATE_BEFORE_RESTORE)
     ivalidate_clean_spaces(i_ctx_p);
     /* Check the contents of the stacks. */
     osp--;
     {
+        int code;
+
+        if ((code = restore_check_stack(&o_stack, *asave, false)) < 0 ||
+            (code = restore_check_stack(&e_stack, *asave, true)) < 0 ||
+            (code = restore_check_stack(&d_stack, *asave, false)) < 0
+            ) {
+            osp++;
+            return code;
+        }
+    }
+    osp++;
+    return 0;
+}
+
+int
+dorestore(i_ctx_t *i_ctx_p, alloc_save_t *asave)
+{
+    os_ptr op = osp;
+    bool last;
+    vm_save_t *vmsave;
     int code;
+    osp--;

-    if ((code = restore_check_stack(&o_stack, asave, false)) < 0 ||
-        (code = restore_check_stack(&e_stack, asave, true)) < 0 ||
-        (code = restore_check_stack(&d_stack, asave, false)) < 0
-        ) {
-        osp++;
-        return code;
-    }
-    }
     /* Reset l_new in all stack entries if the new save level is zero. */
     /* Also do some special fixing on the e-stack. */
     restore_fix_stack(&o_stack, asave, false);
@@ -173,6 +184,17 @@
     i_ctx_p->LockFilePermissions = false;
     return 0;
 }
+
+int
+zrestore(i_ctx_t *i_ctx_p)
+{
+    alloc_save_t *asave;
+    int code = restore_check_save(i_ctx_p, &asave);
+    if (code < 0)
+        return code;
+    return dorestore(i_ctx_p, asave);
+}
+
 /* Check the operand of a restore. */
 private int
 restore_check_operand(os_ptr op, alloc_save_t ** pasave,



Thanks,

Moody

[-- Attachment #2: Type: text/html, Size: 8796 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [9front] Bug: CVE-2018-16509 affecting 9front ghostscript
@ 2019-05-23 12:59 cinap_lenrek
  0 siblings, 0 replies; 2+ messages in thread
From: cinap_lenrek @ 2019-05-23 12:59 UTC (permalink / raw)
  To: 9front

applied. thank you.

--
cinap


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-05-23 12:59 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-23  0:35 [9front] Bug: CVE-2018-16509 affecting 9front ghostscript Jacob Moody
2019-05-23 12:59 cinap_lenrek

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 NNTP newsgroup(s).