static int extract_uint32_t(uint32_t *var, size_t size, uint8_t *body, size_t blen, size_t *c) { if (size != sizeof(uint32_t) || *c+size > blen || SIZE_T_OVERFLOW(*c, size)) return EINVAL; SAFEALIGN_COPY_UINT32_CHECK(var, &body[*c], blen, c); return EOK; }
END_TEST START_TEST(test_size_t_overflow) { fail_unless(!SIZE_T_OVERFLOW(1, 1), "unexpected overflow"); fail_unless(!SIZE_T_OVERFLOW(SIZE_MAX, 0), "unexpected overflow"); fail_unless(!SIZE_T_OVERFLOW(SIZE_MAX-10, 10), "unexpected overflow"); fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, 1), "overflow not detected"); fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, SIZE_MAX), "overflow not detected"); fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, ULLONG_MAX), "overflow not detected"); fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, -10), "overflow not detected"); }
static int extract_string(char **var, size_t size, uint8_t *body, size_t blen, size_t *c) { uint8_t *str; if (*c+size > blen || SIZE_T_OVERFLOW(*c, size)) return EINVAL; str = body+(*c); if (str[size-1]!='\0') return EINVAL; /* If the string isn't valid UTF-8, fail */ if (!sss_utf8_check(str, size-1)) { return EINVAL; } *c += size; *var = (char *) str; return EOK; }
static int extract_authtok_v2(struct sss_auth_token *tok, size_t data_size, uint8_t *body, size_t blen, size_t *c) { uint32_t auth_token_type; uint32_t auth_token_length; uint8_t *auth_token_data; int ret = EOK; if (data_size < sizeof(uint32_t) || *c+data_size > blen || SIZE_T_OVERFLOW(*c, data_size)) return EINVAL; SAFEALIGN_COPY_UINT32_CHECK(&auth_token_type, &body[*c], blen, c); auth_token_length = data_size - sizeof(uint32_t); auth_token_data = body+(*c); switch (auth_token_type) { case SSS_AUTHTOK_TYPE_EMPTY: sss_authtok_set_empty(tok); break; case SSS_AUTHTOK_TYPE_PASSWORD: if (auth_token_length == 0) { sss_authtok_set_empty(tok); } else { ret = sss_authtok_set_password(tok, (const char *)auth_token_data, auth_token_length); } break; default: return EINVAL; } *c += auth_token_length; return ret; }