diff options
-rw-r--r-- | man/systemd.service.xml | 2 | ||||
-rw-r--r-- | man/systemd.xml | 5 | ||||
-rw-r--r-- | src/analyze/analyze.c | 35 | ||||
-rw-r--r-- | src/basic/env-util.c | 2 | ||||
-rw-r--r-- | src/basic/hashmap.c | 7 | ||||
-rw-r--r-- | src/basic/siphash24.c | 257 | ||||
-rw-r--r-- | src/basic/siphash24.h | 4 | ||||
-rw-r--r-- | src/basic/smack-util.c | 3 | ||||
-rw-r--r-- | src/basic/smack-util.h | 3 | ||||
-rw-r--r-- | src/basic/strv.c | 2 | ||||
-rw-r--r-- | src/core/main.c | 28 | ||||
-rw-r--r-- | src/core/service.c | 4 | ||||
-rw-r--r-- | src/import/pull-common.c | 44 | ||||
-rw-r--r-- | src/journal/journald-rate-limit.c | 12 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp-server.c | 6 | ||||
-rw-r--r-- | src/libsystemd-network/test-dhcp-server.c | 7 | ||||
-rw-r--r-- | src/sysusers/sysusers.c | 34 | ||||
-rw-r--r-- | src/test/test-env-replace.c | 6 | ||||
-rw-r--r-- | src/test/test-hashmap-plain.c | 2 | ||||
-rw-r--r-- | src/test/test-siphash24.c | 24 |
20 files changed, 265 insertions, 222 deletions
diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 897ea464d9..8afdbc513b 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -993,7 +993,7 @@ <literal>$FOO</literal> as a separate word on the command line, in which case it will be replaced by the value of the environment variable split at whitespace resulting in zero or more arguments. - For this type of expansion, quotes and respected when splitting + For this type of expansion, quotes are respected when splitting into words, and afterwards removed.</para> <para>Example:</para> diff --git a/man/systemd.xml b/man/systemd.xml index 391333bfb4..8d74ca49c3 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -922,9 +922,8 @@ the machine automatically when it crashes, after a 10s delay. Otherwise, the system will hang indefinitely. Defaults to <option>no</option>, in order to avoid a reboot loop. If - combined with <varname>systemd.crash_shell=</varname>, it is - first attempted to invoke a shell, and if this is not - successful the system is rebooted.</para></listitem> + combined with <varname>systemd.crash_shell=</varname>, the + system is rebooted after the shell exits.</para></listitem> </varlistentry> <varlistentry> diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index f05f1e5581..a76990360a 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -318,6 +318,8 @@ finish: } static void free_host_info(struct host_info *hi) { + if (hi == NULL) + return; free(hi->hostname); free(hi->kernel_name); free(hi->kernel_release); @@ -327,6 +329,8 @@ static void free_host_info(struct host_info *hi) { free(hi->architecture); free(hi); } +DEFINE_TRIVIAL_CLEANUP_FUNC(struct host_info*, free_host_info); +#define _cleanup_host_info_ _cleanup_(free_host_infop) static int acquire_time_data(sd_bus *bus, struct unit_times **out) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; @@ -431,7 +435,8 @@ fail: static int acquire_host_info(sd_bus *bus, struct host_info **hi) { int r; - struct host_info *host; + _cleanup_host_info_ struct host_info *host; + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; static const struct bus_properties_map hostname_map[] = { { "Hostname", "s", NULL, offsetof(struct host_info, hostname) }, @@ -458,7 +463,8 @@ static int acquire_host_info(sd_bus *bus, struct host_info **hi) { hostname_map, host); if (r < 0) - goto fail; + log_debug_errno(r, "Failed to get host information from systemd-hostnamed: %s", + bus_error_message(&error, r)); r = bus_map_all_properties(bus, "org.freedesktop.systemd1", @@ -466,13 +472,12 @@ static int acquire_host_info(sd_bus *bus, struct host_info **hi) { manager_map, host); if (r < 0) - goto fail; + return log_error_errno(r, "Failed to get host information from systemd: %s", + bus_error_message(&error, r)); *hi = host; + host = NULL; return 0; -fail: - free_host_info(host); - return r; } static int pretty_boot_time(sd_bus *bus, char **_buf) { @@ -537,7 +542,7 @@ static void svg_graph_box(double height, double begin, double end) { static int analyze_plot(sd_bus *bus) { struct unit_times *times; struct boot_times *boot; - struct host_info *host = NULL; + _cleanup_host_info_ struct host_info *host = NULL; int n, m = 1, y=0; double width; _cleanup_free_ char *pretty_times = NULL; @@ -557,7 +562,7 @@ static int analyze_plot(sd_bus *bus) { n = acquire_time_data(bus, ×); if (n <= 0) - goto out; + return n; qsort(times, n, sizeof(struct unit_times), compare_unit_start); @@ -653,12 +658,12 @@ static int analyze_plot(sd_bus *bus) { svg("<text x=\"20\" y=\"50\">%s</text>", pretty_times); svg("<text x=\"20\" y=\"30\">%s %s (%s %s %s) %s %s</text>", isempty(host->os_pretty_name) ? "Linux" : host->os_pretty_name, - isempty(host->hostname) ? "" : host->hostname, - isempty(host->kernel_name) ? "" : host->kernel_name, - isempty(host->kernel_release) ? "" : host->kernel_release, - isempty(host->kernel_version) ? "" : host->kernel_version, - isempty(host->architecture) ? "" : host->architecture, - isempty(host->virtualization) ? "" : host->virtualization); + strempty(host->hostname), + strempty(host->kernel_name), + strempty(host->kernel_release), + strempty(host->kernel_version), + strempty(host->architecture), + strempty(host->virtualization)); svg("<g transform=\"translate(%.3f,100)\">\n", 20.0 + (SCALE_X * boot->firmware_time)); svg_graph_box(m, -(double) boot->firmware_time, boot->finish_time); @@ -742,8 +747,6 @@ static int analyze_plot(sd_bus *bus) { free_unit_times(times, (unsigned) n); n = 0; -out: - free_host_info(host); return n; } diff --git a/src/basic/env-util.c b/src/basic/env-util.c index 4804a67f91..ecb2192c4d 100644 --- a/src/basic/env-util.c +++ b/src/basic/env-util.c @@ -541,7 +541,7 @@ char **replace_env_argv(char **argv, char **env) { STRV_FOREACH(i, argv) { /* If $FOO appears as single word, replace it by the split up variable */ - if ((*i)[0] == '$' && (*i)[1] != '{') { + if ((*i)[0] == '$' && (*i)[1] != '{' && (*i)[1] != '$') { char *e; char **w, **m = NULL; unsigned q; diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c index 3e17ed30df..20e7e51d9e 100644 --- a/src/basic/hashmap.c +++ b/src/basic/hashmap.c @@ -372,12 +372,15 @@ static uint8_t *hash_key(HashmapBase *h) { static unsigned base_bucket_hash(HashmapBase *h, const void *p) { struct siphash state; + uint64_t hash; - siphash_init(&state, hash_key(h)); + siphash24_init(&state, hash_key(h)); h->hash_ops->hash(p, &state); - return (unsigned) (siphash24_finalize(&state) % n_buckets(h)); + siphash24_finalize((uint8_t*)&hash, &state); + + return (unsigned) (hash % n_buckets(h)); } #define bucket_hash(h, p) base_bucket_hash(HASHMAP_BASE(h), p) diff --git a/src/basic/siphash24.c b/src/basic/siphash24.c index 308e4230c5..3b61961389 100644 --- a/src/basic/siphash24.c +++ b/src/basic/siphash24.c @@ -13,175 +13,170 @@ this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. (Minimal changes made by Lennart Poettering, to make clean for inclusion in systemd) + (Refactored by Tom Gundersen to split up in several functions and follow systemd + coding style) */ -#include <stdint.h> -#include <stdio.h> -#include <string.h> + +#include "sparse-endian.h" #include "siphash24.h" +#include "util.h" + +static inline uint64_t rotate_left(uint64_t x, uint8_t b) { + assert(b < 64); + + return (x << b) | (x >> (64 - b)); +} + +static inline void sipround(struct siphash *state) { + assert(state); + + state->v0 += state->v1; + state->v1 = rotate_left(state->v1, 13); + state->v1 ^= state->v0; + state->v0 = rotate_left(state->v0, 32); + state->v2 += state->v3; + state->v3 = rotate_left(state->v3, 16); + state->v3 ^= state->v2; + state->v0 += state->v3; + state->v3 = rotate_left(state->v3, 21); + state->v3 ^= state->v0; + state->v2 += state->v1; + state->v1 = rotate_left(state->v1, 17); + state->v1 ^= state->v2; + state->v2 = rotate_left(state->v2, 32); +} + +void siphash24_init(struct siphash *state, const uint8_t k[16]) { + uint64_t k0, k1; -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint8_t u8; - -#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) ) - -#define U32TO8_LE(p, v) \ - (p)[0] = (u8)((v) ); (p)[1] = (u8)((v) >> 8); \ - (p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24); - -#define U64TO8_LE(p, v) \ - U32TO8_LE((p), (u32)((v) )); \ - U32TO8_LE((p) + 4, (u32)((v) >> 32)); - -#define U8TO64_LE(p) \ - (((u64)((p)[0]) ) | \ - ((u64)((p)[1]) << 8) | \ - ((u64)((p)[2]) << 16) | \ - ((u64)((p)[3]) << 24) | \ - ((u64)((p)[4]) << 32) | \ - ((u64)((p)[5]) << 40) | \ - ((u64)((p)[6]) << 48) | \ - ((u64)((p)[7]) << 56)) - -#define SIPROUND(state) \ - do { \ - (state)->v0 += (state)->v1; (state)->v1=ROTL((state)->v1,13); (state)->v1 ^= (state)->v0; (state)->v0=ROTL((state)->v0,32); \ - (state)->v2 += (state)->v3; (state)->v3=ROTL((state)->v3,16); (state)->v3 ^= (state)->v2; \ - (state)->v0 += (state)->v3; (state)->v3=ROTL((state)->v3,21); (state)->v3 ^= (state)->v0; \ - (state)->v2 += (state)->v1; (state)->v1=ROTL((state)->v1,17); (state)->v1 ^= (state)->v2; (state)->v2=ROTL((state)->v2,32); \ - } while(0) - -void siphash_init(struct siphash *state, const uint8_t k[16]) { - u64 k0, k1; - - k0 = U8TO64_LE( k ); - k1 = U8TO64_LE( k + 8 ); - - /* "somepseudorandomlygeneratedbytes" */ - state->v0 = 0x736f6d6570736575ULL ^ k0; - state->v1 = 0x646f72616e646f6dULL ^ k1; - state->v2 = 0x6c7967656e657261ULL ^ k0; - state->v3 = 0x7465646279746573ULL ^ k1; - state->padding = 0; - state->inlen = 0; + assert(state); + assert(k); + + k0 = le64toh(*(le64_t*) k); + k1 = le64toh(*(le64_t*) (k + 8)); + + /* "somepseudorandomlygeneratedbytes" */ + state->v0 = 0x736f6d6570736575ULL ^ k0; + state->v1 = 0x646f72616e646f6dULL ^ k1; + state->v2 = 0x6c7967656e657261ULL ^ k0; + state->v3 = 0x7465646279746573ULL ^ k1; + state->padding = 0; + state->inlen = 0; } void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) { - u64 m; - const u8 *in = _in; - const u8 *end = in + inlen; - int left = state->inlen & 7; + uint64_t m; + const uint8_t *in = _in; + const uint8_t *end = in + inlen; + unsigned left = state->inlen & 7; - /* update total length */ - state->inlen += inlen; + assert(in); + assert(state); - /* if padding exists, fill it out */ - if (left > 0) { - for ( ; in < end && left < 8; in ++, left ++ ) - state->padding |= ( ( u64 )*in ) << (left * 8); + /* update total length */ + state->inlen += inlen; - if (in == end && left < 8) - /* we did not have enough input to fill out the padding completely */ - return; + /* if padding exists, fill it out */ + if (left > 0) { + for ( ; in < end && left < 8; in ++, left ++ ) + state->padding |= ( ( uint64_t )*in ) << (left * 8); + + if (in == end && left < 8) + /* we did not have enough input to fill out the padding completely */ + return; #ifdef DEBUG - printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); - printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); - printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); - printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); - printf( "(%3d) compress padding %08x %08x\n", ( int )state->inlen, ( u32 )( state->padding >> 32 ), ( u32 )state->padding ); + printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0); + printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1); + printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2); + printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3); + printf("(%3zu) compress padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t)state->padding); #endif - state->v3 ^= state->padding; - SIPROUND(state); - SIPROUND(state); - state->v0 ^= state->padding; + state->v3 ^= state->padding; + sipround(state); + sipround(state); + state->v0 ^= state->padding; - state->padding = 0; - } + state->padding = 0; + } - end -= ( state->inlen % sizeof (u64) ); + end -= ( state->inlen % sizeof (uint64_t) ); - for ( ; in < end; in += 8 ) - { - m = U8TO64_LE( in ); + for ( ; in < end; in += 8 ) { + m = le64toh(*(le64_t*) in); #ifdef DEBUG - printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); - printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); - printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); - printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); - printf( "(%3d) compress %08x %08x\n", ( int )state->inlen, ( u32 )( m >> 32 ), ( u32 )m ); + printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0); + printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1); + printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2); + printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3); + printf("(%3zu) compress %08x %08x\n", state->inlen, (uint32_t) (m >> 32), (uint32_t) m); #endif - state->v3 ^= m; - SIPROUND(state); - SIPROUND(state); - state->v0 ^= m; - } + state->v3 ^= m; + sipround(state); + sipround(state); + state->v0 ^= m; + } - left = state->inlen & 7; + left = state->inlen & 7; - switch( left ) - { - case 7: state->padding |= ( ( u64 )in[ 6] ) << 48; + switch(left) + { + case 7: state->padding |= ((uint64_t) in[6]) << 48; - case 6: state->padding |= ( ( u64 )in[ 5] ) << 40; + case 6: state->padding |= ((uint64_t) in[5]) << 40; - case 5: state->padding |= ( ( u64 )in[ 4] ) << 32; + case 5: state->padding |= ((uint64_t) in[4]) << 32; - case 4: state->padding |= ( ( u64 )in[ 3] ) << 24; + case 4: state->padding |= ((uint64_t) in[3]) << 24; - case 3: state->padding |= ( ( u64 )in[ 2] ) << 16; + case 3: state->padding |= ((uint64_t) in[2]) << 16; - case 2: state->padding |= ( ( u64 )in[ 1] ) << 8; + case 2: state->padding |= ((uint64_t) in[1]) << 8; - case 1: state->padding |= ( ( u64 )in[ 0] ); break; + case 1: state->padding |= ((uint64_t) in[0]); break; - case 0: break; - } + case 0: break; + } } -uint64_t siphash24_finalize(struct siphash *state) { - u64 b; +void siphash24_finalize(uint8_t out[8], struct siphash *state) { + uint64_t b; - b = state->padding | (( ( u64 )state->inlen ) << 56); + b = state->padding | (( ( uint64_t )state->inlen ) << 56); #ifdef DEBUG - printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); - printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); - printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); - printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); - printf( "(%3d) padding %08x %08x\n", ( int )state->inlen, ( u32 )( state->padding >> 32 ), ( u32 )state->padding ); + printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t)state->v0); + printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t)state->v1); + printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t)state->v2); + printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t)state->v3); + printf("(%3zu) padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t) state->padding); #endif - state->v3 ^= b; - SIPROUND(state); - SIPROUND(state); - state->v0 ^= b; + state->v3 ^= b; + sipround(state); + sipround(state); + state->v0 ^= b; #ifdef DEBUG - printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); - printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); - printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); - printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); + printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0); + printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1); + printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2); + printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3); #endif - state->v2 ^= 0xff; - SIPROUND(state); - SIPROUND(state); - SIPROUND(state); - SIPROUND(state); + state->v2 ^= 0xff; + + sipround(state); + sipround(state); + sipround(state); + sipround(state); - return state->v0 ^ state->v1 ^ state->v2 ^ state->v3; + *(le64_t*)out = htole64(state->v0 ^ state->v1 ^ state->v2 ^ state->v3); } /* SipHash-2-4 */ -void siphash24(uint8_t out[8], const void *_in, size_t inlen, const uint8_t k[16]) -{ - struct siphash state; - u64 b; - - siphash_init(&state, k); - - siphash24_compress(_in, inlen, &state); - - b = siphash24_finalize(&state); +void siphash24(uint8_t out[8], const void *_in, size_t inlen, const uint8_t k[16]) { + struct siphash state; - U64TO8_LE( out, b ); + siphash24_init(&state, k); + siphash24_compress(_in, inlen, &state); + siphash24_finalize(out, &state); } diff --git a/src/basic/siphash24.h b/src/basic/siphash24.h index c107bdd213..6c5cd98ee8 100644 --- a/src/basic/siphash24.h +++ b/src/basic/siphash24.h @@ -12,8 +12,8 @@ struct siphash { size_t inlen; }; -void siphash_init(struct siphash *state, const uint8_t k[16]); +void siphash24_init(struct siphash *state, const uint8_t k[16]); void siphash24_compress(const void *in, size_t inlen, struct siphash *state); -uint64_t siphash24_finalize(struct siphash *state); +void siphash24_finalize(uint8_t out[8], struct siphash *state); void siphash24(uint8_t out[8], const void *in, size_t inlen, const uint8_t k[16]); diff --git a/src/basic/smack-util.c b/src/basic/smack-util.c index 9e221d6eab..5f570ff02a 100644 --- a/src/basic/smack-util.c +++ b/src/basic/smack-util.c @@ -29,9 +29,6 @@ #include "fileio.h" #include "smack-util.h" -#define SMACK_FLOOR_LABEL "_" -#define SMACK_STAR_LABEL "*" - #ifdef HAVE_SMACK bool mac_smack_use(void) { static int cached_use = -1; diff --git a/src/basic/smack-util.h b/src/basic/smack-util.h index b3aa55eb8a..e756dc8c28 100644 --- a/src/basic/smack-util.h +++ b/src/basic/smack-util.h @@ -27,6 +27,9 @@ #include "macro.h" +#define SMACK_FLOOR_LABEL "_" +#define SMACK_STAR_LABEL "*" + typedef enum SmackAttr { SMACK_ATTR_ACCESS = 0, SMACK_ATTR_EXEC = 1, diff --git a/src/basic/strv.c b/src/basic/strv.c index 27cb540895..b66c176487 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -850,7 +850,7 @@ int strv_extend_n(char ***l, const char *value, size_t n) { return 0; rollback: - for (j = k; j < i; i++) + for (j = k; j < i; j++) free(nl[j]); nl[k] = NULL; diff --git a/src/core/main.c b/src/core/main.c index 2256fc5b33..87b3af92bc 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -142,6 +142,8 @@ noreturn static void freeze_or_reboot(void) { } noreturn static void crash(int sig) { + struct sigaction sa; + pid_t pid; if (getpid() != 1) /* Pass this on immediately, if this is not PID 1 */ @@ -149,11 +151,10 @@ noreturn static void crash(int sig) { else if (!arg_dump_core) log_emergency("Caught <%s>, not dumping core.", signal_to_string(sig)); else { - struct sigaction sa = { + sa = (struct sigaction) { .sa_handler = nop_signal_handler, .sa_flags = SA_NOCLDSTOP|SA_RESTART, }; - pid_t pid; /* We want to wait for the core process, hence let's enable SIGCHLD */ (void) sigaction(SIGCHLD, &sa, NULL); @@ -209,19 +210,18 @@ noreturn static void crash(int sig) { if (arg_crash_chvt >= 0) (void) chvt(arg_crash_chvt); - if (arg_crash_shell) { - struct sigaction sa = { - .sa_handler = SIG_IGN, - .sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART, - }; - pid_t pid; + sa = (struct sigaction) { + .sa_handler = SIG_IGN, + .sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART, + }; + + /* Let the kernel reap children for us */ + (void) sigaction(SIGCHLD, &sa, NULL); + if (arg_crash_shell) { log_notice("Executing crash shell in 10s..."); (void) sleep(10); - /* Let the kernel reap children for us */ - (void) sigaction(SIGCHLD, &sa, NULL); - pid = raw_clone(SIGCHLD, NULL); if (pid < 0) log_emergency_errno(errno, "Failed to fork off crash shell: %m"); @@ -231,11 +231,10 @@ noreturn static void crash(int sig) { (void) execle("/bin/sh", "/bin/sh", NULL, environ); log_emergency_errno(errno, "execle() failed: %m"); - freeze_or_reboot(); _exit(EXIT_FAILURE); } else { log_info("Spawned crash shell as PID "PID_FMT".", pid); - freeze(); + (void) wait_for_terminate(pid, NULL); } } @@ -521,7 +520,6 @@ static int config_parse_crash_chvt( assert(filename); assert(lvalue); assert(rvalue); - assert(data); r = parse_crash_chvt(rvalue); if (r < 0) { @@ -1129,7 +1127,7 @@ static void test_mtab(void) { log_error("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. " "This is not supported anymore. " - "Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output."); + "Please replace /etc/mtab with a symlink to /proc/self/mounts."); freeze_or_reboot(); } diff --git a/src/core/service.c b/src/core/service.c index 8c339765a4..ce3b81398d 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -363,8 +363,10 @@ static int service_add_fd_store(Service *s, int fd, const char *name) { fs->fd = fd; fs->service = s; fs->fdname = strdup(name ?: "stored"); - if (!fs->fdname) + if (!fs->fdname) { + free(fs); return -ENOMEM; + } r = sd_event_add_io(UNIT(s)->manager->event, &fs->event_source, fd, 0, on_fd_store_io, fs); if (r < 0) { diff --git a/src/import/pull-common.c b/src/import/pull-common.c index 38201e46e1..1ddb48e03f 100644 --- a/src/import/pull-common.c +++ b/src/import/pull-common.c @@ -31,8 +31,10 @@ #include "pull-common.h" #include "process-util.h" #include "signal-util.h" +#include "siphash24.h" #define FILENAME_ESCAPE "/.#\"\'" +#define HASH_URL_THRESHOLD_LENGTH (_POSIX_PATH_MAX - 16) int pull_find_old_etags( const char *url, @@ -149,8 +151,21 @@ int pull_make_local_copy(const char *final, const char *image_root, const char * return 0; } +static int hash_url(const char *url, char **ret) { + uint64_t h; + static const sd_id128_t k = SD_ID128_ARRAY(df,89,16,87,01,cc,42,30,98,ab,4a,19,a6,a5,63,4f); + + assert(url); + + siphash24((uint8_t *) &h, url, strlen(url), k.bytes); + if (asprintf(ret, "%"PRIx64, h) < 0) + return -ENOMEM; + + return 0; +} + int pull_make_path(const char *url, const char *etag, const char *image_root, const char *prefix, const char *suffix, char **ret) { - _cleanup_free_ char *escaped_url = NULL; + _cleanup_free_ char *escaped_url = NULL, *escaped_etag = NULL; char *path; assert(url); @@ -164,18 +179,35 @@ int pull_make_path(const char *url, const char *etag, const char *image_root, co return -ENOMEM; if (etag) { - _cleanup_free_ char *escaped_etag = NULL; - escaped_etag = xescape(etag, FILENAME_ESCAPE); if (!escaped_etag) return -ENOMEM; + } - path = strjoin(image_root, "/", strempty(prefix), escaped_url, ".", escaped_etag, strempty(suffix), NULL); - } else - path = strjoin(image_root, "/", strempty(prefix), escaped_url, strempty(suffix), NULL); + path = strjoin(image_root, "/", strempty(prefix), escaped_url, escaped_etag ? "." : "", + strempty(escaped_etag), strempty(suffix), NULL); if (!path) return -ENOMEM; + /* URLs might make the path longer than the maximum allowed length for a file name. + * When that happens, a URL hash is used instead. Paths returned by this function + * can be later used with tempfn_random() which adds 16 bytes to the resulting name. */ + if (strlen(path) >= HASH_URL_THRESHOLD_LENGTH) { + _cleanup_free_ char *hash = NULL; + int r; + + free(path); + + r = hash_url(url, &hash); + if (r < 0) + return r; + + path = strjoin(image_root, "/", strempty(prefix), hash, escaped_etag ? "." : "", + strempty(escaped_etag), strempty(suffix), NULL); + if (!path) + return -ENOMEM; + } + *ret = path; return 0; } diff --git a/src/journal/journald-rate-limit.c b/src/journal/journald-rate-limit.c index 7e06117b31..8afd493b50 100644 --- a/src/journal/journald-rate-limit.c +++ b/src/journal/journald-rate-limit.c @@ -57,7 +57,7 @@ struct JournalRateLimitGroup { char *id; JournalRateLimitPool pools[POOLS_MAX]; - unsigned long hash; + uint64_t hash; LIST_FIELDS(JournalRateLimitGroup, bucket); LIST_FIELDS(JournalRateLimitGroup, lru); @@ -158,9 +158,9 @@ static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, if (!g->id) goto fail; - siphash_init(&state, r->hash_key); + siphash24_init(&state, r->hash_key); string_hash_func(g->id, &state); - g->hash = siphash24_finalize(&state); + siphash24_finalize((uint8_t*)&g->hash, &state); journal_rate_limit_vacuum(r, ts); @@ -207,7 +207,7 @@ static unsigned burst_modulate(unsigned burst, uint64_t available) { } int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) { - unsigned long h; + uint64_t h; JournalRateLimitGroup *g; JournalRateLimitPool *p; struct siphash state; @@ -226,9 +226,9 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u ts = now(CLOCK_MONOTONIC); - siphash_init(&state, r->hash_key); + siphash24_init(&state, r->hash_key); string_hash_func(id, &state); - h = siphash24_finalize(&state); + siphash24_finalize((uint8_t*)&h, &state); g = r->buckets[h % BUCKETS_MAX]; LIST_FOREACH(bucket, g, g) diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index d941e6c0de..d27bb561ca 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -741,15 +741,17 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, address = existing_lease->address; else { struct siphash state; + uint64_t hash; uint32_t next_offer; /* even with no persistence of leases, we try to offer the same client the same IP address. we do this by using the hash of the client id as the offset into the pool of leases when finding the next free one */ - siphash_init(&state, HASH_KEY.bytes); + siphash24_init(&state, HASH_KEY.bytes); client_id_hash_func(&req->client_id, &state); - next_offer = siphash24_finalize(&state) % server->pool_size; + siphash24_finalize((uint8_t*)&hash, &state); + next_offer = hash % server->pool_size; for (i = 0; i < server->pool_size; i++) { if (!server->bound_leases[next_offer]) { diff --git a/src/libsystemd-network/test-dhcp-server.c b/src/libsystemd-network/test-dhcp-server.c index 01205efc18..c3bcb9cb4b 100644 --- a/src/libsystemd-network/test-dhcp-server.c +++ b/src/libsystemd-network/test-dhcp-server.c @@ -200,10 +200,13 @@ static void test_message_handler(void) { static uint64_t client_id_hash_helper(DHCPClientId *id, uint8_t key[HASH_KEY_SIZE]) { struct siphash state; + uint64_t hash; - siphash_init(&state, key); + siphash24_init(&state, key); client_id_hash_func(id, &state); - return siphash24_finalize(&state); + siphash24_finalize((uint8_t*)&hash, &state); + + return hash; } static void test_client_id_hash(void) { diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 07494e764b..ba09727080 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -38,6 +38,7 @@ #include "uid-range.h" #include "utf8.h" #include "util.h" +#include "smack-util.h" typedef enum ItemType { ADD_USER = 'u', @@ -352,6 +353,19 @@ static int sync_rights(FILE *from, FILE *to) { return 0; } +static int rename_and_apply_smack(const char *temp_path, const char *dest_path) { + int r = 0; + if (rename(temp_path, dest_path) < 0) + return -errno; + +#ifdef SMACK_RUN_LABEL + r = mac_smack_apply(dest_path, SMACK_ATTR_ACCESS, SMACK_FLOOR_LABEL); + if (r < 0) + return r; +#endif + return r; +} + static int write_files(void) { _cleanup_fclose_ FILE *passwd = NULL, *group = NULL, *shadow = NULL, *gshadow = NULL; @@ -698,36 +712,32 @@ static int write_files(void) { /* And make the new files count */ if (group_changed) { if (group) { - if (rename(group_tmp, group_path) < 0) { - r = -errno; + r = rename_and_apply_smack(group_tmp, group_path); + if (r < 0) goto finish; - } group_tmp = mfree(group_tmp); } if (gshadow) { - if (rename(gshadow_tmp, gshadow_path) < 0) { - r = -errno; + r = rename_and_apply_smack(gshadow_tmp, gshadow_path); + if (r < 0) goto finish; - } gshadow_tmp = mfree(gshadow_tmp); } } if (passwd) { - if (rename(passwd_tmp, passwd_path) < 0) { - r = -errno; + r = rename_and_apply_smack(passwd_tmp, passwd_path); + if (r < 0) goto finish; - } passwd_tmp = mfree(passwd_tmp); } if (shadow) { - if (rename(shadow_tmp, shadow_path) < 0) { - r = -errno; + r = rename_and_apply_smack(shadow_tmp, shadow_path); + if (r < 0) goto finish; - } shadow_tmp = mfree(shadow_tmp); } diff --git a/src/test/test-env-replace.c b/src/test/test-env-replace.c index 2e28c0c49b..110223f3b8 100644 --- a/src/test/test-env-replace.c +++ b/src/test/test-env-replace.c @@ -118,6 +118,8 @@ static void test_replace_env_arg(void) { "$FOO$FOO", "${FOO}${BAR}", "${FOO", + "FOO$$${FOO}", + "$$FOO${FOO}", NULL }; _cleanup_strv_free_ char **r = NULL; @@ -133,7 +135,9 @@ static void test_replace_env_arg(void) { assert_se(streq(r[6], "BAR")); assert_se(streq(r[7], "BAR BARwaldo")); assert_se(streq(r[8], "${FOO")); - assert_se(strv_length(r) == 9); + assert_se(streq(r[9], "FOO$BAR BAR")); + assert_se(streq(r[10], "$FOOBAR BAR")); + assert_se(strv_length(r) == 11); } static void test_env_clean(void) { diff --git a/src/test/test-hashmap-plain.c b/src/test/test-hashmap-plain.c index 78f9c19f5b..c691f577c6 100644 --- a/src/test/test-hashmap-plain.c +++ b/src/test/test-hashmap-plain.c @@ -710,7 +710,7 @@ static void test_hashmap_many(void) { unsigned n_entries; } tests[] = { { .ops = NULL, .n_entries = 1 << 20 }, - { .ops = &crippled_hashmap_ops, .n_entries = 1 << 11 }, + { .ops = &crippled_hashmap_ops, .n_entries = 1 << 14 }, }; diff --git a/src/test/test-siphash24.c b/src/test/test-siphash24.c index 65eb2b6f35..2402da6a6f 100644 --- a/src/test/test-siphash24.c +++ b/src/test/test-siphash24.c @@ -32,23 +32,13 @@ int main(int argc, char *argv[]) { const uint8_t key[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; uint64_t out = 0; - unsigned i, j, k; - usec_t ts; + unsigned i, j; siphash24((uint8_t *)&out, in, sizeof(in), key); - assert_se(out == 0xa129ca6149be45e5); - - assert_se(out == 0xa129ca6149be45e5ULL); - - ts = now(CLOCK_MONOTONIC); - for (k = 0; k < ITERATIONS; k++) - siphash24((uint8_t *)&out, in, sizeof(in), key); - ts = now(CLOCK_MONOTONIC) - ts; - - log_info("%llu iterations per second", (ITERATIONS * USEC_PER_SEC) / ts); + assert_se(out == htole64(0xa129ca6149be45e5)); /* verify the internal state as given in the above paper */ - siphash_init(&state, key); + siphash24_init(&state, key); assert_se(state.v0 == 0x7469686173716475); assert_se(state.v1 == 0x6b617f6d656e6665); assert_se(state.v2 == 0x6b7f62616d677361); @@ -58,7 +48,8 @@ int main(int argc, char *argv[]) { assert_se(state.v1 == 0x0d52f6f62a4f59a4); assert_se(state.v2 == 0x634cb3577b01fd3d); assert_se(state.v3 == 0xa5224d6f55c7d9c8); - assert_se(siphash24_finalize(&state) == 0xa129ca6149be45e5); + siphash24_finalize((uint8_t*)&out, &state); + assert_se(out == htole64(0xa129ca6149be45e5)); assert_se(state.v0 == 0xf6bcd53893fecff1); assert_se(state.v1 == 0x54b9964c7ea0d937); assert_se(state.v2 == 0x1b38329c099bb55a); @@ -68,11 +59,12 @@ int main(int argc, char *argv[]) { same result */ for (i = 0; i < sizeof(in); i++) { for (j = i; j < sizeof(in); j++) { - siphash_init(&state, key); + siphash24_init(&state, key); siphash24_compress(in, i, &state); siphash24_compress(&in[i], j - i, &state); siphash24_compress(&in[j], sizeof(in) - j, &state); - assert_se(siphash24_finalize(&state) == 0xa129ca6149be45e5); + siphash24_finalize((uint8_t*)&out, &state); + assert_se(out == htole64(0xa129ca6149be45e5)); } } } |