[apparmor] [PATCH v2 17/42] parser: Clean up snprintf_buffer()
John Johansen
john.johansen at canonical.com
Tue Mar 10 16:50:09 UTC 2015
On 03/06/2015 01:48 PM, Tyler Hicks wrote:
> snprintf_buffer() needed to be modified in order to properly return error
> conditions up the stack, instead of exiting, but there were some other
> cleanups that it could use.
>
> It was obviously implemented with the features_struct in mind so this
> patch simplifies the input parameters by directly accepting a
> features_struct pointer. Also, the name is changed to reflect that it is
> intended to work on a features_struct instead of an arbritrary buffer.
>
> A quick sanity check is added to make sure that the features_struct.pos
> value isn't pointing past the end of the buffer.
>
> The printf(3) family of functions can return a negative value upon error
> so a check of the return value of vsnprintf(3) is added.
>
> Finally, the return values of the function are simplified to 0 on
> success or -1, with errno set, on error. This is possible since
> features_struct.pos can be internally updated after a successful
> vsnprintf(3).
>
> Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
Acked-by: John Johansen <john.johansen at canonical.com>
> ---
> parser/features.c | 43 ++++++++++++++++++++++++++++---------------
> 1 file changed, 28 insertions(+), 15 deletions(-)
>
> diff --git a/parser/features.c b/parser/features.c
> index 673fe4f..a2c25c2 100644
> --- a/parser/features.c
> +++ b/parser/features.c
> @@ -36,30 +36,41 @@
> #define FEATURES_STRING_SIZE 8192
> char *features_string = NULL;
>
> -static char *snprintf_buffer(char *buf, char *pos, ssize_t size,
> - const char *fmt, ...)
> +struct features_struct {
> + char **buffer;
> + int size;
> + char *pos;
> +};
> +
> +static int features_snprintf(struct features_struct *fst, const char *fmt, ...)
> {
> va_list args;
> - int i, remaining = size - (pos - buf);
> + int i, remaining = fst->size - (fst->pos - *fst->buffer);
> +
> + if (remaining < 0) {
> + errno = EINVAL;
> + PERROR(_("Invalid features buffer offset\n"));
> + return -1;
> + }
>
> va_start(args, fmt);
> - i = vsnprintf(pos, remaining, fmt, args);
> + i = vsnprintf(fst->pos, remaining, fmt, args);
> va_end(args);
>
> - if (i >= size) {
> + if (i < 0) {
> + errno = EIO;
> + PERROR(_("Failed to write to features buffer\n"));
> + return -1;
> + } else if (i >= remaining) {
> + errno = ENOBUFS;
> PERROR(_("Feature buffer full."));
> - exit(1);
> + return -1;
> }
>
> - return pos + i;
> + fst->pos += i;
> + return 0;
> }
>
> -struct features_struct {
> - char **buffer;
> - int size;
> - char *pos;
> -};
> -
> static int features_dir_cb(DIR *dir, const char *name, struct stat *st,
> void *data)
> {
> @@ -69,7 +80,8 @@ static int features_dir_cb(DIR *dir, const char *name, struct stat *st,
> if (*name == '.' || !strlen(name))
> return 0;
>
> - fst->pos = snprintf_buffer(*fst->buffer, fst->pos, fst->size, "%s {", name);
> + if (features_snprintf(fst, "%s {", name) == -1)
> + return -1;
>
> if (S_ISREG(st->st_mode)) {
> autoclose int file = -1;
> @@ -104,7 +116,8 @@ static int features_dir_cb(DIR *dir, const char *name, struct stat *st,
> return -1;
> }
>
> - fst->pos = snprintf_buffer(*fst->buffer, fst->pos, fst->size, "}\n");
> + if (features_snprintf(fst, "}\n") == -1)
> + return -1;
>
> return 0;
> }
>
More information about the AppArmor
mailing list