]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
[media] saa7164: fix double fetch PCIe access condition
authorSteven Toth <stoth@kernellabs.com>
Tue, 6 Jun 2017 12:30:27 +0000 (09:30 -0300)
committerKirtikar Kashyap <kirtikar.kashyap@oracle.com>
Wed, 13 Sep 2017 15:57:53 +0000 (08:57 -0700)
Avoid a double fetch by reusing the values from the prior transfer.

Originally reported via https://bugzilla.kernel.org/show_bug.cgi?id=195559

Thanks to Pengfei Wang <wpengfeinudt@gmail.com> for reporting.

Signed-off-by: Steven Toth <stoth@kernellabs.com>
Reported-by: Pengfei Wang <wpengfeinudt@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
(cherry picked from commit 6fb05e0dd32e566facb96ea61a48c7488daa5ac3)

Orabug: 26093949
CVE: CVE-2017-8831

Signed-off-by: Kirtikar Kashyap <kirtikar.kashyap@oracle.com>
Reviewed-by: Jack Vogel <jack.vogel@oracle.com>
drivers/media/pci/saa7164/saa7164-bus.c

index 6c73f5b155f644980fd4e39e959d0554eab3dde3..1c779ea8b5ec28271f35d6273d060f4c406efc99 100644 (file)
@@ -393,11 +393,11 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
        msg_tmp.size = le16_to_cpu((__force __le16)msg_tmp.size);
        msg_tmp.command = le32_to_cpu((__force __le32)msg_tmp.command);
        msg_tmp.controlselector = le16_to_cpu((__force __le16)msg_tmp.controlselector);
+       memcpy(msg, &msg_tmp, sizeof(*msg));
 
        /* No need to update the read positions, because this was a peek */
        /* If the caller specifically want to peek, return */
        if (peekonly) {
-               memcpy(msg, &msg_tmp, sizeof(*msg));
                goto peekout;
        }
 
@@ -442,21 +442,15 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
                space_rem = bus->m_dwSizeGetRing - curr_grp;
 
                if (space_rem < sizeof(*msg)) {
-                       /* msg wraps around the ring */
-                       memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, space_rem);
-                       memcpy_fromio((u8 *)msg + space_rem, bus->m_pdwGetRing,
-                               sizeof(*msg) - space_rem);
                        if (buf)
                                memcpy_fromio(buf, bus->m_pdwGetRing + sizeof(*msg) -
                                        space_rem, buf_size);
 
                } else if (space_rem == sizeof(*msg)) {
-                       memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
                        if (buf)
                                memcpy_fromio(buf, bus->m_pdwGetRing, buf_size);
                } else {
                        /* Additional data wraps around the ring */
-                       memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
                        if (buf) {
                                memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp +
                                        sizeof(*msg), space_rem - sizeof(*msg));
@@ -469,15 +463,10 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
 
        } else {
                /* No wrapping */
-               memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
                if (buf)
                        memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg),
                                buf_size);
        }
-       /* Convert from little endian to CPU */
-       msg->size = le16_to_cpu((__force __le16)msg->size);
-       msg->command = le32_to_cpu((__force __le32)msg->command);
-       msg->controlselector = le16_to_cpu((__force __le16)msg->controlselector);
 
        /* Update the read positions, adjusting the ring */
        saa7164_writel(bus->m_dwGetReadPos, new_grp);