From 4fe5604fa18e86a3171038b836fe45cb25524403 Mon Sep 17 00:00:00 2001 From: Paul Jackson Date: Sun, 30 Nov 2003 21:13:14 -0800 Subject: [PATCH] [PATCH] ia64: fix samp_affinity user-space accesses Here is a new improved patch for verifying user access to string passed in to kernel on write to /proc/irq//smp_affinity. The access_ok() but missing __get_user() on each byte earlier patch has been replaced with a copy_from_user(). I have built it and verified that it handles write requests as before, on an ia64 system (well - you can no longer pass more than 14 spaces after the 'R' - tough). --- arch/ia64/kernel/irq.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index f9601ef77d017..5a768ed52bdde 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -997,21 +998,37 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer, unsigned int irq = (unsigned long) data; int full_count = count, err; cpumask_t new_value, tmp; - const char *buf = buffer; +# define R_PREFIX_LEN 16 + char rbuf[R_PREFIX_LEN]; + int rlen; + int prelen; irq_desc_t *desc = irq_descp(irq); - int redir; if (!desc->handler->set_affinity) return -EIO; - if (buf[0] == 'r' || buf[0] == 'R') { - ++buf; - while (*buf == ' ') ++buf; - redir = 1; - } else - redir = 0; + /* + * If string being written starts with a prefix of 'r' or 'R' + * and some limited number of spaces, set IA64_IRQ_REDIRECTED. + * If more than (R_PREFIX_LEN - 2) spaces are passed, they won't + * all be trimmed as part of prelen, the untrimmed spaces will + * cause the hex parsing to fail, and this write() syscall will + * fail with EINVAL. + */ + + if (!count) + return -EINVAL; + rlen = min(sizeof(rbuf)-1, count); + if (copy_from_user(rbuf, buffer, rlen)) + return -EFAULT; + rbuf[rlen] = 0; + prelen = 0; + if (tolower(*rbuf) == 'r') { + prelen = strspn(rbuf, "Rr "); + irq |= IA64_IRQ_REDIRECTED; + } - err = parse_hex_value(buf, count, &new_value); + err = parse_hex_value(buffer+prelen, count-prelen, &new_value); if (err) return err; @@ -1024,7 +1041,7 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer, if (cpus_empty(tmp)) return -EINVAL; - desc->handler->set_affinity(irq | (redir? IA64_IRQ_REDIRECTED : 0), new_value); + desc->handler->set_affinity(irq, new_value); return full_count; } -- 2.53.0