AmendHub

Download:

jcs

/

subtext

/

amendments

/

349

user: Handle malloc failure


jcs made amendment 349 about 1 year ago
--- user.c Thu Feb 23 17:10:10 2023 +++ user.c Wed Mar 1 19:44:21 2023 @@ -47,17 +47,19 @@ void user_cache_usernames(void) { struct user user; - struct username_cache *muser; + struct username_cache *muser, *new_username_cache; struct bile_object *o; - size_t nuser, len; + size_t new_nusers, nuser, len; - if (db->username_cache != NULL) - xfree(&db->username_cache); + new_nusers = bile_count_by_type(db->bile, DB_USER_RTYPE); + new_username_cache = xreallocarray(db->username_cache, + sizeof(struct username_cache), new_nusers); + if (new_username_cache == NULL) + return; + + db->nusers = new_nusers; + db->username_cache = new_username_cache; - db->nusers = bile_count_by_type(db->bile, DB_USER_RTYPE); - db->username_cache = xmalloczero(sizeof(struct username_cache) * - db->nusers, "username_cache"); - nuser = 0; while ((o = bile_get_nth_of_type(db->bile, nuser, DB_USER_RTYPE))) { muser = &db->username_cache[nuser]; @@ -65,24 +67,28 @@ user_cache_usernames(void) len = bile_read(db->bile, DB_USER_RTYPE, o->id, (char *)&user, sizeof(user)); - if (len != sizeof(user)) + if (len == sizeof(user)) + strncpy(muser->username, user.username, sizeof(muser->username)); + else { warn("user_update_cache_map: user %lu read size %lu != %lu (%d)", o->id, len, sizeof(user), bile_error(db->bile)); - - strncpy(muser->username, user.username, sizeof(muser->username)); + memset(muser->username, 0, sizeof(muser->username)); + } xfree(&o); nuser++; } } -void +bool user_save(struct user *user) { size_t len; if (!user->id) { user->id = bile_next_id(db->bile, DB_USER_RTYPE); + if (!user->id) + return false; user->created_at = Time; } @@ -92,6 +98,7 @@ user_save(struct user *user) panic("user_save: failed to write: %d", bile_error(db->bile)); bile_flush(db->bile, true); + return true; } struct user * @@ -107,8 +114,9 @@ user_find(unsigned long id) if (len != sizeof(struct user)) panic("user_find: bad user record size %lu != %lu", len, sizeof(struct user)); - user = xmalloczero(sizeof(struct user), "user_find"); - memcpy(user, data, sizeof(struct user)); + user = xmalloczero(sizeof(struct user)); + if (user != NULL) + memcpy(user, data, sizeof(struct user)); xfree(&data); return user; } @@ -161,7 +169,9 @@ user_authenticate(struct user *user, const char *passw plen = strlen(password); slen = SHA256_DIGEST_STRING_LENGTH - 1 + plen; - salted = xmalloc(slen, "user_authenticate"); + salted = xmalloc(slen); + if (salted == NULL) + return AUTH_USER_FAILED; memcpy(salted, user->password_salt, SHA256_DIGEST_STRING_LENGTH - 1); memcpy(salted + SHA256_DIGEST_STRING_LENGTH - 1, password, plen); @@ -181,7 +191,7 @@ user_authenticate(struct user *user, const char *passw return AUTH_USER_FAILED; } -void +bool user_set_password(struct user *user, const char *password) { char hash[SHA256_DIGEST_STRING_LENGTH]; @@ -200,7 +210,9 @@ user_set_password(struct user *user, const char *passw plen = strlen(password); slen = plen + sizeof(salt) - 1; - salted = xmalloc(slen, "user_set_password"); + salted = xmalloc(slen); + if (salted == NULL) + return false; memcpy(salted, salt, sizeof(salt) - 1); /* exclude null */ memcpy(salted + sizeof(salt) - 1, password, plen); SHA256Data((const u_int8_t *)salted, slen, hash); @@ -211,6 +223,7 @@ user_set_password(struct user *user, const char *passw memset(&hash, 0, sizeof(hash)); memset(&salt, 0, sizeof(salt)); + return true; } bool @@ -222,15 +235,16 @@ user_valid_username(struct user *user, char *username, char c; if (username == NULL) { - *error = xstrdup("username cannot be empty", "user_valid_username"); + *error = xstrdup("username cannot be empty"); return false; } len = strlen(username); if (len > DB_USERNAME_LENGTH) { - *error = xmalloc(61, "user_valid_username"); - snprintf(*error, 60, "username cannot be more than %d characters", - DB_USERNAME_LENGTH); + *error = xmalloc(61); + if (*error) + snprintf(*error, 60, "username cannot be more than %d " + "characters", DB_USERNAME_LENGTH); return false; } @@ -240,20 +254,19 @@ user_valid_username(struct user *user, char *username, if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_')) { *error = xstrdup("username cannot contain non-alphanumeric " - "characters", "user_valid_username"); + "characters"); return false; } } if (strcasecmp(username, GUEST_USERNAME) == 0) { - *error = xstrdup("username is already in use", - "user_valid_username"); + *error = xstrdup("username is already in use"); return false; } if (!(user != NULL && user->is_sysop) && user_username_is_banned(username)) { - *error = xstrdup("username is not permitted", "user_valid_username"); + *error = xstrdup("username is not permitted"); return false; } @@ -262,8 +275,7 @@ user_valid_username(struct user *user, char *username, xfree(&ouser); if (user == NULL || ouser_id != user->id) { - *error = xstrdup("username is already in use", - "user_valid_username"); + *error = xstrdup("username is already in use"); return false; } } @@ -298,7 +310,7 @@ user_first_sysop_username(void) sizeof(user)); xfree(&o); if (user.is_sysop) { - ret = xstrdup(user.username, "user_first_sysop_username"); + ret = xstrdup(user.username); break; } nuser++; @@ -348,15 +360,26 @@ user_change_password(struct session *s, struct user *u if (strcmp(password_confirm, password) != 0) { session_printf(s, "{{B}}Error:{{/B}} " "Passwords do not match\r\n"); + memset(password, 0, strlen(password)); xfree(&password); - password = NULL; + memset(password_confirm, 0, strlen(password_confirm)); xfree(&password_confirm); - password_confirm = NULL; continue; } - user_set_password(user, password); - user_save(user); + if (!user_set_password(user, password)) { + session_logf(s, "Failed saving new password"); + session_printf(s, "{{B}}Error:{{/B}} " + "Failed saving new password\r\n"); + break; + } + + if (!user_save(user)) { + session_logf(s, "Failed saving user account"); + session_printf(s, "{{B}}Error:{{/B}} " + "Failed saving user account\r\n"); + break; + } if (strcmp(s->user->username, user->username) == 0) { session_logf(s, "User changed password"); @@ -372,10 +395,14 @@ user_change_password(struct session *s, struct user *u break; } - if (password != NULL) + if (password != NULL) { + memset(password, 0, strlen(password)); xfree(&password); - if (password_confirm != NULL) + } + if (password_confirm != NULL) { + memset(password_confirm, 0, strlen(password_confirm)); xfree(&password_confirm); + } } void --- user.h Wed Sep 14 16:36:17 2022 +++ user.h Wed Mar 1 17:39:06 2023 @@ -44,12 +44,12 @@ struct username_cache { }; void user_cache_usernames(void); -void user_save(struct user *user); +bool user_save(struct user *user); struct user * user_find(unsigned long id); struct user * user_find_by_username(const char *username); struct username_cache * user_username(unsigned long id); short user_authenticate(struct user *user, const char *password); -void user_set_password(struct user *user, const char *password); +bool user_set_password(struct user *user, const char *password); bool user_valid_username(struct user *user, char *username, char **error); bool user_username_is_banned(char *username); char * user_first_sysop_username(void);