From b79aff3684e02d6f83a2fa2a2fcfe53d5c9d6d14 Mon Sep 17 00:00:00 2001 From: dsmith Date: Tue, 14 Aug 2007 15:27:58 +0000 Subject: 2007-08-14 David Smith Merge from setuid-branch. Changes also by Martin Hunt . * 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. --- runtime/transport/control.c | 48 +++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'runtime/transport/control.c') diff --git a/runtime/transport/control.c b/runtime/transport/control.c index 68c3b9ae..1f7f70bd 100644 --- a/runtime/transport/control.c +++ b/runtime/transport/control.c @@ -21,6 +21,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; @@ -28,7 +29,7 @@ static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf, if (get_user(type, (int __user *)buf)) return -EFAULT; - //kbug ("count:%d type:%d\n", count, type); + // kbug ("count:%d type:%d\n", count, type); if (type == STP_SYMBOLS) { count -= sizeof(long); @@ -41,20 +42,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; @@ -73,11 +83,13 @@ static ssize_t _stp_ctl_write_cmd (struct file *file, const char __user *buf, return count; } +#define STP_CTL_BUFFER_SIZE 256 + struct _stp_buffer { struct list_head list; int len; int type; - char buf[256]; + char buf[STP_CTL_BUFFER_SIZE]; }; static DECLARE_WAIT_QUEUE_HEAD(_stp_ctl_wq); @@ -127,6 +139,10 @@ static int _stp_ctl_write (int type, void *data, unsigned len) _stp_ctl_write_dbug(type, data, len); #endif + /* make sure we won't overflow the buffer */ + if (unlikely(len > STP_CTL_BUFFER_SIZE)) + return 0; + numtrylock = 0; while (!spin_trylock_irqsave (&_stp_pool_lock, flags) && (++numtrylock < MAXTRYLOCK)) ndelay (TRYLOCKDELAY); @@ -145,7 +161,7 @@ static int _stp_ctl_write (int type, void *data, unsigned len) spin_unlock_irqrestore(&_stp_pool_lock, flags); bptr->type = type; - memcpy(bptr->buf, data, min((size_t) len, sizeof(bptr->buf))); + memcpy(bptr->buf, data, len); bptr->len = len; /* put it on the pool of ready buffers */ @@ -215,17 +231,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_ctl_fops_cmd = { @@ -267,6 +289,8 @@ static int _stp_register_ctl_channel (void) _stp_cmd_file = debugfs_create_file("cmd", 0600, _stp_utt->dir, NULL, &_stp_ctl_fops_cmd); if (_stp_cmd_file == NULL) goto err0; + _stp_cmd_file->d_inode->i_uid = _stp_uid;; + _stp_cmd_file->d_inode->i_gid = _stp_gid; return 0; err0: -- cgit