Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(#2037807) Allow unprivileged users to send ICMP echo requests #256

Merged
merged 8 commits into from Feb 7, 2022
Merged
4 changes: 4 additions & 0 deletions man/sysctl.d.xml
Expand Up @@ -60,6 +60,10 @@
<filename>/proc/sys/net/ipv4/conf/enp3s0.200/forwarding</filename>.
</para>

<para>If a variable assignment is prefixed with a single <literal>-</literal> character, any attempts to
set it that fail will be ignored (though are logged). Moreover, any access permission errors, and
attempts to write variables not defined on the local system are ignored (and logged) too.</para>

<para>The settings configured with <filename>sysctl.d</filename>
files will be applied early on boot. The network
interface-specific options will also be applied individually for
Expand Down
2 changes: 2 additions & 0 deletions src/basic/alloc-util.h
Expand Up @@ -8,6 +8,8 @@

#include "macro.h"

typedef void (*free_func_t)(void *p);

#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))

#define new0(t, n) ((t*) calloc((n), sizeof(t)))
Expand Down
49 changes: 13 additions & 36 deletions src/basic/hash-funcs.c
Expand Up @@ -5,21 +5,13 @@
#include "hash-funcs.h"
#include "path-util.h"

void string_hash_func(const void *p, struct siphash *state) {
void string_hash_func(const char *p, struct siphash *state) {
siphash24_compress(p, strlen(p) + 1, state);
}

int string_compare_func(const void *a, const void *b) {
return strcmp(a, b);
}

const struct hash_ops string_hash_ops = {
.hash = string_hash_func,
.compare = string_compare_func
};
DEFINE_HASH_OPS(string_hash_ops, char, string_hash_func, string_compare_func);

void path_hash_func(const void *p, struct siphash *state) {
const char *q = p;
void path_hash_func(const char *q, struct siphash *state) {
size_t n;

assert(q);
Expand Down Expand Up @@ -57,14 +49,11 @@ void path_hash_func(const void *p, struct siphash *state) {
}
}

int path_compare_func(const void *a, const void *b) {
int path_compare_func(const char *a, const char *b) {
return path_compare(a, b);
}

const struct hash_ops path_hash_ops = {
.hash = path_hash_func,
.compare = path_compare_func
};
DEFINE_HASH_OPS(path_hash_ops, char, path_hash_func, path_compare_func);

void trivial_hash_func(const void *p, struct siphash *state) {
siphash24_compress(&p, sizeof(p), state);
Expand All @@ -79,36 +68,24 @@ const struct hash_ops trivial_hash_ops = {
.compare = trivial_compare_func
};

void uint64_hash_func(const void *p, struct siphash *state) {
void uint64_hash_func(const uint64_t *p, struct siphash *state) {
siphash24_compress(p, sizeof(uint64_t), state);
}

int uint64_compare_func(const void *_a, const void *_b) {
uint64_t a, b;
a = *(const uint64_t*) _a;
b = *(const uint64_t*) _b;
return a < b ? -1 : (a > b ? 1 : 0);
int uint64_compare_func(const uint64_t *a, const uint64_t *b) {
return CMP(*a, *b);
}

const struct hash_ops uint64_hash_ops = {
.hash = uint64_hash_func,
.compare = uint64_compare_func
};
DEFINE_HASH_OPS(uint64_hash_ops, uint64_t, uint64_hash_func, uint64_compare_func);

#if SIZEOF_DEV_T != 8
void devt_hash_func(const void *p, struct siphash *state) {
void devt_hash_func(const dev_t *p, struct siphash *state) {
siphash24_compress(p, sizeof(dev_t), state);
}

int devt_compare_func(const void *_a, const void *_b) {
dev_t a, b;
a = *(const dev_t*) _a;
b = *(const dev_t*) _b;
return a < b ? -1 : (a > b ? 1 : 0);
int devt_compare_func(const dev_t *a, const dev_t *b) {
return CMP(*a, *b);
}

const struct hash_ops devt_hash_ops = {
.hash = devt_hash_func,
.compare = devt_compare_func
};
DEFINE_HASH_OPS(devt_hash_ops, dev_t, devt_hash_func, devt_compare_func);
#endif
78 changes: 69 additions & 9 deletions src/basic/hash-funcs.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once


#include "alloc-util.h"
#include "macro.h"
#include "siphash24.h"

Expand All @@ -11,14 +11,74 @@ typedef int (*compare_func_t)(const void *a, const void *b);
struct hash_ops {
hash_func_t hash;
compare_func_t compare;
free_func_t free_key;
free_func_t free_value;
};

void string_hash_func(const void *p, struct siphash *state);
int string_compare_func(const void *a, const void *b) _pure_;
#define _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, free_key_func, free_value_func, scope) \
_unused_ static void (* UNIQ_T(static_hash_wrapper, uq))(const type *, struct siphash *) = hash_func; \
_unused_ static int (* UNIQ_T(static_compare_wrapper, uq))(const type *, const type *) = compare_func; \
scope const struct hash_ops name = { \
.hash = (hash_func_t) hash_func, \
.compare = (compare_func_t) compare_func, \
.free_key = free_key_func, \
.free_value = free_value_func, \
}

#define _DEFINE_FREE_FUNC(uq, type, wrapper_name, func) \
/* Type-safe free function */ \
static void UNIQ_T(wrapper_name, uq)(void *a) { \
type *_a = a; \
func(_a); \
}

#define _DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(uq, name, type, hash_func, compare_func, free_func, scope) \
_DEFINE_FREE_FUNC(uq, type, static_free_wrapper, free_func); \
_DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \
UNIQ_T(static_free_wrapper, uq), NULL, scope)

#define _DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(uq, name, type, hash_func, compare_func, type_value, free_func, scope) \
_DEFINE_FREE_FUNC(uq, type_value, static_free_wrapper, free_func); \
_DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \
NULL, UNIQ_T(static_free_wrapper, uq), scope)

#define _DEFINE_HASH_OPS_FULL(uq, name, type, hash_func, compare_func, free_key_func, type_value, free_value_func, scope) \
_DEFINE_FREE_FUNC(uq, type, static_free_key_wrapper, free_key_func); \
_DEFINE_FREE_FUNC(uq, type_value, static_free_value_wrapper, free_value_func); \
_DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \
UNIQ_T(static_free_key_wrapper, uq), \
UNIQ_T(static_free_value_wrapper, uq), scope)

#define DEFINE_HASH_OPS(name, type, hash_func, compare_func) \
_DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, NULL, NULL,)

#define DEFINE_PRIVATE_HASH_OPS(name, type, hash_func, compare_func) \
_DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, NULL, NULL, static)

#define DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(name, type, hash_func, compare_func, free_func) \
_DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, free_func,)

#define DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(name, type, hash_func, compare_func, free_func) \
_DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, free_func, static)

#define DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(name, type, hash_func, compare_func, value_type, free_func) \
_DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, value_type, free_func,)

#define DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(name, type, hash_func, compare_func, value_type, free_func) \
_DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, value_type, free_func, static)

#define DEFINE_HASH_OPS_FULL(name, type, hash_func, compare_func, free_key_func, value_type, free_value_func) \
_DEFINE_HASH_OPS_FULL(UNIQ, name, type, hash_func, compare_func, free_key_func, value_type, free_value_func,)

#define DEFINE_PRIVATE_HASH_OPS_FULL(name, type, hash_func, compare_func, free_key_func, value_type, free_value_func) \
_DEFINE_HASH_OPS_FULL(UNIQ, name, type, hash_func, compare_func, free_key_func, value_type, free_value_func, static)

void string_hash_func(const char *p, struct siphash *state);
#define string_compare_func strcmp
extern const struct hash_ops string_hash_ops;

void path_hash_func(const void *p, struct siphash *state);
int path_compare_func(const void *a, const void *b) _pure_;
void path_hash_func(const char *p, struct siphash *state);
int path_compare_func(const char *a, const char *b) _pure_;
extern const struct hash_ops path_hash_ops;

/* This will compare the passed pointers directly, and will not dereference them. This is hence not useful for strings
Expand All @@ -29,15 +89,15 @@ extern const struct hash_ops trivial_hash_ops;

/* 32bit values we can always just embed in the pointer itself, but in order to support 32bit archs we need store 64bit
* values indirectly, since they don't fit in a pointer. */
void uint64_hash_func(const void *p, struct siphash *state);
int uint64_compare_func(const void *a, const void *b) _pure_;
void uint64_hash_func(const uint64_t *p, struct siphash *state);
int uint64_compare_func(const uint64_t *a, const uint64_t *b) _pure_;
extern const struct hash_ops uint64_hash_ops;

/* On some archs dev_t is 32bit, and on others 64bit. And sometimes it's 64bit on 32bit archs, and sometimes 32bit on
* 64bit archs. Yuck! */
#if SIZEOF_DEV_T != 8
void devt_hash_func(const void *p, struct siphash *state) _pure_;
int devt_compare_func(const void *a, const void *b) _pure_;
void devt_hash_func(const dev_t *p, struct siphash *state) _pure_;
int devt_compare_func(const dev_t *a, const dev_t *b) _pure_;
extern const struct hash_ops devt_hash_ops;
#else
#define devt_hash_func uint64_hash_func
Expand Down
76 changes: 19 additions & 57 deletions src/basic/hashmap.c
Expand Up @@ -863,47 +863,38 @@ static void hashmap_free_no_clear(HashmapBase *h) {
free(h);
}

HashmapBase *internal_hashmap_free(HashmapBase *h) {

/* Free the hashmap, but nothing in it */

HashmapBase *internal_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) {
if (h) {
internal_hashmap_clear(h);
internal_hashmap_clear(h, default_free_key, default_free_value);
hashmap_free_no_clear(h);
}

return NULL;
}

HashmapBase *internal_hashmap_free_free(HashmapBase *h) {
void internal_hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) {
free_func_t free_key, free_value;
if (!h)
return;

/* Free the hashmap and all data objects in it, but not the
* keys */
free_key = h->hash_ops->free_key ?: default_free_key;
free_value = h->hash_ops->free_value ?: default_free_value;

if (h) {
internal_hashmap_clear_free(h);
hashmap_free_no_clear(h);
}

return NULL;
}
if (free_key || free_value) {
unsigned idx;

Hashmap *hashmap_free_free_free(Hashmap *h) {
for (idx = skip_free_buckets(h, 0); idx != IDX_NIL;
idx = skip_free_buckets(h, idx + 1)) {
struct hashmap_base_entry *e = bucket_at(h, idx);

/* Free the hashmap and all data and key objects in it */
if (free_key)
free_key((void *) e->key);

if (h) {
hashmap_clear_free_free(h);
hashmap_free_no_clear(HASHMAP_BASE(h));
if (free_value)
free_value(entry_value(h, e));
}
}

return NULL;
}

void internal_hashmap_clear(HashmapBase *h) {
if (!h)
return;

if (h->has_indirect) {
free(h->indirect.storage);
h->has_indirect = false;
Expand All @@ -920,35 +911,6 @@ void internal_hashmap_clear(HashmapBase *h) {
base_set_dirty(h);
}

void internal_hashmap_clear_free(HashmapBase *h) {
unsigned idx;

if (!h)
return;

for (idx = skip_free_buckets(h, 0); idx != IDX_NIL;
idx = skip_free_buckets(h, idx + 1))
free(entry_value(h, bucket_at(h, idx)));

internal_hashmap_clear(h);
}

void hashmap_clear_free_free(Hashmap *h) {
unsigned idx;

if (!h)
return;

for (idx = skip_free_buckets(HASHMAP_BASE(h), 0); idx != IDX_NIL;
idx = skip_free_buckets(HASHMAP_BASE(h), idx + 1)) {
struct plain_hashmap_entry *e = plain_bucket_at(h, idx);
free((void*)e->b.key);
free(e->value);
}

internal_hashmap_clear(HASHMAP_BASE(h));
}

static int resize_buckets(HashmapBase *h, unsigned entries_add);

/*
Expand Down Expand Up @@ -1771,7 +1733,7 @@ HashmapBase *internal_hashmap_copy(HashmapBase *h) {
}

if (r < 0) {
internal_hashmap_free(copy);
internal_hashmap_free(copy, false, false);
return NULL;
}

Expand Down