o compat_group() and files_group() are more complicated than I thought

in rev. 1.34.  Mainly I missed the fact that the buffer is used for two
purposes:

1) storing a group line from the group file;

2) __gr_parse_entry() parses the buffer and tries to put the group
members to the remaining part of the buffer and can fail if there
is no enough room for them.

Re-arrange the buffer size checks to account the latter case.

Submitted by:	Kirk R Webb
MFC after:	2 weeks
This commit is contained in:
Maxim Konovalov 2006-07-14 17:45:33 +00:00
parent 2e5ea45f19
commit 0ec15b18a2

View File

@ -770,18 +770,17 @@ files_group(void *retval, void *mdata, va_list ap)
* pointer for the member list terminator. * pointer for the member list terminator.
*/ */
if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) { if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
fseeko(st->fp, pos, SEEK_SET);
*errnop = ERANGE; *errnop = ERANGE;
rv = NS_RETURN; rv = NS_RETURN;
break; break;
} }
pos = ftello(st->fp);
memcpy(buffer, line, linesize); memcpy(buffer, line, linesize);
buffer[linesize] = '\0'; buffer[linesize] = '\0';
rv = __gr_parse_entry(buffer, linesize, grp, rv = __gr_parse_entry(buffer, linesize, grp,
&buffer[linesize + 1], bufsize - linesize - 1, errnop); &buffer[linesize + 1], bufsize - linesize - 1, errnop);
if (rv & NS_TERMINATE) if (rv & NS_TERMINATE)
break; break;
pos = ftello(st->fp);
} }
if (!stayopen && st->fp != NULL) { if (!stayopen && st->fp != NULL) {
fclose(st->fp); fclose(st->fp);
@ -789,6 +788,8 @@ files_group(void *retval, void *mdata, va_list ap)
} }
if (rv == NS_SUCCESS && retval != NULL) if (rv == NS_SUCCESS && retval != NULL)
*(struct group **)retval = grp; *(struct group **)retval = grp;
else if (*errnop == ERANGE)
fseeko(st->fp, pos, SEEK_SET);
return (rv); return (rv);
} }
@ -1322,18 +1323,17 @@ docompat:
* pointer for the member list terminator. * pointer for the member list terminator.
*/ */
if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) { if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
fseeko(st->fp, pos, SEEK_SET);
*errnop = ERANGE; *errnop = ERANGE;
rv = NS_RETURN; rv = NS_RETURN;
break; break;
} }
pos = ftello(st->fp);
memcpy(buffer, line, linesize); memcpy(buffer, line, linesize);
buffer[linesize] = '\0'; buffer[linesize] = '\0';
rv = __gr_parse_entry(buffer, linesize, grp, rv = __gr_parse_entry(buffer, linesize, grp,
&buffer[linesize + 1], bufsize - linesize - 1, errnop); &buffer[linesize + 1], bufsize - linesize - 1, errnop);
if (rv & NS_TERMINATE) if (rv & NS_TERMINATE)
break; break;
pos = ftello(st->fp);
} }
fin: fin:
if (!stayopen && st->fp != NULL) { if (!stayopen && st->fp != NULL) {
@ -1342,6 +1342,8 @@ fin:
} }
if (rv == NS_SUCCESS && retval != NULL) if (rv == NS_SUCCESS && retval != NULL)
*(struct group **)retval = grp; *(struct group **)retval = grp;
else if (*errnop == ERANGE)
fseeko(st->fp, pos, SEEK_SET);
return (rv); return (rv);
#undef set_lookup_type #undef set_lookup_type
} }