chore: Update upower again

This commit is contained in:
Kyle Gospodnetich 2024-09-17 11:16:18 -07:00
parent fb09f1f2a0
commit 89083ddf5c
7 changed files with 456 additions and 2 deletions

View File

@ -0,0 +1,24 @@
From b26c8c79c9ff7fd0ba63e893171c6d5b164fda82 Mon Sep 17 00:00:00 2001
From: Kate Hsuan <hpa@redhat.com>
Date: Wed, 28 Aug 2024 13:29:41 +0800
Subject: [PATCH 1/9] ci: Add polkit dependency
---
.gitlab-ci.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index fbdbd53..1476c85 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -25,6 +25,7 @@ variables:
libplist-devel
umockdev
dbus-x11
+ polkit-devel
python3-gobject
python3-dbusmock
python3-pip
--
2.46.0

View File

@ -0,0 +1,88 @@
From f55641cd4335997bffd2a662de84c69a45ce9394 Mon Sep 17 00:00:00 2001
From: Kate Hsuan <hpa@redhat.com>
Date: Thu, 22 Aug 2024 20:43:43 +0800
Subject: [PATCH 2/9] Revert "Remove polkit tests"
This reverts commit bddc559713ed3e8d790231139b21c8277931b5d0.
Changes:
- Removed Makefile
- Removed test for UpWakeups
---
README | 1 +
src/up-self-test.c | 26 ++++++++++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/README b/README
index dd2a18c..d7f325e 100644
--- a/README
+++ b/README
@@ -8,6 +8,7 @@ Requirements:
gio-2.0 >= 2.16.1
gudev-1.0 >= 235 (Linux)
libimobiledevice-1.0 >= 0.9.7 (optional)
+ polkit-gobject-1 >= 124
UPower is an abstraction for enumerating power devices,
listening to device events and querying history and statistics.
diff --git a/src/up-self-test.c b/src/up-self-test.c
index f60618f..a60f5f2 100644
--- a/src/up-self-test.c
+++ b/src/up-self-test.c
@@ -33,6 +33,7 @@
#include "up-device-list.h"
#include "up-history.h"
#include "up-native.h"
+#include "up-polkit.h"
gchar *history_dir = NULL;
@@ -64,6 +65,12 @@ up_test_daemon_func (void)
{
UpDaemon *daemon;
+ /* needs polkit, which only listens to the system bus */
+ if (!g_file_test (DBUS_SYSTEM_SOCKET, G_FILE_TEST_EXISTS)) {
+ puts("No system D-BUS running, skipping test");
+ return;
+ }
+
daemon = up_daemon_new ();
g_assert (daemon != NULL);
@@ -274,6 +281,24 @@ up_test_history_func (void)
rmdir (history_dir);
}
+static void
+up_test_polkit_func (void)
+{
+ UpPolkit *polkit;
+
+ /* polkit only listens to the system bus */
+ if (!g_file_test (DBUS_SYSTEM_SOCKET, G_FILE_TEST_EXISTS)) {
+ puts("No system D-BUS running, skipping test");
+ return;
+ }
+
+ polkit = up_polkit_new ();
+ g_assert (polkit != NULL);
+
+ /* unref */
+ g_object_unref (polkit);
+}
+
int
main (int argc, char **argv)
{
@@ -290,6 +315,7 @@ main (int argc, char **argv)
g_test_add_func ("/power/device_list", up_test_device_list_func);
g_test_add_func ("/power/history", up_test_history_func);
g_test_add_func ("/power/native", up_test_native_func);
+ g_test_add_func ("/power/polkit", up_test_polkit_func);
g_test_add_func ("/power/daemon", up_test_daemon_func);
return g_test_run ();
--
2.46.0

View File

@ -0,0 +1,229 @@
From b71996a526a73a18ae5e66ad6ce52c297a458df9 Mon Sep 17 00:00:00 2001
From: Kate Hsuan <hpa@redhat.com>
Date: Wed, 28 Aug 2024 12:57:40 +0800
Subject: [PATCH 3/9] linux: integration-test: Add polkit test
Test action is allowed and not allowed when calling EnableChargeThreshold
dbus API.
---
src/linux/integration-test.py | 162 +++++++++++++++++++++++++++++++++-
1 file changed, 159 insertions(+), 3 deletions(-)
diff --git a/src/linux/integration-test.py b/src/linux/integration-test.py
index 61dfa56..df754c7 100755
--- a/src/linux/integration-test.py
+++ b/src/linux/integration-test.py
@@ -157,6 +157,7 @@ class Tests(dbusmock.DBusTestCase):
self.daemon = None
self.bluez = None
self.start_logind({'CanHybridSleep' : 'yes'})
+ self.start_polkitd({})
@classmethod
def stop_process(cls, proc, timeout=1):
@@ -324,6 +325,11 @@ class Tests(dbusmock.DBusTestCase):
parameters or {})
self.addCleanup(self.stop_process, self.bluez)
+ def start_polkitd(self, parameters=None):
+ self.polkit, self.polkit_obj = self.spawn_server_template('polkitd',
+ parameters or {})
+ self.addCleanup(self.stop_process, self.polkit)
+
def assertEventually(self, condition, message=None, timeout=50, value=True):
'''Assert that condition function eventually returns True.
@@ -1014,6 +1020,10 @@ class Tests(dbusmock.DBusTestCase):
def test_battery_charge_limit_multiple_batteries(self):
'''Battery with charge limits with multiple batteries'''
+ if not self.polkit:
+ self.start_polkitd({})
+ self.polkit_obj.SetAllowed(['org.freedesktop.UPower.enable-charging-limit'])
+
self.testbed.add_device('power_supply', 'BAT0', None,
['type', 'Battery',
'present', '1',
@@ -1062,9 +1072,75 @@ class Tests(dbusmock.DBusTestCase):
with open(f'/sys/class/power_supply/{battery_name}/charge_control_end_threshold') as fp:
self.assertEqual(fp.read(), '80')
+ def test_battery_charge_limit_multiple_batteries_polkit_not_allowed(self):
+ '''Battery with charge limits with multiple batteries, but polkit isn't allowed'''
+
+ if not self.polkit:
+ self.start_polkitd({})
+
+ self.testbed.add_device('power_supply', 'BAT0', None,
+ ['type', 'Battery',
+ 'present', '1',
+ 'status', 'unknown',
+ 'energy_full', '60000000',
+ 'energy_full_design', '80000000',
+ 'energy_now', '48000000',
+ 'voltage_now', '12000000',
+ 'charge_control_start_threshold', '0',
+ 'charge_control_end_threshold', '100',
+ ], [])
+ self.testbed.set_property("/sys/class/power_supply/BAT0", 'CHARGE_LIMIT', '70,80')
+
+ self.testbed.add_device('power_supply', 'BAT1', None,
+ ['type', 'Battery',
+ 'present', '1',
+ 'status', 'unknown',
+ 'energy_full', '60000000',
+ 'energy_full_design', '80000000',
+ 'energy_now', '48000000',
+ 'voltage_now', '12000000',
+ 'charge_control_start_threshold', '0',
+ 'charge_control_end_threshold', '100',
+ ], [])
+ self.testbed.set_property("/sys/class/power_supply/BAT1", 'CHARGE_LIMIT', '70,80')
+
+ self.start_daemon()
+ devs = self.proxy.EnumerateDevices()
+ self.assertEqual(len(devs), 2)
+ bat0_up = devs[0]
+ bat1_up = devs[0]
+
+ for bat in [bat0_up, bat1_up]:
+ self.assertEqual(self.get_dbus_dev_property(bat, 'ChargeThresholdSupported'), True)
+ self.assertEqual(self.get_dbus_dev_property(bat, 'ChargeThresholdEnabled'), False)
+ self.assertEqual(self.get_dbus_dev_property(bat, 'ChargeStartThreshold'), 70)
+ self.assertEqual(self.get_dbus_dev_property(bat, 'ChargeEndThreshold'), 80)
+
+ with self.assertRaises(Exception) as cm:
+ self.enable_charge_limits(bat0_up, True)
+ ex = cm.exception
+ self.assertIn("Operation is not allowed", str(ex))
+
+ with self.assertRaises(Exception) as cm:
+ self.enable_charge_limits(bat1_up, True)
+ ex = cm.exception
+ self.assertIn("Operation is not allowed", str(ex))
+
+ for bat in [bat0_up, bat1_up]:
+ self.assertEqual(self.get_dbus_dev_property(bat, 'ChargeThresholdEnabled'), False)
+ battery_name = bat.split('_')[-1]
+ with open(f'/sys/class/power_supply/{battery_name}/charge_control_start_threshold') as fp:
+ self.assertEqual(fp.read(), '0')
+ with open(f'/sys/class/power_supply/{battery_name}/charge_control_end_threshold') as fp:
+ self.assertEqual(fp.read(), '100')
+
def test_battery_charge_limit_supported(self):
'''Battery with charge_control_start/end_threshold supported'''
+ if not self.polkit:
+ self.start_polkitd({})
+ self.polkit_obj.SetAllowed(['org.freedesktop.UPower.enable-charging-limit'])
+
self.testbed.add_device('power_supply', 'BAT0', None,
['type', 'Battery',
'present', '1',
@@ -1135,9 +1211,89 @@ class Tests(dbusmock.DBusTestCase):
with open('/sys/class/power_supply/BAT0/charge_control_end_threshold') as fp:
self.assertEqual(fp.read(), '100')
+ def test_battery_charge_limit_supported_polkit_not_allowed(self):
+ '''Battery with charge_control_start/end_threshold supported'''
+
+ if not self.polkit:
+ self.start_polkitd({})
+
+ self.testbed.add_device('power_supply', 'BAT0', None,
+ ['type', 'Battery',
+ 'present', '1',
+ 'model_name', 'test',
+ 'serial_number', '12',
+ 'status', 'unknown',
+ 'energy_full', '60000000',
+ 'energy_full_design', '80000000',
+ 'energy_now', '48000000',
+ 'voltage_now', '12000000',
+ 'charge_control_start_threshold', '0',
+ 'charge_control_end_threshold', '100',
+ ], [])
+ self.testbed.set_property("/sys/class/power_supply/BAT0", 'CHARGE_LIMIT', '70,80')
+
+ def start_daemon(charge_threshold_value=None):
+ upower_history_dir_override = tempfile.mkdtemp(prefix='upower-history-')
+ if charge_threshold_value is not None:
+ with open(os.path.join(upower_history_dir_override, f"charging-threshold-status") , 'w') as fp:
+ fp.write(charge_threshold_value)
+
+ self.start_daemon(history_dir_override=upower_history_dir_override)
+ devs = self.proxy.EnumerateDevices()
+ self.assertEqual(len(devs), 1)
+ return devs[0]
+
+ bat0_up = start_daemon()
+ self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeThresholdSupported'), True)
+ self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeThresholdEnabled'), False)
+ self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeStartThreshold'), 70)
+ self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeEndThreshold'), 80)
+
+ with self.assertRaises(Exception) as cm:
+ self.enable_charge_limits(bat0_up, True)
+ ex = cm.exception
+ self.assertIn("Operation is not allowed", str(ex))
+
+ self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeThresholdEnabled'), False)
+ # charge limits enabled?
+ with open('/sys/class/power_supply/BAT0/charge_control_start_threshold') as fp:
+ self.assertEqual(fp.read(), '0')
+ with open('/sys/class/power_supply/BAT0/charge_control_end_threshold') as fp:
+ self.assertEqual(fp.read(), '100')
+
+ with self.assertRaises(Exception) as cm:
+ self.enable_charge_limits(bat0_up, False)
+ ex = cm.exception
+ self.assertIn("Operation is not allowed", str(ex))
+
+ self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeThresholdEnabled'), False)
+ with open('/sys/class/power_supply/BAT0/charge_control_start_threshold') as fp:
+ self.assertEqual(fp.read(), '0')
+ with open('/sys/class/power_supply/BAT0/charge_control_end_threshold') as fp:
+ self.assertEqual(fp.read(), '100')
+
+ self.stop_daemon()
+
+ # On startup with threshold set
+ self.testbed.set_property("/sys/class/power_supply/BAT0", 'CHARGE_LIMIT', '90,100')
+ bat0_up = start_daemon(charge_threshold_value='1')
+ self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeThresholdSupported'), True)
+ self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeThresholdEnabled'), True)
+ self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeStartThreshold'), 90)
+ self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeEndThreshold'), 100)
+
+ with open('/sys/class/power_supply/BAT0/charge_control_start_threshold') as fp:
+ self.assertEqual(fp.read(), '90')
+ with open('/sys/class/power_supply/BAT0/charge_control_end_threshold') as fp:
+ self.assertEqual(fp.read(), '100')
+
def test_battery_charge_threshold_unsupported(self):
'''Battery with only end_threshold supported'''
+ if not self.polkit:
+ self.start_polkitd({})
+ self.polkit_obj.SetAllowed(['org.freedesktop.UPower.enable-charging-limit'])
+
self.testbed.add_device('power_supply', 'BAT0', None,
['type', 'Battery',
'present', '1',
@@ -1159,10 +1315,10 @@ class Tests(dbusmock.DBusTestCase):
self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeThresholdSupported'), False)
self.assertEqual(self.get_dbus_dev_property(bat0_up, 'ChargeThresholdEnabled'), False)
- try:
+ with self.assertRaises(Exception) as cm:
self.enable_charge_limits(bat0_up, True)
- except Exception as err:
- self.assertIn("setting battery charge thresholds", str(err))
+ ex = cm.exception
+ self.assertIn("setting battery charge thresholds", str(ex))
self.stop_daemon()
--
2.46.0

View File

@ -0,0 +1,30 @@
From b4697dbc626ced1a456bcb4aba8dca2fe1efa901 Mon Sep 17 00:00:00 2001
From: "Jan Alexander Steffens (heftig)" <heftig@archlinux.org>
Date: Sat, 31 Aug 2024 11:05:54 +0200
Subject: [PATCH 4/9] up-polkit: Add `G_ADD_PRIVATE (UpPolkit)`
Without this, accesses to `UpPolkitPrivate` are actually out of bounds
and writing to it will cause heap corruption.
Fixes: https://gitlab.freedesktop.org/upower/upower/-/issues/281
---
src/up-polkit.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/up-polkit.c b/src/up-polkit.c
index 0ede5a7..e0ba246 100644
--- a/src/up-polkit.c
+++ b/src/up-polkit.c
@@ -43,7 +43,8 @@ struct UpPolkitPrivate
#endif
};
-G_DEFINE_TYPE (UpPolkit, up_polkit, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_CODE (UpPolkit, up_polkit, G_TYPE_OBJECT,
+ G_ADD_PRIVATE (UpPolkit))
static gpointer up_polkit_object = NULL;
#ifdef HAVE_POLKIT
--
2.46.0

View File

@ -0,0 +1,41 @@
From 7db90b28d842744f135114b3e90e6bded4ac6fbb Mon Sep 17 00:00:00 2001
From: Kate Hsuan <hpa@redhat.com>
Date: Mon, 2 Sep 2024 14:03:56 +0800
Subject: [PATCH 8/9] up-polkit: remove global variable and remove
g_object_add_weak_pointer()
Since UpPolkit is only created in the daemon, so the global variable and
g_object_add_weak_pointer() can be removed.
---
src/up-polkit.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/up-polkit.c b/src/up-polkit.c
index e0ba246..fadfc30 100644
--- a/src/up-polkit.c
+++ b/src/up-polkit.c
@@ -45,7 +45,6 @@ struct UpPolkitPrivate
G_DEFINE_TYPE_WITH_CODE (UpPolkit, up_polkit, G_TYPE_OBJECT,
G_ADD_PRIVATE (UpPolkit))
-static gpointer up_polkit_object = NULL;
#ifdef HAVE_POLKIT
/**
@@ -190,12 +189,6 @@ up_polkit_init (UpPolkit *polkit)
UpPolkit *
up_polkit_new (void)
{
- if (up_polkit_object != NULL) {
- g_object_ref (up_polkit_object);
- } else {
- up_polkit_object = g_object_new (UP_TYPE_POLKIT, NULL);
- g_object_add_weak_pointer (up_polkit_object, &up_polkit_object);
- }
- return UP_POLKIT (up_polkit_object);
+ return UP_POLKIT (g_object_new (UP_TYPE_POLKIT, NULL));
}
--
2.46.0

View File

@ -0,0 +1,28 @@
From 131ab3a9d51ca14914a693e18f7f2961efba911e Mon Sep 17 00:00:00 2001
From: Kate Hsuan <hpa@redhat.com>
Date: Mon, 9 Sep 2024 14:03:57 +0800
Subject: [PATCH 9/9] up-polkit: Replace with G_DEFINE_TYPE_WITH_PRIVATE
Since no interface was inplemented in UpPolkit class so G_DEFINE_TYPE_WITH_PRIVATE
macro is batter.
---
src/up-polkit.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/up-polkit.c b/src/up-polkit.c
index fadfc30..1ead7e7 100644
--- a/src/up-polkit.c
+++ b/src/up-polkit.c
@@ -43,8 +43,7 @@ struct UpPolkitPrivate
#endif
};
-G_DEFINE_TYPE_WITH_CODE (UpPolkit, up_polkit, G_TYPE_OBJECT,
- G_ADD_PRIVATE (UpPolkit))
+G_DEFINE_TYPE_WITH_PRIVATE (UpPolkit, up_polkit, G_TYPE_OBJECT)
#ifdef HAVE_POLKIT
/**
--
2.46.0

View File

@ -6,8 +6,6 @@ License: GPL-2.0-or-later
URL: http://upower.freedesktop.org/
Source0: https://gitlab.freedesktop.org/upower/%{name}/-/archive/v%{version}/%{name}-v%{version}.tar.bz2
Patch0: valve.patch
BuildRequires: meson
BuildRequires: git
BuildRequires: gettext
@ -22,11 +20,26 @@ BuildRequires: libimobiledevice-devel
BuildRequires: glib2-devel >= 2.6.0
BuildRequires: gobject-introspection-devel
BuildRequires: gtk-doc
BuildRequires: polkit-devel
BuildRequires: systemd
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Requires: udev
Patch0: valve.patch
# https://gitlab.freedesktop.org/upower/upower/-/commit/b26c8c79c9ff7fd0ba63e893171c6d5b164fda82.patch
Patch1001: 0001-ci-Add-polkit-dependency.patch
# https://gitlab.freedesktop.org/upower/upower/-/commit/f55641cd4335997bffd2a662de84c69a45ce9394.patch
Patch1002: 0002-Revert-Remove-polkit-tests.patch
# https://gitlab.freedesktop.org/upower/upower/-/commit/b71996a526a73a18ae5e66ad6ce52c297a458df9.patch
Patch1003: 0003-linux-integration-test-Add-polkit-test.patch
# https://gitlab.freedesktop.org/upower/upower/-/commit/b4697dbc626ced1a456bcb4aba8dca2fe1efa901.patch
Patch10004: 0004-up-polkit-Add-G_ADD_PRIVATE-UpPolkit.patch
# https://gitlab.freedesktop.org/upower/upower/-/commit/7db90b28d842744f135114b3e90e6bded4ac6fbb.patch
Patch10005: 0008-up-polkit-remove-global-variable-and-remove-g_object.patch
# https://gitlab.freedesktop.org/upower/upower/-/commit/131ab3a9d51ca14914a693e18f7f2961efba911e.patch
Patch10006: 0009-up-polkit-Replace-with-G_DEFINE_TYPE_WITH_PRIVATE.patch
%description
UPower (formerly DeviceKit-power) provides a daemon, API and command
@ -102,6 +115,7 @@ Developer documentation for for libupower-glib.
%{_datadir}/dbus-1/system-services/*.service
%{_unitdir}/*.service
%{_datadir}/installed-tests/upower/upower-integration.test
%{_datadir}/polkit-1/actions/org.freedesktop.upower.policy
%files libs
%license COPYING