neutrinolabs / xrdp

xrdp: an open source RDP server
http://www.xrdp.org/
Apache License 2.0
5.75k stars 1.73k forks source link

xrdp-sesman multi-user login CPU 100%, and xrdp-sesadmin error #2882

Closed tsz8899 closed 10 months ago

tsz8899 commented 10 months ago

xrdp version

devel

Detailed xrdp version, build options

xrdp will be compiled with:

  mp3lame                 no
  opus                    no
  fdkaac                  no
  jpeg                    no
  turbo jpeg              no
  rfxcodec                yes
  painter                 yes
  pixman                  no
  fuse                    no
  ipv6                    no
  ipv6only                no
  vsock                   no
  auth mechanism          PAM
  rdpsndaudin             no

  with imlib2             no
  with freetype2          no

  development logging     no
  development streamcheck no

  strict_locations        no
  prefix                  /usr/local
  exec_prefix             ${prefix}
  libdir                  ${exec_prefix}/lib
  bindir                  ${exec_prefix}/bin
  sysconfdir              /etc
  pamconfdir              /etc/pam.d
  localstatedir           /var
  runstatedir             ${localstatedir}/run
  socketdir               ${localstatedir}/run/xrdp

  unit tests performable  no

  CFLAGS = -g -O2 -Wall -Wwrite-strings -Werror
  LDFLAGS =

Operating system & version

debian 11 ubuntu 22.04

Installation method

git clone & make install

Which backend do you use?

xorgxrdp

What desktop environment do you use?

any

Environment xrdp running on

VM

What's your client?

mstsc freerdp

Area(s) with issue?

Session manager (sesman)

Steps to reproduce

XRDP awesome

2023 may 2 (https://github.com/neutrinolabs/xrdp/commit/82ede293886094dc5438fa4db8136e0ed2e36dd5) The previous version of xrdp-sesman worked fine.

New files for sesexec 8853b1c4eeca0002a066ff7cb622353fcfd01957 After this version, xrdp-sesman error state:

  1. Everything works fine when there is only 1 user login XRDP. after the second user login to XRDP, Xwindows can be used normally, but xrdp-sesman process CPU usage 100%. Output of strace -p 13117 (xrdp-sesman):
    getsockname(16, {sa_family=AF_INET6, sin6_port=htons(6211), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [112->28]) = 0
    close(16)                               = 0
    umask(027)                              = 022
    stat("/var/run/xrdp/1001", {st_mode=S_IFDIR|0750, st_size=40, ...}) = 0
    chown("/var/run/xrdp/1001", 1001, 0)    = 0
    umask(022)                              = 027
    sendmsg(15, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\2\0 \0\2\0\3\0\0\0\0\0hu\v\0\0\0y\1q\0\4q\0\3y\30s\0s\0", iov_len=32}], msg_iovlen=1, msg_control=[{cmsg_len=20, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, cmsg_data=[13]}], msg_controllen=24, msg_flags=0}, 0) = 32
    getsockname(13, {sa_family=AF_UNIX, sun_path="/var/run/xrdp/sesman.socket"}, [112->30]) = 0
    close(13)                               = 0
    poll([{fd=14, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=4, events=POLLIN}, {fd=6, events=POLLIN}, {fd=8, events=POLLIN}, {fd=12, events=POLLIN}, {fd=14, events=POLLIN}, {fd=15, events=POLLIN}], 6, -1) = 1 ([{fd=15, revents=POLLIN}])
    poll([{fd=4, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=8, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=12, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=14, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=4, events=POLLIN}, {fd=6, events=POLLIN}, {fd=8, events=POLLIN}, {fd=12, events=POLLIN}, {fd=14, events=POLLIN}, {fd=15, events=POLLIN}], 6, -1) = 1 ([{fd=15, revents=POLLIN}])
    poll([{fd=4, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=8, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=12, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=14, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=4, events=POLLIN}, {fd=6, events=POLLIN}, {fd=8, events=POLLIN}, {fd=12, events=POLLIN}, {fd=14, events=POLLIN}, {fd=15, events=POLLIN}], 6, -1) = 1 ([{fd=15, revents=POLLIN}])
    poll([{fd=4, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=8, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=12, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=14, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=4, events=POLLIN}, {fd=6, events=POLLIN}, {fd=8, events=POLLIN}, {fd=12, events=POLLIN}, {fd=14, events=POLLIN}, {fd=15, events=POLLIN}], 6, -1) = 1 ([{fd=15, revents=POLLIN}])
    poll([{fd=4, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=8, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=12, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=14, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=4, events=POLLIN}, {fd=6, events=POLLIN}, {fd=8, events=POLLIN}, {fd=12, events=POLLIN}, {fd=14, events=POLLIN}, {fd=15, events=POLLIN}], 6, -1) = 1 ([{fd=15, revents=POLLIN}])
    poll([{fd=4, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=8, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=12, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=14, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=4, events=POLLIN}, {fd=6, events=POLLIN}, {fd=8, events=POLLIN}, {fd=12, events=POLLIN}, {fd=14, events=POLLIN}, {fd=15, events=POLLIN}], 6, -1) = 1 ([{fd=15, revents=POLLIN}])
    poll([{fd=4, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=8, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=12, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=14, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=4, events=POLLIN}, {fd=6, events=POLLIN}, {fd=8, events=POLLIN}, {fd=12, events=POLLIN}, {fd=14, events=POLLIN}, {fd=15, events=POLLIN}], 6, -1) = 1 ([{fd=15, revents=POLLIN}])
    poll([{fd=4, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=6, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=8, events=POLLIN}], 1, 0)     = 0 (Timeout)
    poll([{fd=12, events=POLLIN}], 1, 0)    = 0 (Timeout)
    poll([{fd=14, events=POLLIN}], 1, 0)    = 0 (Timeout)
    ........loop

2.There is also a strange issue with xrdp-sesadmin with multiple users:

user1#xrdp-sesadmin -c=list
Session ID: 25553
        Display: :10
        User: user1
        Session type: Xorg
        Screen size: 1024x768, color depth 24

user2#xrdp-sesadmin -c=list
No sessions.

user3#xrdp-sesadmin -c=list   
Session ID: 28856
        Display: :12
        User: user3
        Session type: Xorg
        Screen size: 1024x768, color depth 24

user4#xrdp-sesadmin -c=list
No sessions.

user5#xrdp-sesadmin -c=list   
Session ID: 39726
        Display: :14
        User: user5
        Session type: Xorg
        Screen size: 1024x768, color depth 24

........loop@@

✔️ Expected Behavior

1.xrdp-sesman multi-user normal

2.xrdp-sesadman multi-user normal

❌ Actual Behavior

No response

Anything else?

No response

matt335672 commented 10 months ago

Thanks for this @tsz8899

I've managed to reproduce this. You've nicely uncovered a bit of duff coding on my part, related to scanning the session list.

Can you try this patch?

--- a/sesman/session_list.c
+++ b/sesman/session_list.c
@@ -525,9 +525,9 @@ session_list_get_wait_objs(tbus robjs[], int *robjs_count)
 int
 session_list_check_wait_objs(void)
 {
-    int i;
+    int i = 0;

-    for (i = 0 ; i < g_session_list->count; ++i)
+    while (i < g_session_list->count)
     {
         struct session_item *si;
         si = (struct session_item *)list_get_item(g_session_list, i);
tsz8899 commented 10 months ago

Thanks !

debian 11 and ubuntu 22.04

xrdp-sesman multi-user normal !

xrdp-sesadman multi-user normal ! ^^