libselinux: Fix if file_contexts not '\n' terminated

If the last line of a file_contexts file is not '\n' terminated
or if any line has additional isspace(3) characters at end, it
gave an invalid file type error.
read_spec_entries now handles these situations.

Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
This commit is contained in:
Richard Haines 2015-06-26 16:03:01 +01:00 committed by Stephen Smalley
parent eda59e2777
commit 893c2924e0

View File

@ -17,9 +17,8 @@
*/
/* Read an entry from a spec file (e.g. file_contexts) */
static inline int read_spec_entry(char **entry, char **ptr)
static inline int read_spec_entry(char **entry, char **ptr, int *len)
{
int entry_len = 0;
*entry = NULL;
char *tmp_buf = NULL;
@ -27,15 +26,18 @@ static inline int read_spec_entry(char **entry, char **ptr)
(*ptr)++;
tmp_buf = *ptr;
*len = 0;
while (!isspace(**ptr) && **ptr != '\0') {
(*ptr)++;
entry_len++;
(*len)++;
}
*entry = strndup(tmp_buf, entry_len);
if (*len) {
*entry = strndup(tmp_buf, *len);
if (!*entry)
return -1;
}
return 0;
}
@ -51,12 +53,17 @@ static inline int read_spec_entry(char **entry, char **ptr)
int hidden read_spec_entries(char *line_buf, int num_args, ...)
{
char **spec_entry, *buf_p;
int len, rc, items;
int len, rc, items, entry_len = 0;
va_list ap;
len = strlen(line_buf);
if (line_buf[len - 1] == '\n')
line_buf[len - 1] = '\0';
else
/* Handle case if line not \n terminated by bumping
* the len for the check below (as the line is NUL
* terminated by getline(3)) */
len++;
buf_p = line_buf;
while (isspace(*buf_p))
@ -69,7 +76,8 @@ int hidden read_spec_entries(char *line_buf, int num_args, ...)
/* Process the spec file entries */
va_start(ap, num_args);
for (items = 0; items < num_args; items++) {
items = 0;
while (items < num_args) {
spec_entry = va_arg(ap, char **);
if (len - 1 == buf_p - line_buf) {
@ -77,11 +85,13 @@ int hidden read_spec_entries(char *line_buf, int num_args, ...)
return items;
}
rc = read_spec_entry(spec_entry, &buf_p);
rc = read_spec_entry(spec_entry, &buf_p, &entry_len);
if (rc < 0) {
va_end(ap);
return rc;
}
if (entry_len)
items++;
}
va_end(ap);
return items;