Skip to content

Commit 7ff4389

Browse files
committed
replace use of strlen()
1 parent a986c3c commit 7ff4389

1 file changed

Lines changed: 36 additions & 7 deletions

File tree

src/OVAL/probes/unix/password_probe.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include <string.h>
5050
#include <stdio.h>
5151
#include <errno.h>
52+
#include <inttypes.h>
5253
#include <pwd.h>
5354
#include <paths.h>
5455
#if defined(OS_APPLE)
@@ -72,14 +73,43 @@
7273
* This parses a standard /etc/passwd-format file one entry at a time.
7374
*/
7475
#ifndef HAVE_FGETPWENT
76+
static int oscap_parse_passwd_id(const char *field, uintmax_t max_value,
77+
uintmax_t *parsed_value)
78+
{
79+
char *endptr;
80+
uintmax_t value;
81+
82+
errno = 0;
83+
value = strtoumax(field, &endptr, 10);
84+
if (errno != 0 || endptr == field || *endptr != '\0' || value > max_value)
85+
return -1;
86+
87+
*parsed_value = value;
88+
return 0;
89+
}
90+
7591
static struct passwd *oscap_fgetpwent(FILE *fp)
7692
{
7793
static char line[2048];
7894
static struct passwd pw;
79-
char *fields[7], *p;
95+
char *fields[7], *newline, *line_end, *p;
96+
uintmax_t parsed_uid, parsed_gid;
8097
int f;
8198

8299
while (fgets(line, sizeof(line), fp) != NULL) {
100+
newline = memchr(line, '\n', sizeof(line) - 1);
101+
line_end = memchr(line, '\0', sizeof(line));
102+
if (newline != NULL)
103+
*newline = '\0';
104+
else if (line_end == &line[sizeof(line) - 1]) {
105+
int ch;
106+
107+
/* Skip truncated records instead of parsing partial passwd entries. */
108+
while ((ch = fgetc(fp)) != '\n' && ch != EOF)
109+
;
110+
continue;
111+
}
112+
83113
if (line[0] == '#' || line[0] == '\n')
84114
continue;
85115
f = 0;
@@ -94,14 +124,13 @@ static struct passwd *oscap_fgetpwent(FILE *fp)
94124
}
95125
if (f < 7)
96126
continue;
97-
/* strip trailing newline from shell field */
98-
size_t n = strlen(fields[6]);
99-
if (n > 0 && fields[6][n - 1] == '\n')
100-
fields[6][n - 1] = '\0';
127+
if (oscap_parse_passwd_id(fields[2], (uintmax_t)(uid_t)-1, &parsed_uid) != 0 ||
128+
oscap_parse_passwd_id(fields[3], (uintmax_t)(gid_t)-1, &parsed_gid) != 0)
129+
continue;
101130
pw.pw_name = fields[0];
102131
pw.pw_passwd = fields[1];
103-
pw.pw_uid = (uid_t)atoi(fields[2]);
104-
pw.pw_gid = (gid_t)atoi(fields[3]);
132+
pw.pw_uid = (uid_t)parsed_uid;
133+
pw.pw_gid = (gid_t)parsed_gid;
105134
pw.pw_gecos = fields[4];
106135
pw.pw_dir = fields[5];
107136
pw.pw_shell = fields[6];

0 commit comments

Comments
 (0)