Skip to content

Commit

Permalink
s390/ipl: fix out of bounds access in scpdata_write
Browse files Browse the repository at this point in the history
The input buffer in reipl_fcp_scpdata_write is accessed out of bounds
when an offset is specified. The problem is that the offset refers to
the data we should write to and not to the buffer we read from.

So instead of
        memcpy(scp_data, buf + off, count);
we could just do
        memcpy(scp_data + off, buf, count);

However we not only modify the data but also store its length. For this to
work we'd need to remember a state per open FH. Since that's not possible
with sysfs callbacks let's just fail when an offset is specified.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Acked-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Sebastian Ott authored and Martin Schwidefsky committed Nov 11, 2015
1 parent 52d43d8 commit e0bedad
Showing 1 changed file with 5 additions and 12 deletions.
17 changes: 5 additions & 12 deletions arch/s390/kernel/ipl.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,21 +687,14 @@ static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
size_t scpdata_len = count;
size_t padding;
size_t scpdata_len;

if (off < 0)
return -EINVAL;

if (off >= DIAG308_SCPDATA_SIZE)
return -ENOSPC;

if (count > DIAG308_SCPDATA_SIZE - off)
count = DIAG308_SCPDATA_SIZE - off;

memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf + off, count);
scpdata_len = off + count;
if (off)
return -EINVAL;

memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf, count);
if (scpdata_len % 8) {
padding = 8 - (scpdata_len % 8);
memset(reipl_block_fcp->ipl_info.fcp.scp_data + scpdata_len,
Expand All @@ -717,7 +710,7 @@ static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
}
static struct bin_attribute sys_reipl_fcp_scp_data_attr =
__BIN_ATTR(scp_data, (S_IRUGO | S_IWUSR), reipl_fcp_scpdata_read,
reipl_fcp_scpdata_write, PAGE_SIZE);
reipl_fcp_scpdata_write, DIAG308_SCPDATA_SIZE);

static struct bin_attribute *reipl_fcp_bin_attrs[] = {
&sys_reipl_fcp_scp_data_attr,
Expand Down

0 comments on commit e0bedad

Please sign in to comment.