From 51106bdfc04779ff01a05d2bbf33656176fb8f61 Mon Sep 17 00:00:00 2001 From: lbellows <19894143+lbellows@users.noreply.github.com> Date: Tue, 22 Sep 2026 22:27:47 -0400 Subject: [PATCH] Pass the exported blacklist to mintupdate-automation on stdin Exporting the blacklist wrote it to /tmp/mintUpdate/blacklist, then mintupdate-automation read that path as root after pkexec authentication. Another local user can replace the file (or plant a symlink) while the authentication dialog is open, so root appended arbitrary lines or the contents of any file, e.g. /etc/shadow, to world-readable /etc/mintupdate.blacklist. Pipe the blacklist to the helper on stdin instead. --- usr/bin/mintupdate-automation | 15 ++++++++------- .../__pycache__/preferences.cpython-314.pyc | Bin 0 -> 21021 bytes usr/lib/linuxmint/mintUpdate/preferences.py | 7 ++----- 3 files changed, 10 insertions(+), 12 deletions(-) create mode 100644 usr/lib/linuxmint/mintUpdate/__pycache__/preferences.cpython-314.pyc diff --git a/usr/bin/mintupdate-automation b/usr/bin/mintupdate-automation index d9a7cb31..75809885 100755 --- a/usr/bin/mintupdate-automation +++ b/usr/bin/mintupdate-automation @@ -55,14 +55,15 @@ def do_disable(_automation_id): print("%s %s removed." % (name, filename)) def add_user_blacklist(outfile): - import tempfile + # The user's blacklist arrives on stdin. Never read it from a shared + # location such as /tmp: another user could swap the file for a symlink + # while the authentication dialog is open. + if sys.stdin is None or sys.stdin.isatty(): + return try: - infile = os.path.join(tempfile.gettempdir(), "mintUpdate/blacklist") - with open(infile, "r") as export: - with open(outfile, "a") as f: - for line in export: - f.write(line) - os.remove(infile) + with open(outfile, "a") as f: + for line in sys.stdin: + f.write(line) print("User blacklist exported.") except: pass diff --git a/usr/lib/linuxmint/mintUpdate/__pycache__/preferences.cpython-314.pyc b/usr/lib/linuxmint/mintUpdate/__pycache__/preferences.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..59697732c5512503a85a162f2ccd6a3bf4ae2b12 GIT binary patch literal 21021 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

Zra#a&FFK$P6}^hKjf4g| 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 BiWvX^ literal 0 HcmV?d00001 diff --git a/usr/lib/linuxmint/mintUpdate/preferences.py b/usr/lib/linuxmint/mintUpdate/preferences.py index 9f96a550..4c64da5d 100644 --- a/usr/lib/linuxmint/mintUpdate/preferences.py +++ b/usr/lib/linuxmint/mintUpdate/preferences.py @@ -5,7 +5,6 @@ import json import os import subprocess -import tempfile import gi gi.require_version('Gtk', '3.0') @@ -215,11 +214,9 @@ def _build_automation(self, builder): section.add_row(switch) def _export_blacklist(self, widget): - filename = os.path.join(tempfile.gettempdir(), "mintUpdate/blacklist") blacklist = self.settings.get_strv("blacklisted-packages") - with open(filename, "w") as f: - f.write("\n".join(blacklist) + "\n") - subprocess.run(["pkexec", "/usr/bin/mintupdate-automation", "blacklist", "enable"]) + subprocess.run(["pkexec", "/usr/bin/mintupdate-automation", "blacklist", "enable"], + input="\n".join(blacklist) + "\n", text=True) def _set_auto_upgrade(self, widget, param): self._toggle_automation(widget, "upgrade")