diff options
| author | Po Lu | 2022-12-07 19:19:34 +0800 |
|---|---|---|
| committer | Po Lu | 2022-12-07 19:19:46 +0800 |
| commit | 78efe08c0706c2719cb12c7fcd1c8f47386d7b15 (patch) | |
| tree | 6b986396ed9a664dfc72a5ebf9f77e5d20bb9073 /src | |
| parent | 82849f9a20bcc043b23c59905044b7f69d8f54a1 (diff) | |
| download | emacs-78efe08c0706c2719cb12c7fcd1c8f47386d7b15.tar.gz emacs-78efe08c0706c2719cb12c7fcd1c8f47386d7b15.zip | |
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'.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfns.c | 14 | ||||
| -rw-r--r-- | src/xterm.c | 43 | ||||
| -rw-r--r-- | src/xterm.h | 4 |
3 files changed, 57 insertions, 4 deletions
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, | |||
| 2642 | if (existing) | 2642 | if (existing) |
| 2643 | XFree (existing); | 2643 | XFree (existing); |
| 2644 | 2644 | ||
| 2645 | if (!found_wm_ping) | 2645 | if (!dpyinfo->untrusted) |
| 2646 | protos[num_protos++] = dpyinfo->Xatom_net_wm_ping; | 2646 | { |
| 2647 | /* Untrusted clients cannot use these protocols which require | ||
| 2648 | communicating with the window manager. */ | ||
| 2649 | |||
| 2650 | if (!found_wm_ping) | ||
| 2651 | protos[num_protos++] = dpyinfo->Xatom_net_wm_ping; | ||
| 2647 | #if !defined HAVE_GTK3 && defined HAVE_XSYNC | 2652 | #if !defined HAVE_GTK3 && defined HAVE_XSYNC |
| 2648 | if (!found_wm_sync_request && dpyinfo->xsync_supported_p) | 2653 | if (!found_wm_sync_request && dpyinfo->xsync_supported_p) |
| 2649 | protos[num_protos++] = dpyinfo->Xatom_net_wm_sync_request; | 2654 | protos[num_protos++] = dpyinfo->Xatom_net_wm_sync_request; |
| 2650 | #endif | 2655 | #endif |
| 2656 | } | ||
| 2651 | 2657 | ||
| 2652 | if (num_protos) | 2658 | if (num_protos) |
| 2653 | XChangeProperty (dpyinfo->display, | 2659 | 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) | |||
| 26775 | if (!NILP (Vx_no_window_manager)) | 26775 | if (!NILP (Vx_no_window_manager)) |
| 26776 | return false; | 26776 | return false; |
| 26777 | 26777 | ||
| 26778 | /* If the window system says Emacs is untrusted, there will be no | ||
| 26779 | way to send any information to the window manager, making any | ||
| 26780 | hints useless. */ | ||
| 26781 | if (dpyinfo->untrusted) | ||
| 26782 | return false; | ||
| 26783 | |||
| 26778 | block_input (); | 26784 | block_input (); |
| 26779 | 26785 | ||
| 26780 | x_catch_errors (dpy); | 26786 | x_catch_errors (dpy); |
| @@ -29507,6 +29513,7 @@ struct x_display_info * | |||
| 29507 | x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | 29513 | x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) |
| 29508 | { | 29514 | { |
| 29509 | Display *dpy; | 29515 | Display *dpy; |
| 29516 | XKeyboardState keyboard_state; | ||
| 29510 | struct terminal *terminal; | 29517 | struct terminal *terminal; |
| 29511 | struct x_display_info *dpyinfo; | 29518 | struct x_display_info *dpyinfo; |
| 29512 | XrmDatabase xrdb; | 29519 | XrmDatabase xrdb; |
| @@ -29726,6 +29733,32 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 29726 | dpyinfo = xzalloc (sizeof *dpyinfo); | 29733 | dpyinfo = xzalloc (sizeof *dpyinfo); |
| 29727 | terminal = x_create_terminal (dpyinfo); | 29734 | terminal = x_create_terminal (dpyinfo); |
| 29728 | 29735 | ||
| 29736 | if (!NILP (Vx_detect_server_trust)) | ||
| 29737 | { | ||
| 29738 | /* Detect whether or not the X server trusts this client, which | ||
| 29739 | is done by making a SetKeyboardControl request and checking | ||
| 29740 | for an Access error. */ | ||
| 29741 | XGrabServer (dpy); | ||
| 29742 | XGetKeyboardControl (dpy, &keyboard_state); | ||
| 29743 | |||
| 29744 | x_catch_errors (dpy); | ||
| 29745 | |||
| 29746 | /* At this point, the display is not on x_display_list, so | ||
| 29747 | x_uncatch_errors won't sync. However, that's okay because | ||
| 29748 | x_had_errors_p will. */ | ||
| 29749 | |||
| 29750 | if (keyboard_state.global_auto_repeat | ||
| 29751 | == AutoRepeatModeOn) | ||
| 29752 | XAutoRepeatOn (dpy); | ||
| 29753 | else | ||
| 29754 | XAutoRepeatOff (dpy); | ||
| 29755 | |||
| 29756 | if (x_had_errors_p (dpy)) | ||
| 29757 | dpyinfo->untrusted = true; | ||
| 29758 | x_uncatch_errors_after_check (); | ||
| 29759 | XUngrabServer (dpy); | ||
| 29760 | } | ||
| 29761 | |||
| 29729 | dpyinfo->next_failable_request = dpyinfo->failable_requests; | 29762 | dpyinfo->next_failable_request = dpyinfo->failable_requests; |
| 29730 | 29763 | ||
| 29731 | { | 29764 | { |
| @@ -31802,4 +31835,14 @@ select text over slow X connections. | |||
| 31802 | If that is still too slow, setting this variable to the symbol | 31835 | If that is still too slow, setting this variable to the symbol |
| 31803 | `really-fast' will make Emacs return only cached values. */); | 31836 | `really-fast' will make Emacs return only cached values. */); |
| 31804 | Vx_use_fast_mouse_position = Qnil; | 31837 | Vx_use_fast_mouse_position = Qnil; |
| 31838 | |||
| 31839 | DEFVAR_LISP ("x-detect-server-trust", Vx_detect_server_trust, | ||
| 31840 | doc: /* Whether or not Emacs should detect whether or not it is trusted by X. | ||
| 31841 | |||
| 31842 | If non-nil, Emacs will make an X request at connection startup that is | ||
| 31843 | prohibited to untrusted clients under the X Security Extension and | ||
| 31844 | check whether or not a resulting Access error is generated by the X | ||
| 31845 | server. If the X server reports the error, then Emacs will disable | ||
| 31846 | certain features that do not work for untrusted clients. */); | ||
| 31847 | Vx_detect_server_trust = Qnil; | ||
| 31805 | } | 31848 | } |
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 | |||
| 376 | /* Number of frames that are on this display. */ | 376 | /* Number of frames that are on this display. */ |
| 377 | int reference_count; | 377 | int reference_count; |
| 378 | 378 | ||
| 379 | /* True if this client cannot communicate with the window manager | ||
| 380 | because it is untrusted. */ | ||
| 381 | bool untrusted; | ||
| 382 | |||
| 379 | /* The Screen this connection is connected to. */ | 383 | /* The Screen this connection is connected to. */ |
| 380 | Screen *screen; | 384 | Screen *screen; |
| 381 | 385 | ||