diff options
author | William Pitcock <nenolod@dereferenced.org> | 2017-10-12 00:51:20 +0000 |
---|---|---|
committer | William Pitcock <nenolod@dereferenced.org> | 2017-10-12 00:51:20 +0000 |
commit | afdba0ba0b8c0e92c376e7f1bfb151c07bf654b6 (patch) | |
tree | 8b8e5b58057c394a57e427ba8776a933c8377335 /main/musl/3002-stdio-implement-fopencookie-3.patch | |
parent | ba95a098380de3c708a38dbecc0a8aae077d7574 (diff) | |
download | aports-afdba0ba0b8c0e92c376e7f1bfb151c07bf654b6.tar.bz2 aports-afdba0ba0b8c0e92c376e7f1bfb151c07bf654b6.tar.xz |
main/musl: update to alpine version 1.1.16-r21
- incorporate unreleased upstream bugfixes from august to present:
- fix OOB reads in memmem implementations
- fix undefined behaviour in memset
- fix memory leak in clearenv
- fix unicode processing bugs
- fix signal masking issue with pthread_create
- fix glob descent with GLOB_PERIOD
- implement fopencookie(3)
Diffstat (limited to 'main/musl/3002-stdio-implement-fopencookie-3.patch')
-rw-r--r-- | main/musl/3002-stdio-implement-fopencookie-3.patch | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/main/musl/3002-stdio-implement-fopencookie-3.patch b/main/musl/3002-stdio-implement-fopencookie-3.patch new file mode 100644 index 0000000000..0c5eb63878 --- /dev/null +++ b/main/musl/3002-stdio-implement-fopencookie-3.patch @@ -0,0 +1,211 @@ +From b0949ba08f7b896593eaf27023a16a0f26c9ed14 Mon Sep 17 00:00:00 2001 +From: William Pitcock <nenolod@dereferenced.org> +Date: Sun, 24 Sep 2017 16:37:48 -0500 +Subject: [PATCH 30/30] stdio: implement fopencookie(3) + +The fopencookie(3) function allows the programmer to create a custom +stdio implementation, using four hook functions which operate on a +"cookie" data type. + +Changelog: + +v6: +- remove pointer arithmetic instead using a structure to contain the parent FILE + object +- set F_ERR flag where appropriate +- style fixes +- fix stdio readahead to handle single-byte read case (as pointed out by dalias, + tested by custom fuzzer) +- handle seek return values correctly (found by fuzzing) + +v5: +- implement stdio readahead buffering support + +v4: +- remove parameter names from header function declarations + +v3: +- remove spurious `struct winsize` +- make f->lock unconditionally 0 + +v2: +- properly implement stdio buffering + +v1: +- initial proof of concept +--- + include/stdio.h | 9 ++++ + src/stdio/fopencookie.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 150 insertions(+) + create mode 100644 src/stdio/fopencookie.c + +diff --git a/include/stdio.h b/include/stdio.h +index 884d2e6a..da0563f6 100644 +--- a/include/stdio.h ++++ b/include/stdio.h +@@ -182,6 +182,15 @@ int vasprintf(char **, const char *, __isoc_va_list); + #ifdef _GNU_SOURCE + char *fgets_unlocked(char *, int, FILE *); + int fputs_unlocked(const char *, FILE *); ++ ++typedef struct { ++ ssize_t (*read)(void *, char *, size_t); ++ ssize_t (*write)(void *, const char *, size_t); ++ int (*seek)(void *, off_t *, int); ++ int (*close)(void *); ++} cookie_io_functions_t; ++ ++FILE *fopencookie(void *, const char *, cookie_io_functions_t); + #endif + + #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE) +diff --git a/src/stdio/fopencookie.c b/src/stdio/fopencookie.c +new file mode 100644 +index 00000000..bcf42c10 +--- /dev/null ++++ b/src/stdio/fopencookie.c +@@ -0,0 +1,141 @@ ++#define _GNU_SOURCE ++#include "stdio_impl.h" ++#include <stdlib.h> ++#include <sys/ioctl.h> ++#include <fcntl.h> ++#include <errno.h> ++#include <string.h> ++ ++struct fcookie { ++ void *cookie; ++ cookie_io_functions_t iofuncs; ++}; ++ ++struct cookie_FILE { ++ FILE f; ++ struct fcookie fc; ++ unsigned char buf[UNGET+BUFSIZ]; ++}; ++ ++static size_t cookieread(FILE *f, unsigned char *buf, size_t len) ++{ ++ struct fcookie *fc = f->cookie; ++ ssize_t ret = -1; ++ size_t remain = len, readlen = 0; ++ ++ if (!fc->iofuncs.read) goto bail; ++ ++ ret = fc->iofuncs.read(fc->cookie, (char *) buf, len > 1 ? (len - 1) : 1); ++ if (ret <= 0) goto bail; ++ ++ readlen += ret; ++ remain -= ret; ++ ++ f->rpos = f->buf; ++ ret = fc->iofuncs.read(fc->cookie, (char *) f->rpos, f->buf_size); ++ if (ret <= 0) goto bail; ++ f->rend = f->rpos + ret; ++ ++ if (remain > 0) { ++ if (remain > f->buf_size) remain = f->buf_size; ++ memcpy(buf + readlen, f->rpos, remain); ++ readlen += remain; ++ f->rpos += remain; ++ } ++ ++ return readlen; ++ ++bail: ++ f->flags |= F_EOF ^ ((F_ERR^F_EOF) & ret); ++ f->rpos = f->rend = f->buf; ++ return readlen; ++} ++ ++static size_t cookiewrite(FILE *f, const unsigned char *buf, size_t len) ++{ ++ struct fcookie *fc = f->cookie; ++ ssize_t ret; ++ size_t len2 = f->wpos - f->wbase; ++ if (!fc->iofuncs.write) return len; ++ if (len2) { ++ f->wpos = f->wbase; ++ if (cookiewrite(f, f->wpos, len2) < len2) return 0; ++ } ++ ret = fc->iofuncs.write(fc->cookie, (const char *) buf, len); ++ if (ret < 0) { ++ f->wpos = f->wbase = f->wend = 0; ++ f->flags |= F_ERR; ++ return 0; ++ } ++ return ret; ++} ++ ++static off_t cookieseek(FILE *f, off_t off, int whence) ++{ ++ struct fcookie *fc = f->cookie; ++ int res; ++ if (whence > 2) { ++ errno = EINVAL; ++ return -1; ++ } ++ if (!fc->iofuncs.seek) { ++ errno = ENOTSUP; ++ return -1; ++ } ++ res = fc->iofuncs.seek(fc->cookie, &off, whence); ++ if (res < 0) ++ return res; ++ return off; ++} ++ ++static int cookieclose(FILE *f) ++{ ++ struct fcookie *fc = f->cookie; ++ if (fc->iofuncs.close) return fc->iofuncs.close(fc->cookie); ++ return 0; ++} ++ ++FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t iofuncs) ++{ ++ struct cookie_FILE *f; ++ ++ /* Check for valid initial mode character */ ++ if (!strchr("rwa", *mode)) { ++ errno = EINVAL; ++ return 0; ++ } ++ ++ /* Allocate FILE+fcookie+buffer or fail */ ++ if (!(f=malloc(sizeof *f))) return 0; ++ ++ /* Zero-fill only the struct, not the buffer */ ++ memset(f, 0, sizeof(FILE)); ++ ++ /* Impose mode restrictions */ ++ if (!strchr(mode, '+')) f->f.flags = (*mode == 'r') ? F_NOWR : F_NORD; ++ ++ /* Set up our fcookie */ ++ f->fc.cookie = cookie; ++ f->fc.iofuncs.read = iofuncs.read; ++ f->fc.iofuncs.write = iofuncs.write; ++ f->fc.iofuncs.seek = iofuncs.seek; ++ f->fc.iofuncs.close = iofuncs.close; ++ ++ f->f.fd = -1; ++ f->f.cookie = &f->fc; ++ f->f.buf = f->buf; ++ f->f.buf_size = BUFSIZ; ++ f->f.lbf = EOF; ++ ++ /* enable opportunistic stdio locking */ ++ f->f.lock = 0; ++ ++ /* Initialize op ptrs. No problem if some are unneeded. */ ++ f->f.read = cookieread; ++ f->f.write = cookiewrite; ++ f->f.seek = cookieseek; ++ f->f.close = cookieclose; ++ ++ /* Add new FILE to open file list */ ++ return __ofl_add(&f->f); ++} +-- +2.13.3 + |