mirror of
https://github.com/systemd/systemd.git
synced 2024-11-02 02:21:44 +03:00
dhcp-identifier: un-inline dhcp_validate_duid_len
After all it is used in more than one place and is not that short. Also tweak the test a bit: - do not check that duid_len > 0, because we want to allow unknown duid types, and there might be some which are fine with 0 length data, (also assert should not be called from library code), - always check that duid_len <= MAX_DUID_LEN, because we could overwrite available buffer space otherwise.
This commit is contained in:
parent
f7a92d1a7e
commit
3b6a4e97ea
@ -31,6 +31,37 @@
|
||||
#define SYSTEMD_PEN 43793
|
||||
#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
|
||||
|
||||
int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
|
||||
struct duid d;
|
||||
|
||||
assert_cc(sizeof(d.raw) >= MAX_DUID_LEN);
|
||||
if (duid_len > MAX_DUID_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
switch (duid_type) {
|
||||
case DUID_TYPE_LLT:
|
||||
if (duid_len <= sizeof(d.llt))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case DUID_TYPE_EN:
|
||||
if (duid_len != sizeof(d.en))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case DUID_TYPE_LL:
|
||||
if (duid_len <= sizeof(d.ll))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case DUID_TYPE_UUID:
|
||||
if (duid_len != sizeof(d.uuid))
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
/* accept unknown type in order to be forward compatible */
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
|
||||
sd_id128_t machine_id;
|
||||
uint64_t hash;
|
||||
|
@ -40,27 +40,28 @@ typedef enum DUIDType {
|
||||
*/
|
||||
#define MAX_DUID_LEN 128
|
||||
|
||||
/* https://tools.ietf.org/html/rfc3315#section-9.1 */
|
||||
struct duid {
|
||||
be16_t type;
|
||||
union {
|
||||
struct {
|
||||
/* DHCP6_DUID_LLT */
|
||||
/* DUID_TYPE_LLT */
|
||||
uint16_t htype;
|
||||
uint32_t time;
|
||||
uint8_t haddr[0];
|
||||
} _packed_ llt;
|
||||
struct {
|
||||
/* DHCP6_DUID_EN */
|
||||
/* DUID_TYPE_EN */
|
||||
uint32_t pen;
|
||||
uint8_t id[8];
|
||||
} _packed_ en;
|
||||
struct {
|
||||
/* DHCP6_DUID_LL */
|
||||
/* DUID_TYPE_LL */
|
||||
int16_t htype;
|
||||
uint8_t haddr[0];
|
||||
} _packed_ ll;
|
||||
struct {
|
||||
/* DHCP6_DUID_UUID */
|
||||
/* DUID_TYPE_UUID */
|
||||
sd_id128_t uuid;
|
||||
} _packed_ uuid;
|
||||
struct {
|
||||
@ -69,36 +70,6 @@ struct duid {
|
||||
};
|
||||
} _packed_;
|
||||
|
||||
int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len);
|
||||
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
|
||||
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
|
||||
|
||||
static inline int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
|
||||
struct duid d;
|
||||
|
||||
assert(duid_len > 0);
|
||||
|
||||
switch (duid_type) {
|
||||
case DUID_TYPE_LLT:
|
||||
if (duid_len <= sizeof(d.llt))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case DUID_TYPE_EN:
|
||||
if (duid_len != sizeof(d.en))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case DUID_TYPE_LL:
|
||||
if (duid_len <= sizeof(d.ll))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case DUID_TYPE_UUID:
|
||||
if (duid_len != sizeof(d.uuid))
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
if (duid_len > sizeof(d.raw))
|
||||
return -EINVAL;
|
||||
/* accept unknown type in order to be forward compatible */
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user