* [for-linus][PATCH 0/2] tracing: Two more small fixes for v6.7-rc8
@ 2024-01-03 1:50 Steven Rostedt
2024-01-03 1:50 ` [for-linus][PATCH 1/2] tracefs: Check for dentry->d_inode exists in set_gid() Steven Rostedt
2024-01-03 1:50 ` [for-linus][PATCH 2/2] eventfs: Fix bitwise fields for "is_events" Steven Rostedt
0 siblings, 2 replies; 3+ messages in thread
From: Steven Rostedt @ 2024-01-03 1:50 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton
tracing fixes for v6.7-rc8:
- Fix a NULL kernel dereference in set_gid() on tracefs mounting.
When tracefs is mounted with "gid=1000", it will update the existing
dentries to have the new gid. The tracefs_inode which is retrieved
by a container_of(dentry->d_inode) has flags to see if the inode
belongs to the eventfs system.
The issue that was fixed was if getdents() was called on tracefs
that was previously mounted, and was not closed. It will leave
a "cursor dentry" in the subdirs list of the current dentries that
set_gid() walks. On a remount of tracefs, the container_of(dentry->d_inode)
will dereference a NULL pointer and cause a crash when referenced.
Simply have a check for dentry->d_inode to see if it is NULL and if
so, skip that entry.
- Fix the bits of the eventfs_inode structure. The "is_events" bit
was taken from the nr_entries field, but the nr_entries field wasn't
updated to be 30 bits and was still 31. Including the "is_freed" bit
this would use 33 bits which would make the structure use another
integer for just one bit.
Steven Rostedt (Google) (2):
tracefs: Check for dentry->d_inode exists in set_gid()
eventfs: Fix bitwise fields for "is_events"
----
fs/tracefs/inode.c | 4 ++++
fs/tracefs/internal.h | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
^ permalink raw reply [flat|nested] 3+ messages in thread
* [for-linus][PATCH 1/2] tracefs: Check for dentry->d_inode exists in set_gid()
2024-01-03 1:50 [for-linus][PATCH 0/2] tracing: Two more small fixes for v6.7-rc8 Steven Rostedt
@ 2024-01-03 1:50 ` Steven Rostedt
2024-01-03 1:50 ` [for-linus][PATCH 2/2] eventfs: Fix bitwise fields for "is_events" Steven Rostedt
1 sibling, 0 replies; 3+ messages in thread
From: Steven Rostedt @ 2024-01-03 1:50 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable, Ubisectech Sirius
From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
If a getdents() is called on the tracefs directory but does not get all
the files, it can leave a "cursor" dentry in the d_subdirs list of tracefs
dentry. This cursor dentry does not have a d_inode for it. Before
referencing tracefs_inode from the dentry, the d_inode must first be
checked if it has content. If not, then it's not a tracefs_inode and can
be ignored.
The following caused a crash:
#define getdents64(fd, dirp, count) syscall(SYS_getdents64, fd, dirp, count)
#define BUF_SIZE 256
#define TDIR "/tmp/file0"
int main(void)
{
char buf[BUF_SIZE];
int fd;
int n;
mkdir(TDIR, 0777);
mount(NULL, TDIR, "tracefs", 0, NULL);
fd = openat(AT_FDCWD, TDIR, O_RDONLY);
n = getdents64(fd, buf, BUF_SIZE);
ret = mount(NULL, TDIR, NULL, MS_NOSUID|MS_REMOUNT|MS_RELATIME|MS_LAZYTIME,
"gid=1000");
return 0;
}
That's because the 256 BUF_SIZE was not big enough to read all the
dentries of the tracefs file system and it left a "cursor" dentry in the
subdirs of the tracefs root inode. Then on remounting with "gid=1000",
it would cause an iteration of all dentries which hit:
ti = get_tracefs(dentry->d_inode);
if (ti && (ti->flags & TRACEFS_EVENT_INODE))
eventfs_update_gid(dentry, gid);
Which crashed because of the dereference of the cursor dentry which had a NULL
d_inode.
In the subdir loop of the dentry lookup of set_gid(), if a child has a
NULL d_inode, simply skip it.
Link: https://lore.kernel.org/all/20240102135637.3a21fb10@gandalf.local.home/
Link: https://lore.kernel.org/linux-trace-kernel/20240102151249.05da244d@gandalf.local.home
Cc: stable@vger.kernel.org
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fixes: 7e8358edf503e ("eventfs: Fix file and directory uid and gid ownership")
Reported-by: "Ubisectech Sirius" <bugreport@ubisectech.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
fs/tracefs/inode.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index 62524b20964e..bc86ffdb103b 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -215,6 +215,10 @@ static void set_gid(struct dentry *parent, kgid_t gid)
struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
next = tmp->next;
+ /* Note, getdents() can add a cursor dentry with no inode */
+ if (!dentry->d_inode)
+ continue;
+
spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
change_gid(dentry, gid);
--
2.42.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [for-linus][PATCH 2/2] eventfs: Fix bitwise fields for "is_events"
2024-01-03 1:50 [for-linus][PATCH 0/2] tracing: Two more small fixes for v6.7-rc8 Steven Rostedt
2024-01-03 1:50 ` [for-linus][PATCH 1/2] tracefs: Check for dentry->d_inode exists in set_gid() Steven Rostedt
@ 2024-01-03 1:50 ` Steven Rostedt
1 sibling, 0 replies; 3+ messages in thread
From: Steven Rostedt @ 2024-01-03 1:50 UTC (permalink / raw)
To: linux-kernel
Cc: Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers, Andrew Morton,
stable
From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
A flag was needed to denote which eventfs_inode was the "events"
directory, so a bit was taken from the "nr_entries" field, as there's not
that many entries, and 2^30 is plenty. But the bit number for nr_entries
was not updated to reflect the bit taken from it, which would add an
unnecessary integer to the structure.
Link: https://lore.kernel.org/linux-trace-kernel/20240102151832.7ca87275@gandalf.local.home
Cc: stable@vger.kernel.org
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fixes: 7e8358edf503e ("eventfs: Fix file and directory uid and gid ownership")
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
fs/tracefs/internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h
index 899e447778ac..42bdeb471a07 100644
--- a/fs/tracefs/internal.h
+++ b/fs/tracefs/internal.h
@@ -63,7 +63,7 @@ struct eventfs_inode {
};
unsigned int is_freed:1;
unsigned int is_events:1;
- unsigned int nr_entries:31;
+ unsigned int nr_entries:30;
};
static inline struct tracefs_inode *get_tracefs(const struct inode *inode)
--
2.42.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-01-03 1:51 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-03 1:50 [for-linus][PATCH 0/2] tracing: Two more small fixes for v6.7-rc8 Steven Rostedt
2024-01-03 1:50 ` [for-linus][PATCH 1/2] tracefs: Check for dentry->d_inode exists in set_gid() Steven Rostedt
2024-01-03 1:50 ` [for-linus][PATCH 2/2] eventfs: Fix bitwise fields for "is_events" Steven Rostedt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox