From e59216049cac290fb437a04c4f41ea46826cfba5 Mon Sep 17 00:00:00 2001
From: Ken Sharp <ken.sharp@artifex.com>
Date: Thu, 24 Aug 2023 15:24:35 +0100
Subject: [PATCH 01/44] IJS device - try and secure the IJS server startup

Bug #707051 ""ijs" device can execute arbitrary commands"

The problem is that the 'IJS' device needs to start the IJS server, and
that is indeed an arbitrary command line. There is (apparently) no way
to validate it. Indeed, this is covered quite clearly in the comments
at the start of the source:

 * WARNING: The ijs server can be selected on the gs command line
 * which is a security risk, since any program can be run.

Previously this used the awful LockSafetyParams hackery, which we
abandoned some time ago because it simply couldn't be made secure (it
was implemented in PostScript and was therefore vulnerable to PostScript
programs).

This commit prevents PostScript programs switching to the IJS device
after SAFER has been activated, and prevents changes to the IjsServer
parameter after SAFER has been activated.

SAFER is activated, unless explicitly disabled, before any user
PostScript is executed which means that the device and the server
invocation can only be configured on the command line. This does at
least provide minimal security against malicious PostScript programs.
---
 devices/gdevijs.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/devices/gdevijs.c b/devices/gdevijs.c
index 8cbd84b97..16f5a1752 100644
--- a/devices/gdevijs.c
+++ b/devices/gdevijs.c
@@ -938,6 +938,8 @@ gsijs_initialize_device(gx_device *dev)
     if(code < 0)
         return code;

+    if (ijsdev->memory->gs_lib_ctx->core->path_control_active)
+        return_error(gs_error_invalidaccess);
     if (!ijsdev->ColorSpace) {
         ijsdev->ColorSpace = gs_malloc(ijsdev->memory, sizeof(rgb), 1,
                 "gsijs_finish_copydevice");
@@ -1326,7 +1328,7 @@ gsijs_put_params(gx_device *dev, gs_param_list *plist)
     if (code >= 0)
         code = gsijs_read_string(plist, "IjsServer",
             ijsdev->IjsServer, sizeof(ijsdev->IjsServer),
-            dev->LockSafetyParams, is_open);
+            ijsdev->memory->gs_lib_ctx->core->path_control_active, is_open);
 
     if (code >= 0)
         code = gsijs_read_string_malloc(plist, "DeviceManufacturer",
-- 
2.33.0

     if(code < 0)
         return code;

+    if (ijsdev->memory->gs_lib_ctx->core->path_control_active)
+        return_error(gs_error_invalidaccess);
+    if (ijsdev->memory->gs_lib_ctx->core->path_control_active)
+        return_error(gs_error_invalidaccess);
     if (!ijsdev->ColorSpace) {
     if (!ijsdev->ColorSpace) {
         ijsdev->ColorSpace = gs_malloc(ijsdev->memory, sizeof(rgb), 1,
         ijsdev->ColorSpace = gs_malloc(ijsdev->memory, sizeof(rgb), 1,
                 "gsijs_finish_copydevice");
                                        "gsijs_initialize");
