Skip to content

Commit 20a7b6b

Browse files
committed
Merge tag 'driver-core-5.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core fixes from Greg KH: "Here are some small driver core and debugfs fixes for 5.9-rc5 Included in here are: - firmware loader memory leak fix - firmware loader testing fixes for non-EFI systems - device link locking fixes found by lockdep - kobject_del() bugfix that has been affecting some callers - debugfs minor fix All of these have been in linux-next for a while with no reported issues" * tag 'driver-core-5.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: test_firmware: Test platform fw loading on non-EFI systems PM: <linux/device.h>: fix @em_pd kernel-doc warning kobject: Drop unneeded conditional in __kobject_del() driver core: Fix device_pm_lock() locking for device links MAINTAINERS: Add the security document to SECURITY CONTACT driver code: print symbolic error code debugfs: Fix module state check condition kobject: Restore old behaviour of kobject_del(NULL) firmware_loader: fix memory leak for paged buffer
2 parents 2a1a4be + baaabec commit 20a7b6b

File tree

9 files changed

+39
-27
lines changed

9 files changed

+39
-27
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15577,6 +15577,7 @@ F: include/uapi/linux/sed*
1557715577
SECURITY CONTACT
1557815578
M: Security Officers <security@kernel.org>
1557915579
S: Supported
15580+
F: Documentation/admin-guide/security-bugs.rst
1558015581

1558115582
SECURITY SUBSYSTEM
1558215583
M: James Morris <jmorris@namei.org>

drivers/base/core.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -807,9 +807,7 @@ static void device_link_put_kref(struct device_link *link)
807807
void device_link_del(struct device_link *link)
808808
{
809809
device_links_write_lock();
810-
device_pm_lock();
811810
device_link_put_kref(link);
812-
device_pm_unlock();
813811
device_links_write_unlock();
814812
}
815813
EXPORT_SYMBOL_GPL(device_link_del);
@@ -830,7 +828,6 @@ void device_link_remove(void *consumer, struct device *supplier)
830828
return;
831829

832830
device_links_write_lock();
833-
device_pm_lock();
834831

835832
list_for_each_entry(link, &supplier->links.consumers, s_node) {
836833
if (link->consumer == consumer) {
@@ -839,7 +836,6 @@ void device_link_remove(void *consumer, struct device *supplier)
839836
}
840837
}
841838

842-
device_pm_unlock();
843839
device_links_write_unlock();
844840
}
845841
EXPORT_SYMBOL_GPL(device_link_remove);
@@ -4237,10 +4233,10 @@ int dev_err_probe(const struct device *dev, int err, const char *fmt, ...)
42374233
vaf.va = &args;
42384234

42394235
if (err != -EPROBE_DEFER) {
4240-
dev_err(dev, "error %d: %pV", err, &vaf);
4236+
dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
42414237
} else {
42424238
device_set_deferred_probe_reason(dev, &vaf);
4243-
dev_dbg(dev, "error %d: %pV", err, &vaf);
4239+
dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
42444240
}
42454241

42464242
va_end(args);

drivers/base/firmware_loader/firmware.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,12 @@ int assign_fw(struct firmware *fw, struct device *device, u32 opt_flags);
142142
void fw_free_paged_buf(struct fw_priv *fw_priv);
143143
int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed);
144144
int fw_map_paged_buf(struct fw_priv *fw_priv);
145+
bool fw_is_paged_buf(struct fw_priv *fw_priv);
145146
#else
146147
static inline void fw_free_paged_buf(struct fw_priv *fw_priv) {}
147148
static inline int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed) { return -ENXIO; }
148149
static inline int fw_map_paged_buf(struct fw_priv *fw_priv) { return -ENXIO; }
150+
static inline bool fw_is_paged_buf(struct fw_priv *fw_priv) { return false; }
149151
#endif
150152

151153
#endif /* __FIRMWARE_LOADER_H */

drivers/base/firmware_loader/main.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,11 @@ static void __free_fw_priv(struct kref *ref)
252252
list_del(&fw_priv->list);
253253
spin_unlock(&fwc->lock);
254254

255-
fw_free_paged_buf(fw_priv); /* free leftover pages */
256-
if (!fw_priv->allocated_size)
255+
if (fw_is_paged_buf(fw_priv))
256+
fw_free_paged_buf(fw_priv);
257+
else if (!fw_priv->allocated_size)
257258
vfree(fw_priv->data);
259+
258260
kfree_const(fw_priv->fw_name);
259261
kfree(fw_priv);
260262
}
@@ -268,13 +270,20 @@ static void free_fw_priv(struct fw_priv *fw_priv)
268270
}
269271

270272
#ifdef CONFIG_FW_LOADER_PAGED_BUF
273+
bool fw_is_paged_buf(struct fw_priv *fw_priv)
274+
{
275+
return fw_priv->is_paged_buf;
276+
}
277+
271278
void fw_free_paged_buf(struct fw_priv *fw_priv)
272279
{
273280
int i;
274281

275282
if (!fw_priv->pages)
276283
return;
277284

285+
vunmap(fw_priv->data);
286+
278287
for (i = 0; i < fw_priv->nr_pages; i++)
279288
__free_page(fw_priv->pages[i]);
280289
kvfree(fw_priv->pages);
@@ -328,10 +337,6 @@ int fw_map_paged_buf(struct fw_priv *fw_priv)
328337
if (!fw_priv->data)
329338
return -ENOMEM;
330339

331-
/* page table is no longer needed after mapping, let's free */
332-
kvfree(fw_priv->pages);
333-
fw_priv->pages = NULL;
334-
335340
return 0;
336341
}
337342
#endif

drivers/firmware/efi/embedded-firmware.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616

1717
/* Exported for use by lib/test_firmware.c only */
1818
LIST_HEAD(efi_embedded_fw_list);
19-
EXPORT_SYMBOL_GPL(efi_embedded_fw_list);
20-
21-
static bool checked_for_fw;
19+
EXPORT_SYMBOL_NS_GPL(efi_embedded_fw_list, TEST_FIRMWARE);
20+
bool efi_embedded_fw_checked;
21+
EXPORT_SYMBOL_NS_GPL(efi_embedded_fw_checked, TEST_FIRMWARE);
2222

2323
static const struct dmi_system_id * const embedded_fw_table[] = {
2424
#ifdef CONFIG_TOUCHSCREEN_DMI
@@ -116,14 +116,14 @@ void __init efi_check_for_embedded_firmwares(void)
116116
}
117117
}
118118

119-
checked_for_fw = true;
119+
efi_embedded_fw_checked = true;
120120
}
121121

122122
int efi_get_embedded_fw(const char *name, const u8 **data, size_t *size)
123123
{
124124
struct efi_embedded_fw *iter, *fw = NULL;
125125

126-
if (!checked_for_fw) {
126+
if (!efi_embedded_fw_checked) {
127127
pr_warn("Warning %s called while we did not check for embedded fw\n",
128128
__func__);
129129
return -ENOENT;

fs/debugfs/file.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ static int open_proxy_open(struct inode *inode, struct file *filp)
177177
goto out;
178178

179179
if (!fops_get(real_fops)) {
180-
#ifdef MODULE
180+
#ifdef CONFIG_MODULES
181181
if (real_fops->owner &&
182182
real_fops->owner->state == MODULE_STATE_GOING)
183183
goto out;
@@ -312,7 +312,7 @@ static int full_proxy_open(struct inode *inode, struct file *filp)
312312
goto out;
313313

314314
if (!fops_get(real_fops)) {
315-
#ifdef MODULE
315+
#ifdef CONFIG_MODULES
316316
if (real_fops->owner &&
317317
real_fops->owner->state == MODULE_STATE_GOING)
318318
goto out;

include/linux/efi_embedded_fw.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#define EFI_EMBEDDED_FW_PREFIX_LEN 8
99

1010
/*
11-
* This struct and efi_embedded_fw_list are private to the efi-embedded fw
12-
* implementation they are in this header for use by lib/test_firmware.c only!
11+
* This struct is private to the efi-embedded fw implementation.
12+
* They are in this header for use by lib/test_firmware.c only!
1313
*/
1414
struct efi_embedded_fw {
1515
struct list_head list;
@@ -18,8 +18,6 @@ struct efi_embedded_fw {
1818
size_t length;
1919
};
2020

21-
extern struct list_head efi_embedded_fw_list;
22-
2321
/**
2422
* struct efi_embedded_fw_desc - This struct is used by the EFI embedded-fw
2523
* code to search for embedded firmwares.

lib/kobject.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -604,9 +604,6 @@ static void __kobject_del(struct kobject *kobj)
604604
struct kernfs_node *sd;
605605
const struct kobj_type *ktype;
606606

607-
if (!kobj)
608-
return;
609-
610607
sd = kobj->sd;
611608
ktype = get_ktype(kobj);
612609

@@ -637,8 +634,12 @@ static void __kobject_del(struct kobject *kobj)
637634
*/
638635
void kobject_del(struct kobject *kobj)
639636
{
640-
struct kobject *parent = kobj->parent;
637+
struct kobject *parent;
638+
639+
if (!kobj)
640+
return;
641641

642+
parent = kobj->parent;
642643
__kobject_del(kobj);
643644
kobject_put(parent);
644645
}

lib/test_firmware.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <linux/vmalloc.h>
2727
#include <linux/efi_embedded_fw.h>
2828

29+
MODULE_IMPORT_NS(TEST_FIRMWARE);
30+
2931
#define TEST_FIRMWARE_NAME "test-firmware.bin"
3032
#define TEST_FIRMWARE_NUM_REQS 4
3133
#define TEST_FIRMWARE_BUF_SIZE SZ_1K
@@ -489,6 +491,9 @@ static ssize_t trigger_request_store(struct device *dev,
489491
static DEVICE_ATTR_WO(trigger_request);
490492

491493
#ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
494+
extern struct list_head efi_embedded_fw_list;
495+
extern bool efi_embedded_fw_checked;
496+
492497
static ssize_t trigger_request_platform_store(struct device *dev,
493498
struct device_attribute *attr,
494499
const char *buf, size_t count)
@@ -501,6 +506,7 @@ static ssize_t trigger_request_platform_store(struct device *dev,
501506
};
502507
struct efi_embedded_fw efi_embedded_fw;
503508
const struct firmware *firmware = NULL;
509+
bool saved_efi_embedded_fw_checked;
504510
char *name;
505511
int rc;
506512

@@ -513,6 +519,8 @@ static ssize_t trigger_request_platform_store(struct device *dev,
513519
efi_embedded_fw.data = (void *)test_data;
514520
efi_embedded_fw.length = sizeof(test_data);
515521
list_add(&efi_embedded_fw.list, &efi_embedded_fw_list);
522+
saved_efi_embedded_fw_checked = efi_embedded_fw_checked;
523+
efi_embedded_fw_checked = true;
516524

517525
pr_info("loading '%s'\n", name);
518526
rc = firmware_request_platform(&firmware, name, dev);
@@ -530,6 +538,7 @@ static ssize_t trigger_request_platform_store(struct device *dev,
530538
rc = count;
531539

532540
out:
541+
efi_embedded_fw_checked = saved_efi_embedded_fw_checked;
533542
release_firmware(firmware);
534543
list_del(&efi_embedded_fw.list);
535544
kfree(name);

0 commit comments

Comments
 (0)