Bug Summary

File:build-scan/../src/libsystemd/sd-netlink/netlink-message.c
Warning:line 75, column 25
Potential leak of memory pointed to by 'm'

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 netlink-message.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 pic -pic-level 2 -fhalf-no-semantic-interposition -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 src/libsystemd/libsystemd_static.a.p -I src/libsystemd -I ../src/libsystemd -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 -I . -I .. -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 default -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-netlink/netlink-message.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <netinet/in.h>
4#include <stdbool.h>
5#include <unistd.h>
6
7#include "sd-netlink.h"
8
9#include "alloc-util.h"
10#include "format-util.h"
11#include "missing.h"
12#include "netlink-internal.h"
13#include "netlink-types.h"
14#include "netlink-util.h"
15#include "refcnt.h"
16#include "socket-util.h"
17#include "util.h"
18
19#define GET_CONTAINER(m, i)((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(
m)->hdr + (m)->containers[i].offset) : ((void*)0))
((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL((void*)0))
20#define PUSH_CONTAINER(m, new)(m)->container_offsets[(m)->n_containers++] = (uint8_t*
)(new) - (uint8_t*)(m)->hdr;
(m)->container_offsets[(m)->n_containers++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
21
22#define RTA_TYPE(rta)((rta)->rta_type & ~((1 << 15) | (1 << 14)
))
((rta)->rta_type & NLA_TYPE_MASK~((1 << 15) | (1 << 14)))
23#define RTA_FLAGS(rta)((rta)->rta_type & ~~((1 << 15) | (1 << 14
)))
((rta)->rta_type & ~NLA_TYPE_MASK~((1 << 15) | (1 << 14)))
24
25int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) {
26 sd_netlink_message *m;
27
28 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 28, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
10
'?' condition is true
11
Taking false branch
12
Loop condition is false. Exiting loop
29
30 /* Note that 'rtnl' is currently unused, if we start using it internally
31 we must take care to avoid problems due to mutual references between
32 buses and their queued messages. See sd-bus.
33 */
34
35 m = new0(sd_netlink_message, 1)((sd_netlink_message*) calloc((1), sizeof(sd_netlink_message)
))
;
13
Memory is allocated
36 if (!m)
14
Assuming 'm' is non-null
15
Taking false branch
37 return -ENOMEM12;
38
39 m->n_ref = REFCNT_INIT((RefCount) { ._value = 1 });
40 m->protocol = rtnl->protocol;
41 m->sealed = false0;
42
43 *ret = m;
44
45 return 0;
46}
47
48int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) {
49 _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *m = NULL((void*)0);
50 const NLType *nl_type;
51 const NLTypeSystem *type_system_root;
52 size_t size;
53 int r;
54
55 assert_return(rtnl, -EINVAL)do { if (!(((__builtin_expect(!!(rtnl),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rtnl"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 55, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1
Assuming 'rtnl' is non-null
2
'?' condition is true
3
Taking false branch
4
Loop condition is false. Exiting loop
56
57 type_system_root = type_system_get_root(rtnl->protocol);
58
59 r = type_system_get_type(type_system_root, &nl_type, type);
60 if (r < 0)
5
Assuming 'r' is >= 0
6
Taking false branch
61 return r;
62
63 if (type_get_type(nl_type) != NETLINK_TYPE_NESTED)
7
Assuming the condition is false
8
Taking false branch
64 return -EINVAL22;
65
66 r = message_new_empty(rtnl, &m);
9
Calling 'message_new_empty'
16
Returned allocated memory via 2nd parameter
67 if (r
16.1
'r' is >= 0
< 0)
17
Taking false branch
68 return r;
69
70 size = NLMSG_SPACE(type_get_size(nl_type))( ((((type_get_size(nl_type)) + ((int) ( ((sizeof(struct nlmsghdr
))+4U -1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )
;
71
72 assert(size >= sizeof(struct nlmsghdr))do { if ((__builtin_expect(!!(!(size >= sizeof(struct nlmsghdr
))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("size >= sizeof(struct nlmsghdr)"
), "../src/libsystemd/sd-netlink/netlink-message.c", 72, __PRETTY_FUNCTION__
); } while (0)
;
18
Assuming the condition is true
19
Taking false branch
20
Loop condition is false. Exiting loop
73 m->hdr = malloc0(size)(calloc(1, (size)));
74 if (!m->hdr)
21
Assuming field 'hdr' is null
22
Taking true branch
75 return -ENOMEM12;
23
Potential leak of memory pointed to by 'm'
76
77 m->hdr->nlmsg_flags = NLM_F_REQUEST0x01 | NLM_F_ACK0x04;
78
79 type_get_type_system(nl_type, &m->containers[0].type_system);
80 m->hdr->nlmsg_len = size;
81 m->hdr->nlmsg_type = type;
82
83 *ret = TAKE_PTR(m)({ typeof(m) _ptr_ = (m); (m) = ((void*)0); _ptr_; });
84
85 return 0;
86}
87
88int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) {
89 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 89, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
90 assert_return(m->hdr, -EINVAL)do { if (!(((__builtin_expect(!!(m->hdr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m->hdr"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 90, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
91
92 assert_return(IN_SET(m->hdr->nlmsg_type, RTM_GETLINK, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH, RTM_GETRULE, RTM_GETADDRLABEL), -EINVAL)do { if (!(((__builtin_expect(!!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){RTM_GETLINK, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH
, RTM_GETRULE, RTM_GETADDRLABEL})/sizeof(int)]; switch(m->
hdr->nlmsg_type) { case RTM_GETLINK: case RTM_GETADDR: case
RTM_GETROUTE: case RTM_GETNEIGH: case RTM_GETRULE: case RTM_GETADDRLABEL
: _found = 1; break; default: break; } _found; })),1))) ? (1)
: (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("IN_SET(m->hdr->nlmsg_type, RTM_GETLINK, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH, RTM_GETRULE, RTM_GETADDRLABEL)"
), "../src/libsystemd/sd-netlink/netlink-message.c", 92, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
93
94 SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump)(m->hdr->nlmsg_flags) = (dump) ? ((m->hdr->nlmsg_flags
) | ((0x100|0x200))) : ((m->hdr->nlmsg_flags) & ~((
0x100|0x200)))
;
95
96 return 0;
97}
98
99sd_netlink_message *sd_netlink_message_ref(sd_netlink_message *m) {
100 if (!m)
101 return NULL((void*)0);
102
103 assert_se(REFCNT_INC(m->n_ref) >= 2)do { if ((__builtin_expect(!!(!((__sync_add_and_fetch(&(m
->n_ref)._value, 1)) >= 2)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("REFCNT_INC(m->n_ref) >= 2"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 103, __PRETTY_FUNCTION__); } while (0)
;
104 return m;
105}
106
107sd_netlink_message *sd_netlink_message_unref(sd_netlink_message *m) {
108 sd_netlink_message *t;
109
110 while (m && REFCNT_DEC(m->n_ref)(__sync_sub_and_fetch(&(m->n_ref)._value, 1)) == 0) {
111 unsigned i;
112
113 free(m->hdr);
114
115 for (i = 0; i <= m->n_containers; i++)
116 free(m->containers[i].attributes);
117
118 t = m;
119 m = m->next;
120 free(t);
121 }
122
123 return NULL((void*)0);
124}
125
126int sd_netlink_message_get_type(sd_netlink_message *m, uint16_t *type) {
127 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 127, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
128 assert_return(type, -EINVAL)do { if (!(((__builtin_expect(!!(type),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("type"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 128, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
129
130 *type = m->hdr->nlmsg_type;
131
132 return 0;
133}
134
135int sd_netlink_message_set_flags(sd_netlink_message *m, uint16_t flags) {
136 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 136, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
137 assert_return(flags, -EINVAL)do { if (!(((__builtin_expect(!!(flags),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("flags"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 137, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
138
139 m->hdr->nlmsg_flags = flags;
140
141 return 0;
142}
143
144int sd_netlink_message_is_broadcast(sd_netlink_message *m) {
145 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 145, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
146
147 return m->broadcast;
148}
149
150/* If successful the updated message will be correctly aligned, if
151 unsuccessful the old message is untouched. */
152static int add_rtattr(sd_netlink_message *m, unsigned short type, const void *data, size_t data_length) {
153 uint32_t rta_length;
154 size_t message_length, padding_length;
155 struct nlmsghdr *new_hdr;
156 struct rtattr *rta;
157 char *padding;
158 unsigned i;
159 int offset;
160
161 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 161, __PRETTY_FUNCTION__); } while (0)
;
162 assert(m->hdr)do { if ((__builtin_expect(!!(!(m->hdr)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m->hdr"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 162, __PRETTY_FUNCTION__); } while (0)
;
163 assert(!m->sealed)do { if ((__builtin_expect(!!(!(!m->sealed)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!m->sealed"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 163, __PRETTY_FUNCTION__); } while (0)
;
164 assert(NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len)do { if ((__builtin_expect(!!(!(( ((m->hdr->nlmsg_len)+
4U -1) & ~(4U -1) ) == m->hdr->nlmsg_len)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len"
), "../src/libsystemd/sd-netlink/netlink-message.c", 164, __PRETTY_FUNCTION__
); } while (0)
;
165 assert(!data || data_length)do { if ((__builtin_expect(!!(!(!data || data_length)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!data || data_length"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 165, __PRETTY_FUNCTION__); } while (0)
;
166
167 /* get offset of the new attribute */
168 offset = m->hdr->nlmsg_len;
169
170 /* get the size of the new rta attribute (with padding at the end) */
171 rta_length = RTA_LENGTH(data_length)(( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (data_length
))
;
172
173 /* get the new message size (with padding at the end) */
174 message_length = offset + RTA_ALIGN(rta_length)( ((rta_length)+4U -1) & ~(4U -1) );
175
176 /* buffer should be smaller than both one page or 8K to be accepted by the kernel */
177 if (message_length > MIN(page_size(), 8192UL)__extension__ ({ const typeof((page_size())) __unique_prefix_A2
= ((page_size())); const typeof((8192UL)) __unique_prefix_B3
= ((8192UL)); __unique_prefix_A2 < __unique_prefix_B3 ? __unique_prefix_A2
: __unique_prefix_B3; })
)
178 return -ENOBUFS105;
179
180 /* realloc to fit the new attribute */
181 new_hdr = realloc(m->hdr, message_length);
182 if (!new_hdr)
183 return -ENOMEM12;
184 m->hdr = new_hdr;
185
186 /* get pointer to the attribute we are about to add */
187 rta = (struct rtattr *) ((uint8_t *) m->hdr + offset);
188
189 /* if we are inside containers, extend them */
190 for (i = 0; i < m->n_containers; i++)
191 GET_CONTAINER(m, i)((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(
m)->hdr + (m)->containers[i].offset) : ((void*)0))
->rta_len += message_length - offset;
192
193 /* fill in the attribute */
194 rta->rta_type = type;
195 rta->rta_len = rta_length;
196 if (data)
197 /* we don't deal with the case where the user lies about the type
198 * and gives us too little data (so don't do that)
199 */
200 padding = mempcpy(RTA_DATA(rta)((void*)(((char*)(rta)) + (( ((sizeof(struct rtattr))+4U -1) &
~(4U -1) ) + (0))))
, data, data_length);
201
202 else
203 /* if no data was passed, make sure we still initialize the padding
204 note that we can have data_length > 0 (used by some containers) */
205 padding = RTA_DATA(rta)((void*)(((char*)(rta)) + (( ((sizeof(struct rtattr))+4U -1) &
~(4U -1) ) + (0))))
;
206
207 /* make sure also the padding at the end of the message is initialized */
208 padding_length = (uint8_t*)m->hdr + message_length - (uint8_t*)padding;
209 memzero(padding, padding_length)({ size_t _l_ = (padding_length); void *_x_ = (padding); _l_ ==
0 ? _x_ : memset(_x_, 0, _l_); })
;
210
211 /* update message size */
212 m->hdr->nlmsg_len = message_length;
213
214 return offset;
215}
216
217static int message_attribute_has_type(sd_netlink_message *m, size_t *out_size, uint16_t attribute_type, uint16_t data_type) {
218 const NLType *type;
219 int r;
220
221 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 221, __PRETTY_FUNCTION__); } while (0)
;
222
223 r = type_system_get_type(m->containers[m->n_containers].type_system, &type, attribute_type);
224 if (r < 0)
225 return r;
226
227 if (type_get_type(type) != data_type)
228 return -EINVAL22;
229
230 if (out_size)
231 *out_size = type_get_size(type);
232 return 0;
233}
234
235int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data) {
236 size_t length, size;
237 int r;
238
239 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 239, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
240 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 240, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
241 assert_return(data, -EINVAL)do { if (!(((__builtin_expect(!!(data),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 241, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
242
243 r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_STRING);
244 if (r < 0)
245 return r;
246
247 if (size) {
248 length = strnlen(data, size+1);
249 if (length > size)
250 return -EINVAL22;
251 } else
252 length = strlen(data);
253
254 r = add_rtattr(m, type, data, length + 1);
255 if (r < 0)
256 return r;
257
258 return 0;
259}
260
261int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type) {
262 size_t size;
263 int r;
264
265 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 265, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
266 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 266, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
267
268 r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_FLAG);
269 if (r < 0)
270 return r;
271
272 r = add_rtattr(m, type, NULL((void*)0), 0);
273 if (r < 0)
274 return r;
275
276 return 0;
277}
278
279int sd_netlink_message_append_u8(sd_netlink_message *m, unsigned short type, uint8_t data) {
280 int r;
281
282 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 282, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
283 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 283, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
284
285 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_U8);
286 if (r < 0)
287 return r;
288
289 r = add_rtattr(m, type, &data, sizeof(uint8_t));
290 if (r < 0)
291 return r;
292
293 return 0;
294}
295
296int sd_netlink_message_append_u16(sd_netlink_message *m, unsigned short type, uint16_t data) {
297 int r;
298
299 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 299, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
300 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 300, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
301
302 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_U16);
303 if (r < 0)
304 return r;
305
306 r = add_rtattr(m, type, &data, sizeof(uint16_t));
307 if (r < 0)
308 return r;
309
310 return 0;
311}
312
313int sd_netlink_message_append_u32(sd_netlink_message *m, unsigned short type, uint32_t data) {
314 int r;
315
316 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 316, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
317 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 317, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
318
319 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_U32);
320 if (r < 0)
321 return r;
322
323 r = add_rtattr(m, type, &data, sizeof(uint32_t));
324 if (r < 0)
325 return r;
326
327 return 0;
328}
329
330int sd_netlink_message_append_data(sd_netlink_message *m, unsigned short type, const void *data, size_t len) {
331 int r;
332
333 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 333, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
334 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 334, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
335
336 r = add_rtattr(m, type, data, len);
337 if (r < 0)
338 return r;
339
340 return 0;
341}
342
343int sd_netlink_message_append_in_addr(sd_netlink_message *m, unsigned short type, const struct in_addr *data) {
344 int r;
345
346 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 346, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
347 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 347, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
348 assert_return(data, -EINVAL)do { if (!(((__builtin_expect(!!(data),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 348, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
349
350 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_IN_ADDR);
351 if (r < 0)
352 return r;
353
354 r = add_rtattr(m, type, data, sizeof(struct in_addr));
355 if (r < 0)
356 return r;
357
358 return 0;
359}
360
361int sd_netlink_message_append_in6_addr(sd_netlink_message *m, unsigned short type, const struct in6_addr *data) {
362 int r;
363
364 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 364, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
365 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 365, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
366 assert_return(data, -EINVAL)do { if (!(((__builtin_expect(!!(data),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 366, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
367
368 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_IN_ADDR);
369 if (r < 0)
370 return r;
371
372 r = add_rtattr(m, type, data, sizeof(struct in6_addr));
373 if (r < 0)
374 return r;
375
376 return 0;
377}
378
379int sd_netlink_message_append_ether_addr(sd_netlink_message *m, unsigned short type, const struct ether_addr *data) {
380 int r;
381
382 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 382, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
383 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 383, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
384 assert_return(data, -EINVAL)do { if (!(((__builtin_expect(!!(data),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 384, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
385
386 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_ETHER_ADDR);
387 if (r < 0)
388 return r;
389
390 r = add_rtattr(m, type, data, ETH_ALEN6);
391 if (r < 0)
392 return r;
393
394 return 0;
395}
396
397int sd_netlink_message_append_cache_info(sd_netlink_message *m, unsigned short type, const struct ifa_cacheinfo *info) {
398 int r;
399
400 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 400, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
401 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 401, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
402 assert_return(info, -EINVAL)do { if (!(((__builtin_expect(!!(info),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("info"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 402, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
403
404 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_CACHE_INFO);
405 if (r < 0)
406 return r;
407
408 r = add_rtattr(m, type, info, sizeof(struct ifa_cacheinfo));
409 if (r < 0)
410 return r;
411
412 return 0;
413}
414
415int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type) {
416 size_t size;
417 int r;
418
419 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 419, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
420 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 420, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
421 assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE)do { if (!(((__builtin_expect(!!(m->n_containers < 32),
1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("m->n_containers < RTNL_CONTAINER_DEPTH"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 421, __PRETTY_FUNCTION__), 0))) return (-34); } while (0)
;
422
423 r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_NESTED);
424 if (r < 0) {
425 const NLTypeSystemUnion *type_system_union;
426 int family;
427
428 r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_UNION);
429 if (r < 0)
430 return r;
431
432 r = sd_rtnl_message_get_family(m, &family);
433 if (r < 0)
434 return r;
435
436 r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type);
437 if (r < 0)
438 return r;
439
440 r = type_system_union_protocol_get_type_system(type_system_union,
441 &m->containers[m->n_containers + 1].type_system,
442 family);
443 if (r < 0)
444 return r;
445 } else {
446 r = type_system_get_type_system(m->containers[m->n_containers].type_system,
447 &m->containers[m->n_containers + 1].type_system,
448 type);
449 if (r < 0)
450 return r;
451 }
452
453 r = add_rtattr(m, type | NLA_F_NESTED(1 << 15), NULL((void*)0), size);
454 if (r < 0)
455 return r;
456
457 m->containers[m->n_containers++].offset = r;
458
459 return 0;
460}
461
462int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned short type, const char *key) {
463 const NLTypeSystemUnion *type_system_union;
464 int r;
465
466 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 466, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
467 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 467, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
468
469 r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type);
470 if (r < 0)
471 return r;
472
473 r = type_system_union_get_type_system(type_system_union,
474 &m->containers[m->n_containers + 1].type_system,
475 key);
476 if (r < 0)
477 return r;
478
479 r = sd_netlink_message_append_string(m, type_system_union->match, key);
480 if (r < 0)
481 return r;
482
483 /* do we ever need non-null size */
484 r = add_rtattr(m, type | NLA_F_NESTED(1 << 15), NULL((void*)0), 0);
485 if (r < 0)
486 return r;
487
488 m->containers[m->n_containers++].offset = r;
489
490 return 0;
491}
492
493int sd_netlink_message_close_container(sd_netlink_message *m) {
494 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 494, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
495 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 495, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
496 assert_return(m->n_containers > 0, -EINVAL)do { if (!(((__builtin_expect(!!(m->n_containers > 0),1
))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("m->n_containers > 0"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 496, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
497
498 m->containers[m->n_containers].type_system = NULL((void*)0);
499 m->containers[m->n_containers].offset = 0;
500 m->n_containers--;
501
502 return 0;
503}
504
505int sd_netlink_message_open_array(sd_netlink_message *m, uint16_t type) {
506 int r;
507
508 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 508, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
509 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 509, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
510 assert_return(m->n_containers > 0, -EINVAL)do { if (!(((__builtin_expect(!!(m->n_containers > 0),1
))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("m->n_containers > 0"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 510, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
511
512 r = add_rtattr(m, type | NLA_F_NESTED(1 << 15), NULL((void*)0), 0);
513 if (r < 0)
514 return r;
515
516 m->containers[m->n_containers].offset = r;
517 m->n_containers++;
518 m->containers[m->n_containers].type_system = m->containers[m->n_containers - 1].type_system;
519
520 return 0;
521}
522
523int sd_netlink_message_cancel_array(sd_netlink_message *m) {
524 unsigned i;
525 uint32_t rta_len;
526
527 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 527, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
528 assert_return(!m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(!m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 528, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
529 assert_return(m->n_containers > 1, -EINVAL)do { if (!(((__builtin_expect(!!(m->n_containers > 1),1
))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("m->n_containers > 1"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 529, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
530
531 rta_len = GET_CONTAINER(m, (m->n_containers - 1))(((m->n_containers - 1)) < (m)->n_containers ? (struct
rtattr*)((uint8_t*)(m)->hdr + (m)->containers[(m->n_containers
- 1)].offset) : ((void*)0))
->rta_len;
532
533 for (i = 0; i < m->n_containers; i++)
534 GET_CONTAINER(m, i)((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(
m)->hdr + (m)->containers[i].offset) : ((void*)0))
->rta_len -= rta_len;
535
536 m->hdr->nlmsg_len -= rta_len;
537
538 m->n_containers--;
539 m->containers[m->n_containers].type_system = NULL((void*)0);
540
541 return 0;
542}
543
544static int netlink_message_read_internal(sd_netlink_message *m, unsigned short type, void **data, bool_Bool *net_byteorder) {
545 struct netlink_attribute *attribute;
546 struct rtattr *rta;
547
548 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 548, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
549 assert_return(m->sealed, -EPERM)do { if (!(((__builtin_expect(!!(m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 549, __PRETTY_FUNCTION__
), 0))) return (-1); } while (0)
;
550 assert_return(data, -EINVAL)do { if (!(((__builtin_expect(!!(data),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 550, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
551
552 assert(m->n_containers < RTNL_CONTAINER_DEPTH)do { if ((__builtin_expect(!!(!(m->n_containers < 32)),
0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("m->n_containers < RTNL_CONTAINER_DEPTH"
), "../src/libsystemd/sd-netlink/netlink-message.c", 552, __PRETTY_FUNCTION__
); } while (0)
;
553 assert(m->containers[m->n_containers].attributes)do { if ((__builtin_expect(!!(!(m->containers[m->n_containers
].attributes)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("m->containers[m->n_containers].attributes"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 553, __PRETTY_FUNCTION__); } while (0)
;
554 assert(type < m->containers[m->n_containers].n_attributes)do { if ((__builtin_expect(!!(!(type < m->containers[m->
n_containers].n_attributes)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("type < m->containers[m->n_containers].n_attributes"
), "../src/libsystemd/sd-netlink/netlink-message.c", 554, __PRETTY_FUNCTION__
); } while (0)
;
555
556 attribute = &m->containers[m->n_containers].attributes[type];
557
558 if (attribute->offset == 0)
559 return -ENODATA61;
560
561 rta = (struct rtattr*)((uint8_t *) m->hdr + attribute->offset);
562
563 *data = RTA_DATA(rta)((void*)(((char*)(rta)) + (( ((sizeof(struct rtattr))+4U -1) &
~(4U -1) ) + (0))))
;
564
565 if (net_byteorder)
566 *net_byteorder = attribute->net_byteorder;
567
568 return RTA_PAYLOAD(rta)((int)((rta)->rta_len) - (( ((sizeof(struct rtattr))+4U -1
) & ~(4U -1) ) + (0)))
;
569}
570
571int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, const char **data) {
572 int r;
573 void *attr_data;
574
575 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 575, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
576
577 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_STRING);
578 if (r < 0)
579 return r;
580
581 r = netlink_message_read_internal(m, type, &attr_data, NULL((void*)0));
582 if (r < 0)
583 return r;
584 else if (strnlen(attr_data, r) >= (size_t) r)
585 return -EIO5;
586
587 if (data)
588 *data = (const char *) attr_data;
589
590 return 0;
591}
592
593int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8_t *data) {
594 int r;
595 void *attr_data;
596
597 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 597, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
598
599 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_U8);
600 if (r < 0)
601 return r;
602
603 r = netlink_message_read_internal(m, type, &attr_data, NULL((void*)0));
604 if (r < 0)
605 return r;
606 else if ((size_t) r < sizeof(uint8_t))
607 return -EIO5;
608
609 if (data)
610 *data = *(uint8_t *) attr_data;
611
612 return 0;
613}
614
615int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint16_t *data) {
616 void *attr_data;
617 bool_Bool net_byteorder;
618 int r;
619
620 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 620, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
621
622 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_U16);
623 if (r < 0)
624 return r;
625
626 r = netlink_message_read_internal(m, type, &attr_data, &net_byteorder);
627 if (r < 0)
628 return r;
629 else if ((size_t) r < sizeof(uint16_t))
630 return -EIO5;
631
632 if (data) {
633 if (net_byteorder)
634 *data = be16toh(*(uint16_t *) attr_data)__bswap_16 (*(uint16_t *) attr_data);
635 else
636 *data = *(uint16_t *) attr_data;
637 }
638
639 return 0;
640}
641
642int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint32_t *data) {
643 void *attr_data;
644 bool_Bool net_byteorder;
645 int r;
646
647 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 647, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
648
649 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_U32);
650 if (r < 0)
651 return r;
652
653 r = netlink_message_read_internal(m, type, &attr_data, &net_byteorder);
654 if (r < 0)
655 return r;
656 else if ((size_t)r < sizeof(uint32_t))
657 return -EIO5;
658
659 if (data) {
660 if (net_byteorder)
661 *data = be32toh(*(uint32_t *) attr_data)__bswap_32 (*(uint32_t *) attr_data);
662 else
663 *data = *(uint32_t *) attr_data;
664 }
665
666 return 0;
667}
668
669int sd_netlink_message_read_ether_addr(sd_netlink_message *m, unsigned short type, struct ether_addr *data) {
670 int r;
671 void *attr_data;
672
673 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 673, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
674
675 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_ETHER_ADDR);
676 if (r < 0)
677 return r;
678
679 r = netlink_message_read_internal(m, type, &attr_data, NULL((void*)0));
680 if (r < 0)
681 return r;
682 else if ((size_t)r < sizeof(struct ether_addr))
683 return -EIO5;
684
685 if (data)
686 memcpy(data, attr_data, sizeof(struct ether_addr));
687
688 return 0;
689}
690
691int sd_netlink_message_read_cache_info(sd_netlink_message *m, unsigned short type, struct ifa_cacheinfo *info) {
692 int r;
693 void *attr_data;
694
695 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 695, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
696
697 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_CACHE_INFO);
698 if (r < 0)
699 return r;
700
701 r = netlink_message_read_internal(m, type, &attr_data, NULL((void*)0));
702 if (r < 0)
703 return r;
704 else if ((size_t)r < sizeof(struct ifa_cacheinfo))
705 return -EIO5;
706
707 if (info)
708 memcpy(info, attr_data, sizeof(struct ifa_cacheinfo));
709
710 return 0;
711}
712
713int sd_netlink_message_read_in_addr(sd_netlink_message *m, unsigned short type, struct in_addr *data) {
714 int r;
715 void *attr_data;
716
717 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 717, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
718
719 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_IN_ADDR);
720 if (r < 0)
721 return r;
722
723 r = netlink_message_read_internal(m, type, &attr_data, NULL((void*)0));
724 if (r < 0)
725 return r;
726 else if ((size_t)r < sizeof(struct in_addr))
727 return -EIO5;
728
729 if (data)
730 memcpy(data, attr_data, sizeof(struct in_addr));
731
732 return 0;
733}
734
735int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, struct in6_addr *data) {
736 int r;
737 void *attr_data;
738
739 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 739, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
740
741 r = message_attribute_has_type(m, NULL((void*)0), type, NETLINK_TYPE_IN_ADDR);
742 if (r < 0)
743 return r;
744
745 r = netlink_message_read_internal(m, type, &attr_data, NULL((void*)0));
746 if (r < 0)
747 return r;
748 else if ((size_t)r < sizeof(struct in6_addr))
749 return -EIO5;
750
751 if (data)
752 memcpy(data, attr_data, sizeof(struct in6_addr));
753
754 return 0;
755}
756
757static int netlink_container_parse(sd_netlink_message *m,
758 struct netlink_container *container,
759 int count,
760 struct rtattr *rta,
761 unsigned int rt_len) {
762 _cleanup_free___attribute__((cleanup(freep))) struct netlink_attribute *attributes = NULL((void*)0);
763
764 attributes = new0(struct netlink_attribute, count)((struct netlink_attribute*) calloc((count), sizeof(struct netlink_attribute
)))
;
765 if (!attributes)
766 return -ENOMEM12;
767
768 for (; RTA_OK(rta, rt_len)((rt_len) >= (int)sizeof(struct rtattr) && (rta)->
rta_len >= sizeof(struct rtattr) && (rta)->rta_len
<= (rt_len))
; rta = RTA_NEXT(rta, rt_len)((rt_len) -= ( (((rta)->rta_len)+4U -1) & ~(4U -1) ), (
struct rtattr*)(((char*)(rta)) + ( (((rta)->rta_len)+4U -1
) & ~(4U -1) )))
) {
769 unsigned short type;
770
771 type = RTA_TYPE(rta)((rta)->rta_type & ~((1 << 15) | (1 << 14)
))
;
772
773 /* if the kernel is newer than the headers we used
774 when building, we ignore out-of-range attributes */
775 if (type >= count)
776 continue;
777
778 if (attributes[type].offset != 0)
779 log_debug("rtnl: message parse - overwriting repeated attribute")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-netlink/netlink-message.c", 779, __func__
, "rtnl: message parse - overwriting repeated attribute") : -
abs(_e); })
;
780
781 attributes[type].offset = (uint8_t *) rta - (uint8_t *) m->hdr;
782 attributes[type].nested = RTA_FLAGS(rta)((rta)->rta_type & ~~((1 << 15) | (1 << 14
)))
& NLA_F_NESTED(1 << 15);
783 attributes[type].net_byteorder = RTA_FLAGS(rta)((rta)->rta_type & ~~((1 << 15) | (1 << 14
)))
& NLA_F_NET_BYTEORDER(1 << 14);
784 }
785
786 container->attributes = TAKE_PTR(attributes)({ typeof(attributes) _ptr_ = (attributes); (attributes) = ((
void*)0); _ptr_; })
;
787 container->n_attributes = count;
788
789 return 0;
790}
791
792int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short type_id) {
793 const NLType *nl_type;
794 const NLTypeSystem *type_system;
795 void *container;
796 uint16_t type;
797 size_t size;
798 int r;
799
800 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 800, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
801 assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL)do { if (!(((__builtin_expect(!!(m->n_containers < 32),
1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("m->n_containers < RTNL_CONTAINER_DEPTH"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 801, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
802
803 r = type_system_get_type(m->containers[m->n_containers].type_system,
804 &nl_type,
805 type_id);
806 if (r < 0)
807 return r;
808
809 type = type_get_type(nl_type);
810
811 if (type == NETLINK_TYPE_NESTED) {
812 r = type_system_get_type_system(m->containers[m->n_containers].type_system,
813 &type_system,
814 type_id);
815 if (r < 0)
816 return r;
817 } else if (type == NETLINK_TYPE_UNION) {
818 const NLTypeSystemUnion *type_system_union;
819
820 r = type_system_get_type_system_union(m->containers[m->n_containers].type_system,
821 &type_system_union,
822 type_id);
823 if (r < 0)
824 return r;
825
826 switch (type_system_union->match_type) {
827 case NL_MATCH_SIBLING:
828 {
829 const char *key;
830
831 r = sd_netlink_message_read_string(m, type_system_union->match, &key);
832 if (r < 0)
833 return r;
834
835 r = type_system_union_get_type_system(type_system_union,
836 &type_system,
837 key);
838 if (r < 0)
839 return r;
840
841 break;
842 }
843 case NL_MATCH_PROTOCOL:
844 {
845 int family;
846
847 r = sd_rtnl_message_get_family(m, &family);
848 if (r < 0)
849 return r;
850
851 r = type_system_union_protocol_get_type_system(type_system_union,
852 &type_system,
853 family);
854 if (r < 0)
855 return r;
856
857 break;
858 }
859 default:
860 assert_not_reached("sd-netlink: invalid type system union type")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"sd-netlink: invalid type system union type"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 860, __PRETTY_FUNCTION__); } while (0)
;
861 }
862 } else
863 return -EINVAL22;
864
865 r = netlink_message_read_internal(m, type_id, &container, NULL((void*)0));
866 if (r < 0)
867 return r;
868 else
869 size = (size_t)r;
870
871 m->n_containers++;
872
873 r = netlink_container_parse(m,
874 &m->containers[m->n_containers],
875 type_system_get_count(type_system),
876 container,
877 size);
878 if (r < 0) {
879 m->n_containers--;
880 return r;
881 }
882
883 m->containers[m->n_containers].type_system = type_system;
884
885 return 0;
886}
887
888int sd_netlink_message_exit_container(sd_netlink_message *m) {
889 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 889, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
890 assert_return(m->sealed, -EINVAL)do { if (!(((__builtin_expect(!!(m->sealed),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("m->sealed"
), "../src/libsystemd/sd-netlink/netlink-message.c", 890, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
891 assert_return(m->n_containers > 0, -EINVAL)do { if (!(((__builtin_expect(!!(m->n_containers > 0),1
))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("m->n_containers > 0"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 891, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
892
893 m->containers[m->n_containers].attributes = mfree(m->containers[m->n_containers].attributes);
894 m->containers[m->n_containers].type_system = NULL((void*)0);
895
896 m->n_containers--;
897
898 return 0;
899}
900
901uint32_t rtnl_message_get_serial(sd_netlink_message *m) {
902 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 902, __PRETTY_FUNCTION__); } while (0)
;
903 assert(m->hdr)do { if ((__builtin_expect(!!(!(m->hdr)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m->hdr"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 903, __PRETTY_FUNCTION__); } while (0)
;
904
905 return m->hdr->nlmsg_seq;
906}
907
908int sd_netlink_message_is_error(sd_netlink_message *m) {
909 assert_return(m, 0)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 909, __PRETTY_FUNCTION__), 0))) return (0); } while (0)
;
910 assert_return(m->hdr, 0)do { if (!(((__builtin_expect(!!(m->hdr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m->hdr"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 910, __PRETTY_FUNCTION__), 0))) return (0); } while (0)
;
911
912 return m->hdr->nlmsg_type == NLMSG_ERROR0x2;
913}
914
915int sd_netlink_message_get_errno(sd_netlink_message *m) {
916 struct nlmsgerr *err;
917
918 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 918, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
919 assert_return(m->hdr, -EINVAL)do { if (!(((__builtin_expect(!!(m->hdr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m->hdr"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 919, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
920
921 if (!sd_netlink_message_is_error(m))
922 return 0;
923
924 err = NLMSG_DATA(m->hdr)((void*)(((char*)m->hdr) + ((0) + ((int) ( ((sizeof(struct
nlmsghdr))+4U -1) & ~(4U -1) )))))
;
925
926 return err->error;
927}
928
929int sd_netlink_message_rewind(sd_netlink_message *m) {
930 const NLType *nl_type;
931 const NLTypeSystem *type_system_root;
932 uint16_t type;
933 size_t size;
934 unsigned i;
935 int r;
936
937 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 937, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
938
939 /* don't allow appending to message once parsed */
940 if (!m->sealed)
941 rtnl_message_seal(m);
942
943 type_system_root = type_system_get_root(m->protocol);
944
945 for (i = 1; i <= m->n_containers; i++)
946 m->containers[i].attributes = mfree(m->containers[i].attributes);
947
948 m->n_containers = 0;
949
950 if (m->containers[0].attributes)
951 /* top-level attributes have already been parsed */
952 return 0;
953
954 assert(m->hdr)do { if ((__builtin_expect(!!(!(m->hdr)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m->hdr"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 954, __PRETTY_FUNCTION__); } while (0)
;
955
956 r = type_system_get_type(type_system_root, &nl_type, m->hdr->nlmsg_type);
957 if (r < 0)
958 return r;
959
960 type = type_get_type(nl_type);
961 size = type_get_size(nl_type);
962
963 if (type == NETLINK_TYPE_NESTED) {
964 const NLTypeSystem *type_system;
965
966 type_get_type_system(nl_type, &type_system);
967
968 m->containers[0].type_system = type_system;
969
970 r = netlink_container_parse(m,
971 &m->containers[m->n_containers],
972 type_system_get_count(type_system),
973 (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr)((void*)(((char*)m->hdr) + ((0) + ((int) ( ((sizeof(struct
nlmsghdr))+4U -1) & ~(4U -1) )))))
+ NLMSG_ALIGN(size)( ((size)+4U -1) & ~(4U -1) )),
974 NLMSG_PAYLOAD(m->hdr, size)((m->hdr)->nlmsg_len - ( (((((size)) + ((int) ( ((sizeof
(struct nlmsghdr))+4U -1) & ~(4U -1) ))))+4U -1) & ~(
4U -1) ))
);
975 if (r < 0)
976 return r;
977 }
978
979 return 0;
980}
981
982void rtnl_message_seal(sd_netlink_message *m) {
983 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 983, __PRETTY_FUNCTION__); } while (0)
;
984 assert(!m->sealed)do { if ((__builtin_expect(!!(!(!m->sealed)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!m->sealed"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 984, __PRETTY_FUNCTION__); } while (0)
;
985
986 m->sealed = true1;
987}
988
989sd_netlink_message *sd_netlink_message_next(sd_netlink_message *m) {
990 assert_return(m, NULL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-netlink/netlink-message.c"
, 990, __PRETTY_FUNCTION__), 0))) return (((void*)0)); } while
(0)
;
991
992 return m->next;
993}