diff options
author | dsmith <dsmith> | 2007-08-14 15:27:58 +0000 |
---|---|---|
committer | dsmith <dsmith> | 2007-08-14 15:27:58 +0000 |
commit | b79aff3684e02d6f83a2fa2a2fcfe53d5c9d6d14 (patch) | |
tree | bb872eed2c44fbca889e0a068ecd964e86938f87 /runtime/transport/procfs.c | |
parent | 5eddf13b73a01f3b334e5be80fc3cc1b312d1fea (diff) | |
download | systemtap-steved-b79aff3684e02d6f83a2fa2a2fcfe53d5c9d6d14.tar.gz systemtap-steved-b79aff3684e02d6f83a2fa2a2fcfe53d5c9d6d14.tar.xz systemtap-steved-b79aff3684e02d6f83a2fa2a2fcfe53d5c9d6d14.zip |
2007-08-14 David Smith <dsmith@redhat.com>
Merge from setuid-branch. Changes also by Martin Hunt
<hunt@redhat.com>.
* control.c (_stp_ctl_write): Make sure we don't overflow.
(_stp_ctl_open_cmd): Do not allow multiple opens of the control
file.
(_stp_ctl_write_cmd): Once STP_START is received, ignore
everything except STP_EXIT. Create another state variable
"initialized". Don't respond to STP_SYMBOLS or STP_MODULES unless
initialized is 0. Also check that current pid is the same as the
pid that did insmod.
(_stp_register_ctl_channel): Bug fix - sets owner/group after
checking for NULL.
* procfs.c (_stp_ctl_write): Make sure we don't overflow.
(_stp_ctl_open_cmd): Do not allow multiple opens of the control
file.
(_stp_ctl_write_cmd): Once STP_START is received, ignore
everything except STP_EXIT. Create another state variable
"initialized". Don't respond to STP_SYMBOLS or STP_MODULES unless
initialized is 0. Also check that current pid is the same as the
pid that did insmod.
(_stp_register_ctl_channel): Set ownership of cmd file and percpu
files for bulkmode.
* relayfs.c (utt_trace_setup): Set ownership of percpu files.
Improved error handling.
(utt_trace_remove): Improved error checking.
* utt.c (utt_remove_tree): Improved error checking.
(utt_trace_cleanup): Ditto.
(utt_create_buf_file_callback): Set file ownership.
(utt_create_global_buf_file_callback): Set file ownership.
* transport.h: Delcare _stp_uid, _stp_gid, and _stp_init_pid.
* transport.c (_stp_transport_init): Set _stp_uid, _stp_gid, and
_stp_init_pid.
Diffstat (limited to 'runtime/transport/procfs.c')
-rw-r--r-- | runtime/transport/procfs.c | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c index 36920707..ca07660f 100644 --- a/runtime/transport/procfs.c +++ b/runtime/transport/procfs.c @@ -67,6 +67,7 @@ static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int type; + static int started = 0, initialized = 0; if (count < sizeof(int)) return 0; @@ -87,20 +88,29 @@ static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf, switch (type) { case STP_START: { - struct _stp_msg_start st; - if (count < sizeof(st)) - return 0; - if (copy_from_user (&st, buf, sizeof(st))) - return -EFAULT; - _stp_handle_start (&st); + if (started == 0) { + struct _stp_msg_start st; + if (count < sizeof(st)) + return 0; + if (copy_from_user (&st, buf, sizeof(st))) + return -EFAULT; + _stp_handle_start (&st); + started = 1; + } break; } case STP_SYMBOLS: - count = _stp_do_symbols(buf, count); + if (initialized == 0 && count && current->pid == _stp_init_pid) + count = _stp_do_symbols(buf, count); break; case STP_MODULE: - count = _stp_do_module(buf, count); + if (initialized == 0 && current->pid == _stp_init_pid) { + if (count) + count = _stp_do_module(buf, count); + else + initialized = 1; + } break; case STP_EXIT: _stp_exit_flag = 1; @@ -151,6 +161,10 @@ static int _stp_ctl_write (int type, void *data, int len) spin_unlock_irqrestore(&_stp_ready_lock, flags); #endif + /* make sure we won't overflow the buffer */ + if (unlikely(len > STP_BUFFER_SIZE)) + return 0; + numtrylock = 0; while (!spin_trylock_irqsave (&_stp_pool_lock, flags) && (++numtrylock < MAXTRYLOCK)) ndelay (TRYLOCKDELAY); @@ -237,17 +251,23 @@ _stp_ctl_read_cmd (struct file *file, char __user *buf, size_t count, loff_t *pp return len; } +static int _stp_ctl_opens = 0; static int _stp_ctl_open_cmd (struct inode *inode, struct file *file) { + if (_stp_ctl_opens) + return -1; + + _stp_ctl_opens++; _stp_pid = current->pid; return 0; } static int _stp_ctl_close_cmd (struct inode *inode, struct file *file) { + if (_stp_ctl_opens) + _stp_ctl_opens--; _stp_pid = 0; return 0; - } static struct file_operations _stp_proc_fops_cmd = { @@ -378,9 +398,11 @@ static int _stp_register_ctl_channel (void) /* now for each cpu "n", create /proc/systemtap/module_name/n */ for_each_cpu(i) { sprintf(buf, "%d", i); - de = create_proc_entry (buf, S_IFREG|S_IRUSR, _stp_proc_mod); + de = create_proc_entry (buf, 0600, _stp_proc_mod); if (de == NULL) goto err1; + de->uid = _stp_uid; + de->gid = _stp_gid; de->proc_fops = &_stp_proc_fops; de->data = _stp_kmalloc(sizeof(int)); if (de->data == NULL) { @@ -393,9 +415,11 @@ static int _stp_register_ctl_channel (void) #endif /* STP_BULKMODE */ /* finally create /proc/systemtap/module_name/cmd */ - de = create_proc_entry ("cmd", S_IFREG|S_IRUSR|S_IWUSR, _stp_proc_mod); + de = create_proc_entry ("cmd", 0600, _stp_proc_mod); if (de == NULL) goto err1; + de->uid = _stp_uid; + de->gid = _stp_gid; de->proc_fops = &_stp_proc_fops_cmd; return 0; |