[prev in list] [next in list] [prev in thread] [next in thread] 

List:       oss-security
Subject:    [oss-security] FW: An out-of-bound read/write in fsi driver
From:       "Luo Likang" <luolikang () nsfocus ! com>
Date:       2021-06-25 2:57:09
Message-ID: 001f01d7696d$ca7f4890$5f7dd9b0$ () nsfocus ! com
[Download RAW message or body]


 

Because of my mistake, I took a normal bug as a security bug and reported it
to linux-distros£¬linux-distros requested me notify oss-security since these
bugs were deemed to not be a security vulnerability, and no embargo was set.


 

Because of copy_ from_user has some check, so - 1 does not cause
cross-border access, and lots of check in fsi_check_access().

 

The following is the original of my report:

 

I found an oob read/write bug in function cfam_read/cfam_write of
drivers/fsi/fsi-core.c

It lack of the check of count and offset.

 

```

/* Create chardev for userspace access */

       cdev_init(&slave->cdev, &cfam_fops);

- - - -  - - - - - - - - - - - -- - - - - - - - - - - 

static const struct file_operations cfam_fops = {

       .owner           = THIS_MODULE,

       .open             = cfam_open,

       .llseek            = cfam_llseek,

       .read       = cfam_read,

       .write             = cfam_write,

};

```

In userspace, we can open this chardev can invoke read to use cfam_read.

 

cfam_read

```

static ssize_t cfam_read(struct file *filep, char __user *buf, size_t count,

                     loff_t *offset)

{

       struct fsi_slave *slave = filep->private_data;

       size_t total_len, read_len;

       loff_t off = *offset;

       ssize_t rc;

 

       if (off < 0)

              return -EINVAL;

 

       if (off > 0xffffffff || count > 0xffffffff || off + count >
0xffffffff)//[0]

              return -EINVAL;

 

       for (total_len = 0; total_len < count; total_len += read_len) {

              __be32 data;

 

              read_len = min_t(size_t, count, 4); //[1]

              read_len -= off & 0x3;          //[2]

 

              rc = fsi_slave_read(slave, off, &data, read_len);//[3]

              if (rc)

                     goto fail;

              rc = copy_to_user(buf + total_len, &data, read_len);//[4]

              ¡­¡­¡­

       }

       ¡­¡­..

       return count;

}

```

In [0]: This line will check the parameters to prevent integer overflow, but
it did not compare the size of count and offset, wo can pass count=2,
offset=3 to this function.

In [1]: read_len will be assigned a value of 2

In [2]: read_len-=offset&3  => read_len-=3 => read_len=-1.

In[3]/[4]: will OOB access

 

Cfam_write :

The reason for the vulnerability of cfam_write is the same as cfam_read.



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic