This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[PATCH] Do not use relay_file_operations directly.
- From: Przemyslaw Pawelczyk <przemyslaw at pawelczyk dot it>
- To: systemtap at sourceware dot org
- Date: Thu, 1 Jul 2010 11:30:17 +0200
- Subject: [PATCH] Do not use relay_file_operations directly.
- Mail-from: 8af0ed12bb050d38cb655eac6ca19efb9ff959d3 Mon Sep 17 00:00:00 2001
Reference counting is important to avoid removing the module while the
file exposing relay channel is being used. SystemTap alone does not need
it, but malicious user may block reloading the module by opening such
file and stap user won't notice it during unloading.
relay_file_operations defined and exported in kernel/relay.c is const
and .owner is obviously not set there, hence it shouldn't be used
directly by any kernel module.
Add relay_file_operations_w_owner and use it instead of mentioned one to
fix 'trace' file handling w.r.t. module unloading.
* runtime/transport/relay_v2.c: Add owner to the trace file.
---
runtime/transport/relay_v2.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/runtime/transport/relay_v2.c b/runtime/transport/relay_v2.c
index 104b14e..974941d 100644
--- a/runtime/transport/relay_v2.c
+++ b/runtime/transport/relay_v2.c
@@ -51,6 +51,10 @@ struct _stp_relay_data_type {
};
struct _stp_relay_data_type _stp_relay_data;
+/* relay_file_operations is const, so .owner is obviously not set there.
+ * Below struct, filled in _stp_transport_data_fs_init(), fixes it. */
+static struct file_operations relay_file_operations_w_owner;
+
/*
* __stp_relay_switch_subbuf - switch to a new sub-buffer
*
@@ -204,7 +208,7 @@ __stp_relay_create_buf_file_callback(const char *filename,
int *is_global)
{
struct dentry *file = debugfs_create_file(filename, mode, parent, buf,
- &relay_file_operations);
+ &relay_file_operations_w_owner);
/*
* Here's what 'is_global' does (from linux/relay.h):
*
@@ -317,6 +321,8 @@ static int _stp_transport_data_fs_init(void)
"log buffer size exceeds free memory(%luMB)\n",
MB(si.freeram));
}
+ relay_file_operations_w_owner = relay_file_operations;
+ relay_file_operations_w_owner.owner = THIS_MODULE;
#if (RELAYFS_CHANNEL_VERSION >= 7)
_stp_relay_data.rchan = relay_open("trace", _stp_get_module_dir(),
_stp_subbuf_size, _stp_nsubbufs,
--
1.7.1