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