mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-17 22:03:45 +00:00
trivial: Fix several potential leaks when parsing remotes
This fixes several issues when calling fwupd_remote_load_from_filename() multiple times on the same FwupdRemote.
This commit is contained in:
parent
6c706c74d6
commit
2e6fee186e
@ -5,8 +5,8 @@ Enabled=false
|
||||
Title=Linux Vendor Firmware Service (testing)
|
||||
MetadataURI=https://cdn.fwupd.org/downloads/firmware-testing.xml.gz
|
||||
ReportURI=https://fwupd.org/lvfs/firmware/report
|
||||
Username=
|
||||
Password=
|
||||
#Username=
|
||||
#Password=
|
||||
OrderBefore=lvfs,fwupd
|
||||
AutomaticReports=false
|
||||
ApprovalRequired=false
|
||||
|
4
data/tests/disabled.conf
Normal file
4
data/tests/disabled.conf
Normal file
@ -0,0 +1,4 @@
|
||||
[fwupd Remote]
|
||||
Enabled=false
|
||||
Keyring=none
|
||||
Password=
|
@ -79,8 +79,12 @@ static void
|
||||
fwupd_remote_set_username (FwupdRemote *self, const gchar *username)
|
||||
{
|
||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
||||
if (username != NULL && username[0] == '\0')
|
||||
username = NULL;
|
||||
|
||||
/* not changed */
|
||||
if (g_strcmp0 (priv->username, username) == 0)
|
||||
return;
|
||||
|
||||
g_free (priv->username);
|
||||
priv->username = g_strdup (username);
|
||||
}
|
||||
|
||||
@ -141,8 +145,6 @@ fwupd_remote_set_password (FwupdRemote *self, const gchar *password)
|
||||
if (g_strcmp0 (priv->password, password) == 0)
|
||||
return;
|
||||
|
||||
if (password != NULL && password[0] == '\0')
|
||||
password = NULL;
|
||||
g_free (priv->password);
|
||||
priv->password = g_strdup (password);
|
||||
}
|
||||
@ -312,6 +314,12 @@ static void
|
||||
fwupd_remote_set_firmware_base_uri (FwupdRemote *self, const gchar *firmware_base_uri)
|
||||
{
|
||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
/* not changed */
|
||||
if (g_strcmp0 (priv->firmware_base_uri, firmware_base_uri) == 0)
|
||||
return;
|
||||
|
||||
g_free (priv->firmware_base_uri);
|
||||
priv->firmware_base_uri = g_strdup (firmware_base_uri);
|
||||
}
|
||||
|
||||
@ -319,6 +327,12 @@ static void
|
||||
fwupd_remote_set_report_uri (FwupdRemote *self, const gchar *report_uri)
|
||||
{
|
||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
/* not changed */
|
||||
if (g_strcmp0 (priv->report_uri, report_uri) == 0)
|
||||
return;
|
||||
|
||||
g_free (priv->report_uri);
|
||||
priv->report_uri = g_strdup (report_uri);
|
||||
}
|
||||
|
||||
@ -326,6 +340,12 @@ static void
|
||||
fwupd_remote_set_security_report_uri (FwupdRemote *self, const gchar *security_report_uri)
|
||||
{
|
||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
/* not changed */
|
||||
if (g_strcmp0 (priv->security_report_uri, security_report_uri) == 0)
|
||||
return;
|
||||
|
||||
g_free (priv->security_report_uri);
|
||||
priv->security_report_uri = g_strdup (security_report_uri);
|
||||
}
|
||||
|
||||
@ -396,6 +416,24 @@ fwupd_remote_set_filename_cache (FwupdRemote *self, const gchar *filename)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_remote_set_order_before (FwupdRemote *self, const gchar *order_before)
|
||||
{
|
||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
||||
g_clear_pointer (&priv->order_before, g_strfreev);
|
||||
if (order_before != NULL)
|
||||
priv->order_before = g_strsplit_set (order_before, ",:;", -1);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_remote_set_order_after (FwupdRemote *self, const gchar *order_after)
|
||||
{
|
||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
||||
g_clear_pointer (&priv->order_after, g_strfreev);
|
||||
if (order_after != NULL)
|
||||
priv->order_after = g_strsplit_set (order_after, ",:;", -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_remote_load_from_filename:
|
||||
* @self: a #FwupdRemote
|
||||
@ -419,14 +457,7 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
|
||||
{
|
||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
||||
const gchar *group = "fwupd Remote";
|
||||
g_autofree gchar *firmware_base_uri = NULL;
|
||||
g_autofree gchar *id = NULL;
|
||||
g_autofree gchar *keyring_kind = NULL;
|
||||
g_autofree gchar *metadata_uri = NULL;
|
||||
g_autofree gchar *order_after = NULL;
|
||||
g_autofree gchar *order_before = NULL;
|
||||
g_autofree gchar *report_uri = NULL;
|
||||
g_autofree gchar *security_report_uri = NULL;
|
||||
g_autoptr(GKeyFile) kf = NULL;
|
||||
|
||||
g_return_val_if_fail (FWUPD_IS_REMOTE (self), FALSE);
|
||||
@ -443,28 +474,25 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
|
||||
if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_NONE, error))
|
||||
return FALSE;
|
||||
|
||||
/* get verification type, falling back to GPG */
|
||||
keyring_kind = g_key_file_get_string (kf, group, "Keyring", NULL);
|
||||
if (keyring_kind == NULL) {
|
||||
priv->keyring_kind = FWUPD_KEYRING_KIND_JCAT;
|
||||
} else {
|
||||
priv->keyring_kind = fwupd_keyring_kind_from_string (keyring_kind);
|
||||
/* optional verification type */
|
||||
if (g_key_file_has_key (kf, group, "Keyring", NULL)) {
|
||||
g_autofree gchar *tmp = g_key_file_get_string (kf, group, "Keyring", NULL);
|
||||
priv->keyring_kind = fwupd_keyring_kind_from_string (tmp);
|
||||
if (priv->keyring_kind == FWUPD_KEYRING_KIND_UNKNOWN) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"Failed to parse type '%s'",
|
||||
keyring_kind);
|
||||
"keyring kind '%s' unknown",
|
||||
tmp);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* all remotes need a URI, even if it's file:// to the cache */
|
||||
metadata_uri = g_key_file_get_string (kf, group, "MetadataURI", error);
|
||||
if (metadata_uri == NULL)
|
||||
return FALSE;
|
||||
if (g_str_has_prefix (metadata_uri, "file://")) {
|
||||
const gchar *filename_cache = metadata_uri;
|
||||
/* the first remote sets the URI, even if it's file:// to the cache */
|
||||
if (g_key_file_has_key (kf, group, "MetadataURI", NULL)) {
|
||||
g_autofree gchar *tmp = g_key_file_get_string (kf, group, "MetadataURI", NULL);
|
||||
if (g_str_has_prefix (tmp, "file://")) {
|
||||
const gchar *filename_cache = tmp;
|
||||
if (g_str_has_prefix (filename_cache, "file://"))
|
||||
filename_cache += 7;
|
||||
fwupd_remote_set_filename_cache (self, filename_cache);
|
||||
@ -472,71 +500,75 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
|
||||
priv->kind = FWUPD_REMOTE_KIND_DIRECTORY;
|
||||
else
|
||||
priv->kind = FWUPD_REMOTE_KIND_LOCAL;
|
||||
} else if (g_str_has_prefix (metadata_uri, "http://") ||
|
||||
g_str_has_prefix (metadata_uri, "https://") ||
|
||||
g_str_has_prefix (metadata_uri, "ipfs://") ||
|
||||
g_str_has_prefix (metadata_uri, "ipns://")) {
|
||||
} else if (g_str_has_prefix (tmp, "http://") ||
|
||||
g_str_has_prefix (tmp, "https://") ||
|
||||
g_str_has_prefix (tmp, "ipfs://") ||
|
||||
g_str_has_prefix (tmp, "ipns://")) {
|
||||
priv->kind = FWUPD_REMOTE_KIND_DOWNLOAD;
|
||||
} else {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"Failed to parse MetadataURI type '%s'",
|
||||
metadata_uri);
|
||||
return FALSE;
|
||||
fwupd_remote_set_metadata_uri (self, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* extract data */
|
||||
/* all keys are optional */
|
||||
if (g_key_file_has_key (kf, group, "Enabled", NULL))
|
||||
priv->enabled = g_key_file_get_boolean (kf, group, "Enabled", NULL);
|
||||
if (g_key_file_has_key (kf, group, "ApprovalRequired", NULL))
|
||||
priv->approval_required = g_key_file_get_boolean (kf, group, "ApprovalRequired", NULL);
|
||||
priv->title = g_key_file_get_string (kf, group, "Title", NULL);
|
||||
|
||||
/* reporting is optional */
|
||||
report_uri = g_key_file_get_string (kf, group, "ReportURI", NULL);
|
||||
if (report_uri != NULL && report_uri[0] != '\0')
|
||||
fwupd_remote_set_report_uri (self, report_uri);
|
||||
|
||||
/* security reporting is optional */
|
||||
security_report_uri = g_key_file_get_string (kf, group, "SecurityReportURI", NULL);
|
||||
if (security_report_uri != NULL && security_report_uri[0] != '\0')
|
||||
fwupd_remote_set_security_report_uri (self, security_report_uri);
|
||||
|
||||
/* automatic report uploading */
|
||||
if (g_key_file_has_key (kf, group, "Title", NULL)) {
|
||||
g_autofree gchar *tmp = g_key_file_get_string (kf, group, "Title", NULL);
|
||||
fwupd_remote_set_title (self, tmp);
|
||||
}
|
||||
if (g_key_file_has_key (kf, group, "ReportURI", NULL)) {
|
||||
g_autofree gchar *tmp = g_key_file_get_string (kf, group, "ReportURI", NULL);
|
||||
fwupd_remote_set_report_uri (self, tmp);
|
||||
}
|
||||
if (g_key_file_has_key (kf, group, "SecurityReportURI", NULL)) {
|
||||
g_autofree gchar *tmp = g_key_file_get_string (kf, group, "SecurityReportURI", NULL);
|
||||
fwupd_remote_set_security_report_uri (self, tmp);
|
||||
}
|
||||
if (g_key_file_has_key (kf, group, "Username", NULL)) {
|
||||
g_autofree gchar *tmp = g_key_file_get_string (kf, group, "Username", NULL);
|
||||
fwupd_remote_set_username (self, tmp);
|
||||
}
|
||||
if (g_key_file_has_key (kf, group, "Password", NULL)) {
|
||||
g_autofree gchar *tmp = g_key_file_get_string (kf, group, "Password", NULL);
|
||||
fwupd_remote_set_password (self, tmp);
|
||||
}
|
||||
if (g_key_file_has_key (kf, group, "FirmwareBaseURI", NULL)) {
|
||||
g_autofree gchar *tmp = g_key_file_get_string (kf, group, "FirmwareBaseURI", NULL);
|
||||
fwupd_remote_set_firmware_base_uri (self, tmp);
|
||||
}
|
||||
if (g_key_file_has_key (kf, group, "OrderBefore", NULL)) {
|
||||
g_autofree gchar *tmp = g_key_file_get_string (kf, group, "OrderBefore", NULL);
|
||||
fwupd_remote_set_order_before (self, tmp);
|
||||
}
|
||||
if (g_key_file_has_key (kf, group, "OrderAfter", NULL)) {
|
||||
g_autofree gchar *tmp = g_key_file_get_string (kf, group, "OrderAfter", NULL);
|
||||
fwupd_remote_set_order_after (self, tmp);
|
||||
}
|
||||
if (g_key_file_has_key (kf, group, "AutomaticReports", NULL))
|
||||
priv->automatic_reports = g_key_file_get_boolean (kf, group, "AutomaticReports", NULL);
|
||||
if (g_key_file_has_key (kf, group, "AutomaticSecurityReports", NULL))
|
||||
priv->automatic_security_reports = g_key_file_get_boolean (kf, group, "AutomaticSecurityReports", NULL);
|
||||
|
||||
/* DOWNLOAD-type remotes */
|
||||
if (priv->kind == FWUPD_REMOTE_KIND_DOWNLOAD) {
|
||||
g_autofree gchar *filename_cache = NULL;
|
||||
g_autofree gchar *username = NULL;
|
||||
g_autofree gchar *password = NULL;
|
||||
|
||||
/* the client has to download this and the signature */
|
||||
fwupd_remote_set_metadata_uri (self, metadata_uri);
|
||||
|
||||
/* check the URI was valid */
|
||||
if (priv->metadata_uri == NULL) {
|
||||
g_set_error (error,
|
||||
/* we can override, hence the extra section */
|
||||
if (priv->kind == FWUPD_REMOTE_KIND_UNKNOWN) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"Failed to parse URI '%s' in %s",
|
||||
metadata_uri, filename);
|
||||
"metadata kind invalid");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* username and password are optional */
|
||||
username = g_key_file_get_string (kf, group, "Username", NULL);
|
||||
if (username != NULL)
|
||||
fwupd_remote_set_username (self, username);
|
||||
password = g_key_file_get_string (kf, group, "Password", NULL);
|
||||
if (password != NULL)
|
||||
fwupd_remote_set_password (self, password);
|
||||
/* some validation for DOWNLOAD types */
|
||||
if (priv->kind == FWUPD_REMOTE_KIND_DOWNLOAD) {
|
||||
g_autofree gchar *filename_cache = NULL;
|
||||
|
||||
if (priv->remotes_dir == NULL) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"Remotes directory not set");
|
||||
"remotes directory not set");
|
||||
return FALSE;
|
||||
}
|
||||
/* set cache to /var/lib... */
|
||||
@ -547,6 +579,25 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
|
||||
fwupd_remote_set_filename_cache (self, filename_cache);
|
||||
}
|
||||
|
||||
/* some validation for DIRECTORY types */
|
||||
if (priv->kind == FWUPD_REMOTE_KIND_DIRECTORY) {
|
||||
if (priv->keyring_kind != FWUPD_KEYRING_KIND_NONE) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"keyring kind %s is not supported with directory remote",
|
||||
fwupd_keyring_kind_to_string (priv->keyring_kind));
|
||||
return FALSE;
|
||||
}
|
||||
if (priv->firmware_base_uri != NULL) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"Directory remotes don't support firmware base URI");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* load the checksum */
|
||||
if (priv->filename_cache_sig != NULL &&
|
||||
g_file_test (priv->filename_cache_sig, G_FILE_TEST_EXISTS)) {
|
||||
@ -563,38 +614,6 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
|
||||
fwupd_remote_set_checksum (self, NULL);
|
||||
}
|
||||
|
||||
/* the base URI is optional */
|
||||
firmware_base_uri = g_key_file_get_string (kf, group, "FirmwareBaseURI", NULL);
|
||||
if (firmware_base_uri != NULL)
|
||||
fwupd_remote_set_firmware_base_uri (self, firmware_base_uri);
|
||||
|
||||
/* some validation around DIRECTORY types */
|
||||
if (priv->kind == FWUPD_REMOTE_KIND_DIRECTORY) {
|
||||
if (priv->keyring_kind != FWUPD_KEYRING_KIND_NONE) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"Keyring kind %s is not supported with directory remote",
|
||||
fwupd_keyring_kind_to_string (priv->keyring_kind));
|
||||
return FALSE;
|
||||
}
|
||||
if (firmware_base_uri != NULL) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"Directory remotes don't support firmware base URI");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* dep logic */
|
||||
order_before = g_key_file_get_string (kf, group, "OrderBefore", NULL);
|
||||
if (order_before != NULL)
|
||||
priv->order_before = g_strsplit_set (order_before, ",:;", -1);
|
||||
order_after = g_key_file_get_string (kf, group, "OrderAfter", NULL);
|
||||
if (order_after != NULL)
|
||||
priv->order_after = g_strsplit_set (order_after, ",:;", -1);
|
||||
|
||||
/* success */
|
||||
fwupd_remote_set_filename_source (self, filename);
|
||||
return TRUE;
|
||||
@ -1533,6 +1552,8 @@ fwupd_remote_class_init (FwupdRemoteClass *klass)
|
||||
static void
|
||||
fwupd_remote_init (FwupdRemote *self)
|
||||
{
|
||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
||||
priv->keyring_kind = FWUPD_KEYRING_KIND_JCAT;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -235,6 +235,30 @@ fwupd_remote_baseuri_func (void)
|
||||
g_assert_cmpstr (firmware_uri, ==, "https://my.fancy.cdn/firmware.cab");
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_remote_duplicate_func (void)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autofree gchar *fn2 = NULL;
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autoptr(FwupdRemote) remote = fwupd_remote_new ();
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
fn = g_build_filename (TESTDATADIR, "tests", "remotes.d", "stable.conf", NULL);
|
||||
ret = fwupd_remote_load_from_filename (remote, fn, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
fn2 = g_build_filename (TESTDATADIR, "tests", "disabled.conf", NULL);
|
||||
ret = fwupd_remote_load_from_filename (remote, fn2, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
g_assert_false (fwupd_remote_get_enabled (remote));
|
||||
g_assert_cmpint (fwupd_remote_get_keyring_kind (remote), ==, FWUPD_KEYRING_KIND_NONE);
|
||||
g_assert_cmpstr (fwupd_remote_get_username (remote), ==, NULL);
|
||||
g_assert_cmpstr (fwupd_remote_get_password (remote), ==, "");
|
||||
g_assert_cmpstr (fwupd_remote_get_filename_cache (remote), ==, "/tmp/fwupd-self-test/stable.xml");
|
||||
}
|
||||
|
||||
/* verify we used the metadata path for firmware */
|
||||
static void
|
||||
fwupd_remote_nopath_func (void)
|
||||
@ -686,6 +710,7 @@ main (int argc, char **argv)
|
||||
g_test_add_func ("/fwupd/remote{base-uri}", fwupd_remote_baseuri_func);
|
||||
g_test_add_func ("/fwupd/remote{no-path}", fwupd_remote_nopath_func);
|
||||
g_test_add_func ("/fwupd/remote{local}", fwupd_remote_local_func);
|
||||
g_test_add_func ("/fwupd/remote{duplicate}", fwupd_remote_duplicate_func);
|
||||
if (fwupd_has_system_bus ()) {
|
||||
g_test_add_func ("/fwupd/client{remotes}", fwupd_client_remotes_func);
|
||||
g_test_add_func ("/fwupd/client{devices}", fwupd_client_devices_func);
|
||||
|
Loading…
Reference in New Issue
Block a user