emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 78efe08c070: Fix some more problems with running Emacs as untrust


From: Po Lu
Subject: master 78efe08c070: Fix some more problems with running Emacs as untrusted
Date: Wed, 7 Dec 2022 06:20:17 -0500 (EST)

branch: master
commit 78efe08c0706c2719cb12c7fcd1c8f47386d7b15
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Fix some more problems with running Emacs as untrusted
    
    * etc/PROBLEMS (X security problems): Describe new variable.
    * src/xfns.c (append_wm_protocols): Don't support ping when it
    does not work.
    * src/xterm.c (x_wm_supports_1): Don't support anything when
    untrusted.
    (x_term_init): Implement Vx_detect_server_trust.
    (syms_of_xterm): New variable `x-detect-server-trust'.
    * src/xterm.h (struct x_display_info): New field `untrusted'.
---
 etc/PROBLEMS | 14 ++++++++++++++
 src/xfns.c   | 14 ++++++++++----
 src/xterm.c  | 43 +++++++++++++++++++++++++++++++++++++++++++
 src/xterm.h  |  4 ++++
 4 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index 2169ed0f80b..68f7cdb0560 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -1227,6 +1227,20 @@ you should use an Emacs input method instead.
 
 * X runtime problems
 
+** X security problems
+
+*** Emacs faces trouble when running as an untrusted client.
+
+When Emacs is running as an untrusted client under X servers with the
+Security extension, it is unable to use some window manager features
+but reports them to the window manager anyway.  This can lead to
+constant prompting by the window manager about Emacs being
+unresponsive.  To resolve the problem, place:
+
+  (setq x-detect-server-trust t)
+
+in your early-init.el.
+
 ** X keyboard problems
 
 *** `x-focus-frame' fails to activate the frame.
diff --git a/src/xfns.c b/src/xfns.c
index 9951ced6611..2bf282fd243 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -2642,12 +2642,18 @@ append_wm_protocols (struct x_display_info *dpyinfo,
   if (existing)
     XFree (existing);
 
-  if (!found_wm_ping)
-    protos[num_protos++] = dpyinfo->Xatom_net_wm_ping;
+  if (!dpyinfo->untrusted)
+    {
+      /* Untrusted clients cannot use these protocols which require
+        communicating with the window manager.  */
+
+      if (!found_wm_ping)
+       protos[num_protos++] = dpyinfo->Xatom_net_wm_ping;
 #if !defined HAVE_GTK3 && defined HAVE_XSYNC
-  if (!found_wm_sync_request && dpyinfo->xsync_supported_p)
-    protos[num_protos++] = dpyinfo->Xatom_net_wm_sync_request;
+      if (!found_wm_sync_request && dpyinfo->xsync_supported_p)
+       protos[num_protos++] = dpyinfo->Xatom_net_wm_sync_request;
 #endif
+    }
 
   if (num_protos)
     XChangeProperty (dpyinfo->display,
diff --git a/src/xterm.c b/src/xterm.c
index f446d093ef4..f2dbff1c446 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -26775,6 +26775,12 @@ x_wm_supports_1 (struct x_display_info *dpyinfo, Atom 
want_atom)
   if (!NILP (Vx_no_window_manager))
     return false;
 
+  /* If the window system says Emacs is untrusted, there will be no
+     way to send any information to the window manager, making any
+     hints useless.  */
+  if (dpyinfo->untrusted)
+    return false;
+
   block_input ();
 
   x_catch_errors (dpy);
@@ -29507,6 +29513,7 @@ struct x_display_info *
 x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 {
   Display *dpy;
+  XKeyboardState keyboard_state;
   struct terminal *terminal;
   struct x_display_info *dpyinfo;
   XrmDatabase xrdb;
@@ -29726,6 +29733,32 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
   dpyinfo = xzalloc (sizeof *dpyinfo);
   terminal = x_create_terminal (dpyinfo);
 
+  if (!NILP (Vx_detect_server_trust))
+    {
+      /* Detect whether or not the X server trusts this client, which
+        is done by making a SetKeyboardControl request and checking
+        for an Access error.  */
+      XGrabServer (dpy);
+      XGetKeyboardControl (dpy, &keyboard_state);
+
+      x_catch_errors (dpy);
+
+      /* At this point, the display is not on x_display_list, so
+        x_uncatch_errors won't sync.  However, that's okay because
+        x_had_errors_p will.  */
+
+      if (keyboard_state.global_auto_repeat
+         == AutoRepeatModeOn)
+       XAutoRepeatOn (dpy);
+      else
+       XAutoRepeatOff (dpy);
+
+      if (x_had_errors_p (dpy))
+       dpyinfo->untrusted = true;
+      x_uncatch_errors_after_check ();
+      XUngrabServer (dpy);
+    }
+
   dpyinfo->next_failable_request = dpyinfo->failable_requests;
 
   {
@@ -31802,4 +31835,14 @@ select text over slow X connections.
 If that is still too slow, setting this variable to the symbol
 `really-fast' will make Emacs return only cached values.  */);
   Vx_use_fast_mouse_position = Qnil;
+
+  DEFVAR_LISP ("x-detect-server-trust", Vx_detect_server_trust,
+    doc: /* Whether or not Emacs should detect whether or not it is trusted by 
X.
+
+If non-nil, Emacs will make an X request at connection startup that is
+prohibited to untrusted clients under the X Security Extension and
+check whether or not a resulting Access error is generated by the X
+server.  If the X server reports the error, then Emacs will disable
+certain features that do not work for untrusted clients.  */);
+  Vx_detect_server_trust = Qnil;
 }
diff --git a/src/xterm.h b/src/xterm.h
index fae40930e9b..c3bd647b6f3 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -376,6 +376,10 @@ struct x_display_info
   /* Number of frames that are on this display.  */
   int reference_count;
 
+  /* True if this client cannot communicate with the window manager
+     because it is untrusted.  */
+  bool untrusted;
+
   /* The Screen this connection is connected to.  */
   Screen *screen;
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]