Revert "eventfs: Do not differentiate the toplevel events directory"

This reverts commit e26405d5b2 which is
commit d53891d348 upstream.

It breaks the Android kernel abi and can be brought back in the future
in an abi-safe way if it is really needed.

Bug: 161946584
Change-Id: Ie3848e673e1a7feac84a7ec3e8d88a4c3e46080a
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2024-06-15 08:49:51 +00:00
parent 5ef5f28bbb
commit 0902992e03
2 changed files with 25 additions and 11 deletions

View File

@ -57,6 +57,7 @@ enum {
EVENTFS_SAVE_MODE = BIT(16),
EVENTFS_SAVE_UID = BIT(17),
EVENTFS_SAVE_GID = BIT(18),
EVENTFS_TOPLEVEL = BIT(19),
};
#define EVENTFS_MODE_MASK (EVENTFS_SAVE_MODE - 1)
@ -181,10 +182,14 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,
return ret;
}
static void update_events_attr(struct eventfs_inode *ei, struct super_block *sb)
static void update_top_events_attr(struct eventfs_inode *ei, struct super_block *sb)
{
struct inode *root;
/* Only update if the "events" was on the top level */
if (!ei || !(ei->attr.mode & EVENTFS_TOPLEVEL))
return;
/* Get the tracefs root inode. */
root = d_inode(sb->s_root);
ei->attr.uid = root->i_uid;
@ -197,10 +202,10 @@ static void set_top_events_ownership(struct inode *inode)
struct eventfs_inode *ei = ti->private;
/* The top events directory doesn't get automatically updated */
if (!ei || !ei->is_events)
if (!ei || !ei->is_events || !(ei->attr.mode & EVENTFS_TOPLEVEL))
return;
update_events_attr(ei, inode->i_sb);
update_top_events_attr(ei, inode->i_sb);
if (!(ei->attr.mode & EVENTFS_SAVE_UID))
inode->i_uid = ei->attr.uid;
@ -229,7 +234,7 @@ static int eventfs_permission(struct mnt_idmap *idmap,
return generic_permission(idmap, inode, mask);
}
static const struct inode_operations eventfs_dir_inode_operations = {
static const struct inode_operations eventfs_root_dir_inode_operations = {
.lookup = eventfs_root_lookup,
.setattr = eventfs_set_attr,
.getattr = eventfs_get_attr,
@ -297,7 +302,7 @@ static struct eventfs_inode *eventfs_find_events(struct dentry *dentry)
// Walk upwards until you find the events inode
} while (!ei->is_events);
update_events_attr(ei, dentry->d_sb);
update_top_events_attr(ei, dentry->d_sb);
return ei;
}
@ -401,7 +406,7 @@ static struct dentry *lookup_dir_entry(struct dentry *dentry,
update_inode_attr(dentry, inode, &ei->attr,
S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
inode->i_op = &eventfs_dir_inode_operations;
inode->i_op = &eventfs_root_dir_inode_operations;
inode->i_fop = &eventfs_file_operations;
/* All directories will have the same inode number */
@ -750,6 +755,14 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
uid = d_inode(dentry->d_parent)->i_uid;
gid = d_inode(dentry->d_parent)->i_gid;
/*
* If the events directory is of the top instance, then parent
* is NULL. Set the attr.mode to reflect this and its permissions will
* default to the tracefs root dentry.
*/
if (!parent)
ei->attr.mode = EVENTFS_TOPLEVEL;
/* This is used as the default ownership of the files and directories */
ei->attr.uid = uid;
ei->attr.gid = gid;
@ -758,13 +771,13 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
INIT_LIST_HEAD(&ei->list);
ti = get_tracefs(inode);
ti->flags |= TRACEFS_EVENT_INODE;
ti->flags |= TRACEFS_EVENT_INODE | TRACEFS_EVENT_TOP_INODE;
ti->private = ei;
inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
inode->i_uid = uid;
inode->i_gid = gid;
inode->i_op = &eventfs_dir_inode_operations;
inode->i_op = &eventfs_root_dir_inode_operations;
inode->i_fop = &eventfs_file_operations;
dentry->d_fsdata = get_ei(ei);

View File

@ -4,9 +4,10 @@
enum {
TRACEFS_EVENT_INODE = BIT(1),
TRACEFS_GID_PERM_SET = BIT(2),
TRACEFS_UID_PERM_SET = BIT(3),
TRACEFS_INSTANCE_INODE = BIT(4),
TRACEFS_EVENT_TOP_INODE = BIT(2),
TRACEFS_GID_PERM_SET = BIT(3),
TRACEFS_UID_PERM_SET = BIT(4),
TRACEFS_INSTANCE_INODE = BIT(5),
};
struct tracefs_inode {