Bug Summary

File:build-scan/../src/libsystemd/sd-resolve/test-resolve.c
Warning:line 40, column 46
Access to field 'ai_canonname' results in a dereference of a null pointer (loaded from variable 'ai')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name test-resolve.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I test-resolve.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/libsystemd/sd-resolve/test-resolve.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2/***
3 Copyright © 2014 Daniel Buch
4***/
5
6#include <arpa/inet.h>
7#include <errno(*__errno_location ()).h>
8#include <netinet/in.h>
9#include <resolv.h>
10#include <stdio.h>
11#include <string.h>
12#include <sys/socket.h>
13
14#include "sd-resolve.h"
15
16#include "alloc-util.h"
17#include "macro.h"
18#include "socket-util.h"
19#include "string-util.h"
20
21#define TEST_TIMEOUT_USEC(20*((usec_t) 1000000ULL)) (20*USEC_PER_SEC((usec_t) 1000000ULL))
22
23static int getaddrinfo_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
24 const struct addrinfo *i;
25
26 assert_se(q)do { if ((__builtin_expect(!!(!(q)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("q"), "../src/libsystemd/sd-resolve/test-resolve.c"
, 26, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 'q' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
27
28 if (ret != 0) {
4
Assuming 'ret' is equal to 0
5
Taking false branch
29 log_error("getaddrinfo error: %s %i", gai_strerror(ret), ret)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-resolve/test-resolve.c", 29, __func__
, "getaddrinfo error: %s %i", gai_strerror(ret), ret) : -abs(
_e); })
;
30 return 0;
31 }
32
33 for (i = ai; i; i = i->ai_next) {
6
Assuming pointer value is null
7
Loop condition is false. Execution continues on line 40
34 _cleanup_free___attribute__((cleanup(freep))) char *addr = NULL((void*)0);
35
36 assert_se(sockaddr_pretty(i->ai_addr, i->ai_addrlen, false, true, &addr) == 0)do { if ((__builtin_expect(!!(!(sockaddr_pretty(i->ai_addr
, i->ai_addrlen, 0, 1, &addr) == 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("sockaddr_pretty(i->ai_addr, i->ai_addrlen, false, true, &addr) == 0"
), "../src/libsystemd/sd-resolve/test-resolve.c", 36, __PRETTY_FUNCTION__
); } while (0)
;
37 puts(addr);
38 }
39
40 printf("canonical name: %s\n", strna(ai->ai_canonname));
8
Access to field 'ai_canonname' results in a dereference of a null pointer (loaded from variable 'ai')
41
42 return 0;
43}
44
45static int getnameinfo_handler(sd_resolve_query *q, int ret, const char *host, const char *serv, void *userdata) {
46 assert_se(q)do { if ((__builtin_expect(!!(!(q)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("q"), "../src/libsystemd/sd-resolve/test-resolve.c"
, 46, __PRETTY_FUNCTION__); } while (0)
;
47
48 if (ret != 0) {
49 log_error("getnameinfo error: %s %i", gai_strerror(ret), ret)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-resolve/test-resolve.c", 49, __func__
, "getnameinfo error: %s %i", gai_strerror(ret), ret) : -abs(
_e); })
;
50 return 0;
51 }
52
53 printf("Host: %s — Serv: %s\n", strna(host), strna(serv));
54 return 0;
55}
56
57int main(int argc, char *argv[]) {
58 _cleanup_(sd_resolve_query_unrefp)__attribute__((cleanup(sd_resolve_query_unrefp))) sd_resolve_query *q1 = NULL((void*)0), *q2 = NULL((void*)0);
59 _cleanup_(sd_resolve_unrefp)__attribute__((cleanup(sd_resolve_unrefp))) sd_resolve *resolve = NULL((void*)0);
60 int r = 0;
61
62 struct addrinfo hints = {
63 .ai_family = PF_UNSPEC0,
64 .ai_socktype = SOCK_STREAMSOCK_STREAM,
65 .ai_flags = AI_CANONNAME0x0002
66 };
67
68 struct sockaddr_in sa = {
69 .sin_family = AF_INET2,
70 .sin_port = htons(80)
71 };
72
73 assert_se(sd_resolve_default(&resolve) >= 0)do { if ((__builtin_expect(!!(!(sd_resolve_default(&resolve
) >= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, (
"sd_resolve_default(&resolve) >= 0"), "../src/libsystemd/sd-resolve/test-resolve.c"
, 73, __PRETTY_FUNCTION__); } while (0)
;
74
75 /* Test a floating resolver query */
76 r = sd_resolve_getaddrinfo(resolve, NULL((void*)0), "redhat.com", "http", NULL((void*)0), getaddrinfo_handler, NULL((void*)0));
77 if (r < 0)
78 log_error_errno(r, "sd_resolve_getaddrinfo(): %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-resolve/test-resolve.c", 78, __func__
, "sd_resolve_getaddrinfo(): %m") : -abs(_e); })
;
79
80 /* Make a name -> address query */
81 r = sd_resolve_getaddrinfo(resolve, &q1, argc >= 2 ? argv[1] : "www.heise.de", NULL((void*)0), &hints, getaddrinfo_handler, NULL((void*)0));
82 if (r < 0)
83 log_error_errno(r, "sd_resolve_getaddrinfo(): %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-resolve/test-resolve.c", 83, __func__
, "sd_resolve_getaddrinfo(): %m") : -abs(_e); })
;
84
85 /* Make an address -> name query */
86 sa.sin_addr.s_addr = inet_addr(argc >= 3 ? argv[2] : "193.99.144.71");
87 r = sd_resolve_getnameinfo(resolve, &q2, (struct sockaddr*) &sa, sizeof(sa), 0, SD_RESOLVE_GET_BOTH, getnameinfo_handler, NULL((void*)0));
88 if (r < 0)
89 log_error_errno(r, "sd_resolve_getnameinfo(): %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-resolve/test-resolve.c", 89, __func__
, "sd_resolve_getnameinfo(): %m") : -abs(_e); })
;
90
91 /* Wait until all queries are completed */
92 for (;;) {
93 r = sd_resolve_wait(resolve, TEST_TIMEOUT_USEC(20*((usec_t) 1000000ULL)));
94 if (r == 0)
95 break;
96 if (r == -ETIMEDOUT110) {
97 /* Let's catch time-outs here, so that we can run safely in a CI that has no reliable DNS. Note
98 * that we invoke exit() directly here, as the stuck NSS call will not allow us to exit
99 * cleanly. */
100
101 log_notice_errno(r, "sd_resolve_wait() timed out, but that's OK")({ int _level = ((5)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-resolve/test-resolve.c", 101, __func__
, "sd_resolve_wait() timed out, but that's OK") : -abs(_e); }
)
;
102 exit(EXIT_SUCCESS0);
103 }
104 if (r < 0) {
105 log_error_errno(r, "sd_resolve_wait(): %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-resolve/test-resolve.c", 105, __func__
, "sd_resolve_wait(): %m") : -abs(_e); })
;
106 assert_not_reached("sd_resolve_wait() failed")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"sd_resolve_wait() failed"), "../src/libsystemd/sd-resolve/test-resolve.c"
, 106, __PRETTY_FUNCTION__); } while (0)
;
107 }
108 }
109
110 return 0;
111}