mirror of
https://github.com/systemd/systemd.git
synced 2025-03-13 00:58:27 +03:00
Add memcpy_safe
ISO/IEC 9899:1999 §7.21.1/2 says: Where an argument declared as size_t n specifies the length of the array for a function, n can have the value zero on a call to that function. Unless explicitly stated otherwise in the description of a particular function in this subclause, pointer arguments on such a call shall still have valid values, as described in 7.1.4. In base64_append_width memcpy was called as memcpy(x, NULL, 0). GCC 4.9 started making use of this and assumes This worked fine under -O0, but does something strange under -O3. This patch fixes a bug in base64_append_width(), fixes a possible bug in journal_file_append_entry_internal(), and makes use of the new function to simplify the code in other places.
This commit is contained in:
parent
8cd095cc27
commit
75f32f047c
@ -27,6 +27,7 @@
|
||||
#include "alloc-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "macro.h"
|
||||
#include "util.h"
|
||||
|
||||
char octchar(int x) {
|
||||
return '0' + (x & 7);
|
||||
@ -574,7 +575,7 @@ static int base64_append_width(char **prefix, int plen,
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(t + plen, sep, slen);
|
||||
memcpy_safe(t + plen, sep, slen);
|
||||
|
||||
for (line = 0, s = t + plen + slen, avail = len; line < lines; line++) {
|
||||
int act = MIN(width, avail);
|
||||
|
@ -104,6 +104,16 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_
|
||||
qsort(base, nmemb, size, compar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal memcpy requires src to be nonnull. We do nothing if n is 0.
|
||||
*/
|
||||
static inline void memcpy_safe(void *dst, const void *src, size_t n) {
|
||||
if (n == 0)
|
||||
return;
|
||||
assert(src);
|
||||
memcpy(dst, src, n);
|
||||
}
|
||||
|
||||
int on_ac_power(void);
|
||||
|
||||
#define memzero(x,l) (memset((x), 0, (l)))
|
||||
|
@ -1110,8 +1110,8 @@ static int journal_file_append_data(
|
||||
}
|
||||
#endif
|
||||
|
||||
if (compression == 0 && size > 0)
|
||||
memcpy(o->data.payload, data, size);
|
||||
if (compression == 0)
|
||||
memcpy_safe(o->data.payload, data, size);
|
||||
|
||||
r = journal_file_link_data(f, o, p, hash);
|
||||
if (r < 0)
|
||||
@ -1373,7 +1373,7 @@ static int journal_file_append_entry_internal(
|
||||
return r;
|
||||
|
||||
o->entry.seqnum = htole64(journal_file_entry_seqnum(f, seqnum));
|
||||
memcpy(o->entry.items, items, n_items * sizeof(EntryItem));
|
||||
memcpy_safe(o->entry.items, items, n_items * sizeof(EntryItem));
|
||||
o->entry.realtime = htole64(ts->realtime);
|
||||
o->entry.monotonic = htole64(ts->monotonic);
|
||||
o->entry.xor_hash = htole64(xor_hash);
|
||||
|
@ -56,12 +56,7 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
||||
options[*offset] = code;
|
||||
options[*offset + 1] = optlen;
|
||||
|
||||
if (optlen) {
|
||||
assert(optval);
|
||||
|
||||
memcpy(&options[*offset + 2], optval, optlen);
|
||||
}
|
||||
|
||||
memcpy_safe(&options[*offset + 2], optval, optlen);
|
||||
*offset += optlen + 2;
|
||||
|
||||
break;
|
||||
|
@ -73,8 +73,7 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (optval)
|
||||
memcpy(*buf, optval, optlen);
|
||||
memcpy_safe(*buf, optval, optlen);
|
||||
|
||||
*buf += optlen;
|
||||
*buflen -= optlen;
|
||||
|
@ -112,14 +112,9 @@ static DHCPMessage *create_message(uint8_t *options, uint16_t optlen,
|
||||
message = malloc0(len);
|
||||
assert_se(message);
|
||||
|
||||
if (options && optlen)
|
||||
memcpy(&message->options, options, optlen);
|
||||
|
||||
if (file && filelen <= 128)
|
||||
memcpy(&message->file, file, filelen);
|
||||
|
||||
if (sname && snamelen <= 64)
|
||||
memcpy(&message->sname, sname, snamelen);
|
||||
memcpy_safe(&message->options, options, optlen);
|
||||
memcpy_safe(&message->file, file, filelen);
|
||||
memcpy_safe(&message->sname, sname, snamelen);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
@ -1133,8 +1133,7 @@ static int add_name_change_match(sd_bus *bus,
|
||||
item->name_change.old_id.id = old_owner_id;
|
||||
item->name_change.new_id.id = new_owner_id;
|
||||
|
||||
if (name)
|
||||
memcpy(item->name_change.name, name, l);
|
||||
memcpy_safe(item->name_change.name, name, l);
|
||||
|
||||
/* If the old name is unset or empty, then
|
||||
* this can match against added names */
|
||||
|
@ -2633,8 +2633,7 @@ _public_ int sd_bus_message_append_array(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (size > 0)
|
||||
memcpy(p, ptr, size);
|
||||
memcpy_safe(p, ptr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -352,7 +352,7 @@ static int bus_socket_auth_write(sd_bus *b, const char *t) {
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
|
||||
memcpy_safe(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
|
||||
memcpy(p + b->auth_iovec[0].iov_len, t, l);
|
||||
|
||||
b->auth_iovec[0].iov_base = p;
|
||||
@ -789,7 +789,7 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
|
||||
|
||||
n = m->n_iovec * sizeof(struct iovec);
|
||||
iov = alloca(n);
|
||||
memcpy(iov, m->iovec, n);
|
||||
memcpy_safe(iov, m->iovec, n);
|
||||
|
||||
j = 0;
|
||||
iovec_advance(iov, &j, *idx);
|
||||
@ -1000,7 +1000,7 @@ int bus_socket_read_message(sd_bus *bus) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
|
||||
memcpy_safe(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
|
||||
bus->fds = f;
|
||||
bus->n_fds += n;
|
||||
} else
|
||||
|
@ -219,9 +219,8 @@ static void *serialize_addrinfo(void *p, const struct addrinfo *ai, size_t *leng
|
||||
|
||||
memcpy((uint8_t*) p, &s, sizeof(AddrInfoSerialization));
|
||||
memcpy((uint8_t*) p + sizeof(AddrInfoSerialization), ai->ai_addr, ai->ai_addrlen);
|
||||
|
||||
if (ai->ai_canonname)
|
||||
memcpy((char*) p + sizeof(AddrInfoSerialization) + ai->ai_addrlen, ai->ai_canonname, cnl);
|
||||
memcpy_safe((char*) p + sizeof(AddrInfoSerialization) + ai->ai_addrlen,
|
||||
ai->ai_canonname, cnl);
|
||||
|
||||
*length += l;
|
||||
return (uint8_t*) p + l;
|
||||
|
@ -2580,12 +2580,10 @@ static int inner_child(
|
||||
|
||||
/* Automatically search for the init system */
|
||||
|
||||
m = 1 + strv_length(arg_parameters);
|
||||
a = newa(char*, m + 1);
|
||||
if (strv_isempty(arg_parameters))
|
||||
a[1] = NULL;
|
||||
else
|
||||
memcpy(a + 1, arg_parameters, m * sizeof(char*));
|
||||
m = strv_length(arg_parameters);
|
||||
a = newa(char*, m + 2);
|
||||
memcpy_safe(a + 1, arg_parameters, m * sizeof(char*));
|
||||
a[1 + m] = NULL;
|
||||
|
||||
a[0] = (char*) "/usr/lib/systemd/systemd";
|
||||
execve(a[0], a, env_use);
|
||||
|
@ -433,8 +433,7 @@ int dns_packet_append_raw_string(DnsPacket *p, const void *s, size_t size, size_
|
||||
|
||||
((uint8_t*) d)[0] = (uint8_t) size;
|
||||
|
||||
if (size > 0)
|
||||
memcpy(((uint8_t*) d) + 1, s, size);
|
||||
memcpy_safe(((uint8_t*) d) + 1, s, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user