mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-06 05:28:29 -04:00
core: fix security and concurrency issues found in a backend audit (#2805)
* core: fix security and concurrency issues found in backend audit Security: - privesc: pipe the sudo password via stdin (sudo -S) instead of embedding it in the command string, so it no longer appears in argv (readable by any local user via /proc/<pid>/cmdline or ps) - greeter: tokenize a session .desktop Exec= line into argv and execve directly instead of running it through /bin/sh -c, closing a command- injection path via user-writable ~/.local/share/wayland-sessions - plugins: reject path-separator/.. in plugin id/name before joining into a filesystem path, closing an arbitrary-directory-delete in the uninstall/update fallback - keybinds/hyprland: always quote unrecognized bind actions/keys when writing generated Lua; only re-emit genuine round-tripped custom Lua verbatim (tracked via an explicit flag), closing a Lua-injection path - desktop/mimeapps: reject newline/bracket in mime/desktop-id fields so they can't inject fake sections into the shared mimeapps.list Robustness / concurrency: - server: recover panics in the request-dispatch path so one bad handler can't crash the daemon and drop every client - go-wayland: recover panics in the shared dispatch choke point so a malformed compositor event can't crash CLI tools / the daemon - server: per-connection D-Bus client ID instead of a shared constant, fixing cross-client signal delivery and subscription teardown - network: guard the NetworkManager device maps with a mutex (a concurrent map read/write here is an unrecoverable fatal error) - cups: close the event channel on Stop() so Unsubscribe() of the last subscriber no longer deadlocks; allocate the fresh channel in Start() - freedesktop: reuse the shared session conn for the settings watcher and tear it down in Close(), fixing a per-Manager conn+goroutine leak - clipboard: mutex-guard lazy dbusConn creation - geolocation: use WithMatchMember for the GeoClue2 LocationUpdated signal (was WithMatchSender with an interface.member string, so the match never fired and live location updates never arrived) - screenshot: set failed=true on buffer/pool creation errors so the dispatch loop doesn't wait forever for a ready/failed that never comes * apply code review comments --------- Co-authored-by: bbedward <bbedward@gmail.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -41,7 +42,7 @@ import (
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap"
|
||||
)
|
||||
|
||||
const APIVersion = 27
|
||||
const APIVersion = 28
|
||||
|
||||
var CLIVersion = "dev"
|
||||
|
||||
@@ -398,6 +399,11 @@ func InitializeSysUpdateManager() error {
|
||||
|
||||
func handleConnection(conn net.Conn) {
|
||||
defer conn.Close()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Errorf("handleConnection panic recovered: panic=%v\n%s", r, debug.Stack())
|
||||
}
|
||||
}()
|
||||
|
||||
caps := getCapabilities()
|
||||
capsData, _ := json.Marshal(caps)
|
||||
@@ -415,10 +421,21 @@ func handleConnection(conn net.Conn) {
|
||||
continue
|
||||
}
|
||||
|
||||
go RouteRequest(conn, req)
|
||||
go routeRequestRecovered(conn, req)
|
||||
}
|
||||
}
|
||||
|
||||
// routeRequestRecovered keeps a panicking handler from taking down the whole daemon
|
||||
func routeRequestRecovered(conn net.Conn, req models.Request) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Errorf("RouteRequest panic recovered: method=%s panic=%v\n%s", req.Method, r, debug.Stack())
|
||||
models.RespondError(conn, req.ID, "internal server error")
|
||||
}
|
||||
}()
|
||||
RouteRequest(conn, req)
|
||||
}
|
||||
|
||||
func getCapabilities() Capabilities {
|
||||
caps := []string{"plugins"}
|
||||
|
||||
@@ -581,6 +598,11 @@ func notifyCapabilityChange() {
|
||||
func handleSubscribe(conn net.Conn, req models.Request) {
|
||||
clientID := fmt.Sprintf("meta-client-%p", conn)
|
||||
|
||||
dbusClient := dbusClientID
|
||||
if id, ok := models.Get[string](req, "clientId"); ok && id != "" {
|
||||
dbusClient = id
|
||||
}
|
||||
|
||||
var services []string
|
||||
if servicesParam, ok := models.Get[[]any](req, "services"); ok {
|
||||
for _, s := range servicesParam {
|
||||
@@ -1249,10 +1271,10 @@ func handleSubscribe(conn net.Conn, req models.Request) {
|
||||
|
||||
if shouldSubscribe("dbus") && dbusManager != nil {
|
||||
wg.Add(1)
|
||||
dbusChan := dbusManager.SubscribeSignals(dbusClientID)
|
||||
dbusChan := dbusManager.SubscribeSignals(dbusClient)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
defer dbusManager.UnsubscribeSignals(dbusClientID)
|
||||
defer dbusManager.UnsubscribeSignals(dbusClient)
|
||||
|
||||
for {
|
||||
select {
|
||||
|
||||
Reference in New Issue
Block a user