]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix some more problems with running Emacs as untrusted
authorPo Lu <luangruo@yahoo.com>
Wed, 7 Dec 2022 11:19:34 +0000 (19:19 +0800)
committerPo Lu <luangruo@yahoo.com>
Wed, 7 Dec 2022 11:19:46 +0000 (19:19 +0800)
* 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
src/xfns.c
src/xterm.c
src/xterm.h

index 2169ed0f80b70064f730594036247d55b1011d6e..68f7cdb05600d2dccf81affb1bf80b68b93cebfd 100644 (file)
@@ -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.
index 9951ced661101152a1f7b56cfe6f4e85daa12964..2bf282fd24365c0c1dff88cfca407e8a18f44ed6 100644 (file)
@@ -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,
index f446d093ef4cd785c54c78816b22605106ef00ee..f2dbff1c446dbb93663427083fe2ed908814dc07 100644 (file)
@@ -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;
 }
index fae40930e9b7ff360d769cafb435b2e5a96575bb..c3bd647b6f32660866b497bb867a9a3b94976fec 100644 (file)
@@ -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;