Sat Feb 22 00:24:15 2020 UTC ()
Avoid undefined behavior in get_modstat_info

t_modctl.c:114:16, member access within misaligned address 0x71bf5bcede84
for type 'struct modstat_t'

t_modctl.c:116:13, load of misaligned address 0x7e81bc3c9104 for type
'struct modstat_t' which requires 8 byte alignment


(kamil)
diff -r1.14 -r1.15 src/tests/modules/t_modctl.c

cvs diff -r1.14 -r1.15 src/tests/modules/t_modctl.c (expand / switch to unified diff)

--- src/tests/modules/t_modctl.c 2019/04/21 11:45:09 1.14
+++ src/tests/modules/t_modctl.c 2020/02/22 00:24:15 1.15
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: t_modctl.c,v 1.14 2019/04/21 11:45:09 maya Exp $ */ 1/* $NetBSD: t_modctl.c,v 1.15 2020/02/22 00:24:15 kamil Exp $ */
2/* 2/*
3 * Copyright (c) 2008 The NetBSD Foundation, Inc. 3 * Copyright (c) 2008 The NetBSD Foundation, Inc.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 19 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: t_modctl.c,v 1.14 2019/04/21 11:45:09 maya Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: t_modctl.c,v 1.15 2020/02/22 00:24:15 kamil Exp $");
31 31
32#include <sys/module.h> 32#include <sys/module.h>
33#include <sys/sysctl.h> 33#include <sys/sysctl.h>
34 34
35#include <assert.h> 35#include <assert.h>
36#include <errno.h> 36#include <errno.h>
37#include <stdarg.h> 37#include <stdarg.h>
38#include <stdbool.h> 38#include <stdbool.h>
39#include <stdio.h> 39#include <stdio.h>
40#include <stdlib.h> 40#include <stdlib.h>
41#include <string.h> 41#include <string.h>
42 42
43#include <prop/proplib.h> 43#include <prop/proplib.h>
@@ -77,53 +77,55 @@ check_permission(void) @@ -77,53 +77,55 @@ check_permission(void)
77 atf_tc_skip("Module loading administratively forbidden"); 77 atf_tc_skip("Module loading administratively forbidden");
78 ATF_REQUIRE_EQ_MSG(errno, 0, "unexpected error %d from " 78 ATF_REQUIRE_EQ_MSG(errno, 0, "unexpected error %d from "
79 "modctl(MODCTL_EXISTS, 0)", errno); 79 "modctl(MODCTL_EXISTS, 0)", errno);
80} 80}
81 81
82static bool 82static bool
83get_modstat_info(const char *name, modstat_t *msdest) 83get_modstat_info(const char *name, modstat_t *msdest)
84{ 84{
85 bool found; 85 bool found;
86 size_t len; 86 size_t len;
87 int count; 87 int count;
88 struct iovec iov; 88 struct iovec iov;
89 modstat_t *ms; 89 modstat_t *ms;
 90 modstat_t m;
90 91
91 check_permission(); 92 check_permission();
92 for (len = 8192; ;) { 93 for (len = 8192; ;) {
93 iov.iov_base = malloc(len); 94 iov.iov_base = malloc(len);
94 iov.iov_len = len; 95 iov.iov_len = len;
95 96
96 errno = 0; 97 errno = 0;
97 98
98 if (modctl(MODCTL_STAT, &iov) != 0) { 99 if (modctl(MODCTL_STAT, &iov) != 0) {
99 int err = errno; 100 int err = errno;
100 fprintf(stderr, "modctl(MODCTL_STAT) failed: %s\n", 101 fprintf(stderr, "modctl(MODCTL_STAT) failed: %s\n",
101 strerror(err)); 102 strerror(err));
102 atf_tc_fail("Failed to query module status"); 103 atf_tc_fail("Failed to query module status");
103 } 104 }
104 if (len >= iov.iov_len) 105 if (len >= iov.iov_len)
105 break; 106 break;
106 free(iov.iov_base); 107 free(iov.iov_base);
107 len = iov.iov_len; 108 len = iov.iov_len;
108 } 109 }
109 110
110 found = false; 111 found = false;
111 count = *(int *)iov.iov_base; 112 count = *(int *)iov.iov_base;
112 ms = (modstat_t *)((char *)iov.iov_base + sizeof(int)); 113 ms = (modstat_t *)((char *)iov.iov_base + sizeof(int));
113 while ( count ) { 114 while ( count ) {
114 if (strcmp(ms->ms_name, name) == 0) { 115 memcpy(&m, ms, sizeof(m));
 116 if (strcmp(m.ms_name, name) == 0) {
115 if (msdest != NULL) 117 if (msdest != NULL)
116 *msdest = *ms; 118 memcpy(msdest, &m, sizeof(*msdest));
117 found = true; 119 found = true;
118 break; 120 break;
119 } 121 }
120 ms++; 122 ms++;
121 count--; 123 count--;
122 } 124 }
123 125
124 free(iov.iov_base); 126 free(iov.iov_base);
125 127
126 return found; 128 return found;
127} 129}
128 130
129/* 131/*