From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org>
Synthetic events create and destroy tracefs files when they are created
and removed. The tracing subsystem has its own file descriptor
representing the state of the events attached to the tracefs files.
There's a race between the eventfs files and this file descriptor of the
tracing system where the following can cause an issue:
With two scripts 'A' and 'B' doing:
Script 'A':
echo "hello int aaa" > /sys/kernel/tracing/synthetic_events
while :
do
echo 0 > /sys/kernel/tracing/events/synthetic/hello/enable
done
Script 'B':
echo > /sys/kernel/tracing/synthetic_events
Script 'A' creates a synthetic event "hello" and then just writes zero
into its enable file.
Script 'B' removes all synthetic events (including the newly created
"hello" event).
What happens is that the opening of the "enable" file has:
{
struct trace_event_file *file = inode->i_private;
int ret;
ret = tracing_check_open_get_tr(file->tr);
[..]
But deleting the events frees the "file" descriptor, and a "use after
free" happens with the dereference at "file->tr".
The file descriptor does have a reference counter, but there needs to be a
way to decrement it from the eventfs when the eventfs_inode is removed
that represents this file descriptor.
Add an optional "release" callback to the eventfs_entry array structure,
that gets called when the eventfs file is about to be removed. This allows
for the creating on the eventfs file to increment the tracing file
descriptor ref counter. When the eventfs file is deleted, it can call the
release function that will call the put function for the tracing file
descriptor.
This will protect the tracing file from being freed while a eventfs file
that references it is being opened.
Link: https://lore.kernel.org/linux-trace-kernel/20240426073410.17154-1-Tze-nan.W…
Link: https://lore.kernel.org/linux-trace-kernel/20240502090315.448cba46@gandalf.…
Cc: stable(a)vger.kernel.org
Cc: Masami Hiramatsu <mhiramat(a)kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers(a)efficios.com>
Fixes: 5790b1fb3d672 ("eventfs: Remove eventfs_file and just use eventfs_inode")
Reported-by: Tze-nan wu <Tze-nan.Wu(a)mediatek.com>
Tested-by: Tze-nan Wu (吳澤南) <Tze-nan.Wu(a)mediatek.com>
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
---
fs/tracefs/event_inode.c | 23 +++++++++++++++++++++--
include/linux/tracefs.h | 3 +++
kernel/trace/trace_events.c | 12 ++++++++++++
3 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
index 894c6ca1e500..f5510e26f0f6 100644
--- a/fs/tracefs/event_inode.c
+++ b/fs/tracefs/event_inode.c
@@ -84,10 +84,17 @@ enum {
static void release_ei(struct kref *ref)
{
struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref);
+ const struct eventfs_entry *entry;
struct eventfs_root_inode *rei;
WARN_ON_ONCE(!ei->is_freed);
+ for (int i = 0; i < ei->nr_entries; i++) {
+ entry = &ei->entries[i];
+ if (entry->release)
+ entry->release(entry->name, ei->data);
+ }
+
kfree(ei->entry_attrs);
kfree_const(ei->name);
if (ei->is_events) {
@@ -112,6 +119,18 @@ static inline void free_ei(struct eventfs_inode *ei)
}
}
+/*
+ * Called when creation of an ei fails, do not call release() functions.
+ */
+static inline void cleanup_ei(struct eventfs_inode *ei)
+{
+ if (ei) {
+ /* Set nr_entries to 0 to prevent release() function being called */
+ ei->nr_entries = 0;
+ free_ei(ei);
+ }
+}
+
static inline struct eventfs_inode *get_ei(struct eventfs_inode *ei)
{
if (ei)
@@ -734,7 +753,7 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode
/* Was the parent freed? */
if (list_empty(&ei->list)) {
- free_ei(ei);
+ cleanup_ei(ei);
ei = NULL;
}
return ei;
@@ -835,7 +854,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
return ei;
fail:
- free_ei(ei);
+ cleanup_ei(ei);
tracefs_failed_creating(dentry);
return ERR_PTR(-ENOMEM);
}
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index 7a5fe17b6bf9..d03f74658716 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -62,6 +62,8 @@ struct eventfs_file;
typedef int (*eventfs_callback)(const char *name, umode_t *mode, void **data,
const struct file_operations **fops);
+typedef void (*eventfs_release)(const char *name, void *data);
+
/**
* struct eventfs_entry - dynamically created eventfs file call back handler
* @name: Then name of the dynamic file in an eventfs directory
@@ -72,6 +74,7 @@ typedef int (*eventfs_callback)(const char *name, umode_t *mode, void **data,
struct eventfs_entry {
const char *name;
eventfs_callback callback;
+ eventfs_release release;
};
struct eventfs_inode;
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 52f75c36bbca..6ef29eba90ce 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -2552,6 +2552,14 @@ static int event_callback(const char *name, umode_t *mode, void **data,
return 0;
}
+/* The file is incremented on creation and freeing the enable file decrements it */
+static void event_release(const char *name, void *data)
+{
+ struct trace_event_file *file = data;
+
+ event_file_put(file);
+}
+
static int
event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file)
{
@@ -2566,6 +2574,7 @@ event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file)
{
.name = "enable",
.callback = event_callback,
+ .release = event_release,
},
{
.name = "filter",
@@ -2634,6 +2643,9 @@ event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file)
return ret;
}
+ /* Gets decremented on freeing of the "enable" file */
+ event_file_get(file);
+
return 0;
}
--
2.43.0
Sysctl handlers are not supposed to modify the ctl_table passed to them.
Adapt the logic to work with a temporary
variable, similar to how it is done in other parts of the kernel.
This is also a prerequisite to enforce the immutability of the argument
through the callbacks prototy.
Fixes: 964c9dff0091 ("stackleak: Allow runtime disabling of kernel stack erasing")
Cc: stable(a)vger.kernel.org
Acked-by: Kees Cook <keescook(a)chromium.org>
Reviewed-by: Luis Chamberlain <mcgrof(a)kernel.org>
Signed-off-by: Thomas Weißschuh <linux(a)weissschuh.net>
---
This was split out of my sysctl-const-handler series [0].
As that series will take some more time, submit the patch on its own,
as it is a generic bugfix that is valuable on its own.
And I can get it out of my books.
Changelog in contrast to the patch in the series:
* Reword commit message to remove strong relation to the constification
* Cc stable
[0] https://lore.kernel.org/lkml/20240423-sysctl-const-handler-v3-0-e0beccb836e…
Cc: Joel Granados <j.granados(a)samsung.com>
---
kernel/stackleak.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/kernel/stackleak.c b/kernel/stackleak.c
index 34c9d81eea94..b292e5ca0b7d 100644
--- a/kernel/stackleak.c
+++ b/kernel/stackleak.c
@@ -27,10 +27,11 @@ static int stack_erasing_sysctl(struct ctl_table *table, int write,
int ret = 0;
int state = !static_branch_unlikely(&stack_erasing_bypass);
int prev_state = state;
+ struct ctl_table tmp = *table;
- table->data = &state;
- table->maxlen = sizeof(int);
- ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+ tmp.data = &state;
+ tmp.maxlen = sizeof(int);
+ ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
state = !!state;
if (ret || !write || state == prev_state)
return ret;
---
base-commit: f03359bca01bf4372cf2c118cd9a987a5951b1c8
change-id: 20240503-sysctl-const-stackleak-af3e67bc65b0
Best regards,
--
Thomas Weißschuh <linux(a)weissschuh.net>
If there is no bus number available for the downstream bus of the
hot-plugged bridge, pci_hp_add_bridge() will fail. The driver proceeds
regardless, and the kernel crashes.
Abort if pci_hp_add_bridge() fails.
Fixes: 7d01f70ac6f4 ("PCI: shpchp: use generic pci_hp_add_bridge()")
Signed-off-by: Nam Cao <namcao(a)linutronix.de>
Cc: Yinghai Lu <yinghai(a)kernel.org>
Cc: <stable(a)vger.kernel.org>
---
drivers/pci/hotplug/shpchp_pci.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 36db0c3c4ea6..2ac98bdc83d9 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -48,8 +48,13 @@ int shpchp_configure_device(struct slot *p_slot)
}
for_each_pci_bridge(dev, parent) {
- if (PCI_SLOT(dev->devfn) == p_slot->device)
- pci_hp_add_bridge(dev);
+ if (PCI_SLOT(dev->devfn) == p_slot->device) {
+ if (pci_hp_add_bridge(dev)) {
+ pci_stop_and_remove_bus_device(dev);
+ ret = -EINVAL;
+ goto out;
+ }
+ }
}
pci_assign_unassigned_bridge_resources(bridge);
--
2.39.2
On Fri, 2024-05-03 at 12:38 -0400, Sasha Levin wrote:
> This is a note to let you know that I've just added the patch titled
>
> wifi: nl80211: don't free NULL coalescing rule
>
> to the 6.8-stable tree which can be found at:
> http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
I was sure I pointed out before (to Greg?) that I made a mistake on this
patch and it should be dropped.
Anyway, please drop this from _all_ stable kernels. It's obviously
bogus.
johannes
To update effective size quota of DAMOS schemes on DAMON sysfs file
interface, user should write 'update_schemes_effective_quotas' to the
kdamond 'state' file. But the document is mistakenly saying the input
string as 'update_schemes_effective_bytes'. Fix it (s/bytes/quotas/).
Fixes: a6068d6dfa2f ("Docs/admin-guide/mm/damon/usage: document effective_bytes file")
Cc: <stable(a)vger.kernel.org> # 6.9.x
Signed-off-by: SeongJae Park <sj(a)kernel.org>
---
Documentation/admin-guide/mm/damon/usage.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/mm/damon/usage.rst b/Documentation/admin-guide/mm/damon/usage.rst
index 3ce3f0aaa1d5..e58ceb89ea2a 100644
--- a/Documentation/admin-guide/mm/damon/usage.rst
+++ b/Documentation/admin-guide/mm/damon/usage.rst
@@ -153,7 +153,7 @@ Users can write below commands for the kdamond to the ``state`` file.
- ``clear_schemes_tried_regions``: Clear the DAMON-based operating scheme
action tried regions directory for each DAMON-based operation scheme of the
kdamond.
-- ``update_schemes_effective_bytes``: Update the contents of
+- ``update_schemes_effective_quotas``: Update the contents of
``effective_bytes`` files for each DAMON-based operation scheme of the
kdamond. For more details, refer to :ref:`quotas directory <sysfs_quotas>`.
@@ -342,7 +342,7 @@ Based on the user-specified :ref:`goal <sysfs_schemes_quota_goals>`, the
effective size quota is further adjusted. Reading ``effective_bytes`` returns
the current effective size quota. The file is not updated in real time, so
users should ask DAMON sysfs interface to update the content of the file for
-the stats by writing a special keyword, ``update_schemes_effective_bytes`` to
+the stats by writing a special keyword, ``update_schemes_effective_quotas`` to
the relevant ``kdamonds/<N>/state`` file.
Under ``weights`` directory, three files (``sz_permil``,
--
2.39.2
The example usage of DAMOS filter sysfs files, specifically the part of
'matching' file writing for memcg type filter, is wrong. The intention
is to exclude pages of a memcg that already getting enough care from a
given scheme, but the example is setting the filter to apply the scheme
to only the pages of the memcg. Fix it.
Fixes: 9b7f9322a530 ("Docs/admin-guide/mm/damon/usage: document DAMOS filters of sysfs")
Closes: https://lore.kernel.org/r/20240317191358.97578-1-sj@kernel.org
Cc: <stable(a)vger.kernel.org> # 6.3.x
Signed-off-by: SeongJae Park <sj(a)kernel.org>
---
Documentation/admin-guide/mm/damon/usage.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/mm/damon/usage.rst b/Documentation/admin-guide/mm/damon/usage.rst
index 69bc8fabf378..3ce3f0aaa1d5 100644
--- a/Documentation/admin-guide/mm/damon/usage.rst
+++ b/Documentation/admin-guide/mm/damon/usage.rst
@@ -434,7 +434,7 @@ pages of all memory cgroups except ``/having_care_already``.::
# # further filter out all cgroups except one at '/having_care_already'
echo memcg > 1/type
echo /having_care_already > 1/memcg_path
- echo N > 1/matching
+ echo Y > 1/matching
Note that ``anon`` and ``memcg`` filters are currently supported only when
``paddr`` :ref:`implementation <sysfs_context>` is being used.
--
2.39.2
A recent commit fixed the code that parses the firmware files before
downloading them to the controller but introduced a memory leak in case
the sanity checks ever fail.
Make sure to free the firmware buffer before returning on errors.
Fixes: 6fb81c405bfa ("Bluetooth: qca: add missing firmware sanity checks")
Cc: stable(a)vger.kernel.org # 4.19
Signed-off-by: Johan Hovold <johan+linaro(a)kernel.org>
---
drivers/bluetooth/btqca.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Luiz,
Sorry for not catching this before posting v2.
Feel to free to squash this fix into commit 6fb81c405bfa ("Bluetooth:
qca: add missing firmware sanity checks") in the bluetooth-next branch
if you prefer.
Note that the commit id in the Fixes tag above won't match if you cherry
pick both commits to the fixes branch.
Johan
diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index 125f140e012a..59e384fa1a0c 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -676,7 +676,7 @@ static int qca_download_firmware(struct hci_dev *hdev,
ret = qca_tlv_check_data(hdev, config, data, size, soc_type);
if (ret)
- return ret;
+ goto out;
segment = data;
remain = size;
--
2.43.2
From: Eric Biggers <ebiggers(a)google.com>
Since the fsverity sysctl registration runs as a builtin initcall, there
is no corresponding sysctl deregistration and the resulting struct
ctl_table_header is not used. This can cause a kmemleak warning just
after the system boots up. (A pointer to the ctl_table_header is stored
in the fsverity_sysctl_header static variable, which kmemleak should
detect; however, the compiler can optimize out that variable.) Avoid
the kmemleak warning by using register_sysctl_init() which is intended
for use by builtin initcalls and uses kmemleak_not_leak().
Reported-by: Yi Zhang <yi.zhang(a)redhat.com>
Closes: https://lore.kernel.org/r/CAHj4cs8DTSvR698UE040rs_pX1k-WVe7aR6N2OoXXuhXJPDC…
Cc: stable(a)vger.kernel.org
Signed-off-by: Eric Biggers <ebiggers(a)google.com>
---
fs/verity/init.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/fs/verity/init.c b/fs/verity/init.c
index cb2c9aac61ed..f440f0e61e3e 100644
--- a/fs/verity/init.c
+++ b/fs/verity/init.c
@@ -8,12 +8,10 @@
#include "fsverity_private.h"
#include <linux/ratelimit.h>
#ifdef CONFIG_SYSCTL
-static struct ctl_table_header *fsverity_sysctl_header;
-
static struct ctl_table fsverity_sysctl_table[] = {
#ifdef CONFIG_FS_VERITY_BUILTIN_SIGNATURES
{
.procname = "require_signatures",
.data = &fsverity_require_signatures,
@@ -26,14 +24,11 @@ static struct ctl_table fsverity_sysctl_table[] = {
#endif
};
static void __init fsverity_init_sysctl(void)
{
- fsverity_sysctl_header = register_sysctl("fs/verity",
- fsverity_sysctl_table);
- if (!fsverity_sysctl_header)
- panic("fsverity sysctl registration failed");
+ register_sysctl_init("fs/verity", fsverity_sysctl_table);
}
#else /* CONFIG_SYSCTL */
static inline void fsverity_init_sysctl(void)
{
}
base-commit: 18daea77cca626f590fb140fc11e3a43c5d41354
--
2.45.0
Commit 5ec27ec735ba ("fs/proc/proc_sysctl.c: fix the default values of i_uid/i_gid on /proc/sys inodes.")
added defaults for i_uid/i_gid when set_ownership() is not implemented.
It missed to also adjust net_ctl_set_ownership() to use the same default
values in case the computation of a better value fails.
Instead always initialize i_uid/i_gid inside the sysfs core so
set_ownership() can safely skip setting them.
Fixes: 5ec27ec735ba ("fs/proc/proc_sysctl.c: fix the default values of i_uid/i_gid on /proc/sys inodes.")
Cc: stable(a)vger.kernel.org
Signed-off-by: Thomas Weißschuh <linux(a)weissschuh.net>
---
Changes in v3:
- Rebase onto v6.9-rc1
- Reword commit message and mention correct fixed commit
- Link to v2: https://lore.kernel.org/r/20240322-sysctl-net-ownership-v2-1-a8b4a3306542@w…
Changes in v2:
- Move the fallback logic to the sysctl core
- Link to v1: https://lore.kernel.org/r/20240315-sysctl-net-ownership-v1-1-2b465555a292@w…
---
fs/proc/proc_sysctl.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 37cde0efee57..9e34ab9c21e4 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -479,12 +479,10 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
make_empty_dir_inode(inode);
}
+ inode->i_uid = GLOBAL_ROOT_UID;
+ inode->i_gid = GLOBAL_ROOT_GID;
if (root->set_ownership)
root->set_ownership(head, table, &inode->i_uid, &inode->i_gid);
- else {
- inode->i_uid = GLOBAL_ROOT_UID;
- inode->i_gid = GLOBAL_ROOT_GID;
- }
return inode;
}
---
base-commit: 4cece764965020c22cff7665b18a012006359095
change-id: 20240315-sysctl-net-ownership-bc4e17eaeea6
Best regards,
--
Thomas Weißschuh <linux(a)weissschuh.net>
From: Johannes Berg <johannes.berg(a)intel.com>
[ Upstream commit 67dfa589aa8806c7959cbca2f4613b8d41c75a06 ]
When probing a client, first check if we have it, and then
check for the channel context, otherwise you can trigger
the warning there easily by probing when the AP isn't even
started yet. Since a client existing means the AP is also
operating, we can then keep the warning.
Also simplify the moved code a bit.
Reported-by: syzbot+999fac712d84878a7379(a)syzkaller.appspotmail.com
Signed-off-by: Johannes Berg <johannes.berg(a)intel.com>
Signed-off-by: Alexander Ofitserov <oficerovas(a)altlinux.org>
---
net/mac80211/cfg.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f277ce839ddb2e..5921f4266d7347 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3681,19 +3681,20 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
mutex_lock(&local->mtx);
rcu_read_lock();
+ sta = sta_info_get_bss(sdata, peer);
+ if (!sta) {
+ ret = -ENOLINK;
+ goto unlock;
+ }
+
+ qos = sta->sta.wme;
+
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
if (WARN_ON(!chanctx_conf)) {
ret = -EINVAL;
goto unlock;
}
band = chanctx_conf->def.chan->band;
- sta = sta_info_get_bss(sdata, peer);
- if (sta) {
- qos = sta->sta.wme;
- } else {
- ret = -ENOLINK;
- goto unlock;
- }
if (qos) {
fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
--
2.42.1