die_if_bad_username: tighten up a bit
No binary (build failed)
—
(log yok)
| @@ -18,23 +18,45 @@ | |
| void FAST_FUNC die_if_bad_username(const char *name) | |
| { | |
| - | /* 1st char being dash or dot isn't valid: */ |
| - | goto skip; |
| - | /* For example, name like ".." can make adduser |
| - | * chown "/home/.." recursively - NOT GOOD |
| + | const char *start = name; |
| + | |
| + | /* 1st char being dash or dot isn't valid: |
| + | * for example, name like ".." can make adduser |
| + | * chown "/home/.." recursively - NOT GOOD. |
| + | * Name of just a single "$" is also rejected. |
| */ | |
| + | goto skip; |
| do { | |
| - | if (*name == '-' || *name == '.') |
| + | unsigned char ch; |
| + | |
| + | /* These chars are valid unless they are at the 1st pos: */ |
| + | if (*name == '-' |
| + | || *name == '.' |
| + | /* $ is allowed if it's the last char: */ |
| + | || (*name == '$' && !name[1]) |
| + | ) { |
| continue; | |
| + | } |
| skip: | |
| - | if (isalnum(*name) |
| - | || *name == '_' |
| - | || *name == '@' |
| - | || (*name == '$' && !name[1]) |
| + | ch = *name; |
| + | if (ch == '_' |
| + | /* || ch == '@' -- we disallow this too. Think about "user@host" */ |
| + | /* open-coded isalnum: */ |
| + | || (ch >= '0' && ch <= '9') |
| + | || ((ch|0x20) >= 'a' && (ch|0x20) <= 'z') |
| ) { | |
| continue; | |
| } | |
| - | bb_error_msg_and_die("illegal character '%c'", *name); |
| + | bb_error_msg_and_die("illegal character with code %u at position %u", |
| + | (unsigned)ch, (unsigned)(name - start)); |
| } while (*++name); | |
| + | |
| + | /* The minimum size of the login name is one char or two if |
| + | * last char is the '$'. Violations of this are caught above. |
| + | * The maximum size of the login name is LOGIN_NAME_MAX |
| + | * including the terminating null byte. |
| + | */ |
| + | if (name - start >= LOGIN_NAME_MAX) |
| + | bb_error_msg_and_die("name is too long"); |
| } | |