Galène videoconferencing server discussion list archives
 help / color / mirror / Atom feed
From: Z0T <zot@mochela.it>
To: galene@lists.galene.org
Subject: [Galene] forbid presenting probably bug
Date: Wed, 21 Oct 2026 12:07:00 +0000	[thread overview]
Message-ID: <00142e73-9c7f-4adf-9076-898cd43541e2@mochela.it> (raw)


Hi,

I think I found a bug in Galene 1.2.1 (also present on master as of 
d2c34df, 4 October 2026): removing a permission from one client 
(unpresent, unop, shutup) can also change the permissions of other 
clients, including clients that join later.

How to reproduce, with a group that has a wildcard user with permissions 
"present":

   1. An operator and a guest ("anna") join; the guest gets ["present", 
"message"].
   2. The operator does "Forbid presenting" (useraction "unpresent") on 
anna.
   3. Another guest ("bruno") joins with the same wildcard password.

bruno gets ["message", "message"] instead of ["present", "message"]: he 
cannot present, and every guest joining after him gets the same, until 
Galene is restarted.

The same happens with stateful tokens: after "unpresent" on one client 
that joined with a token, the other clients that joined with the same 
token lose "present" on the server side (without receiving a 
"joined"/"change" message), and so do new clients joining with that token.

Cause: remove() in rtpconn/webclient.go does append(l[:i], l[i+1:]...), 
which modifies the backing array in place. But c.permissions is not 
always a private slice: Permissions.Permissions() in 
group/description.go returns permissionsMap[p.name] directly (unless 
"record" or "token" is prepended), and for stateful tokens the slice 
comes from the token itself. So unpresent on one client rewrites 
permissionsMap["present"] (or the token's permissions) for everyone. 
addnew() can write into the same shared array afterwards, when its 
capacity allows.

The smallest fix I found is to copy the slice before changing it:

--- a/rtpconn/webclient.go
+++ b/rtpconn/webclient.go
@@ -1216,6 +1216,10 @@
              }
          }
      case changePermissionsAction:
+        // c.permissions may share its backing array with other clients
+        // (permissionsMap, stateful tokens): remove and addnew modify it
+        // in place, so make a private copy first.
+        c.permissions = slices.Clone(c.permissions)
          switch a.kind {
          case "op":
              c.permissions = addnew("op", c.permissions)

With this change, in the scenario above bruno gets ["present", 
"message"], and the clients sharing a token keep their permissions. We 
have been running it in production since today. Perhaps you would prefer 
to fix it at the source instead (Permissions() returning a copy, or 
remove() not working in place); either is fine with us.

Thanks for Galene,

Alberto Brusoni
mochela.it


                 reply	other threads:[~2026-10-21 12:07 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.galene.org/postorius/lists/galene.lists.galene.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=00142e73-9c7f-4adf-9076-898cd43541e2@mochela.it \
    --to=zot@mochela.it \
    --cc=galene@lists.galene.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox