Changeset View
Changeset View
Standalone View
Standalone View
include/ssp/stdio.h
| Show All 30 Lines | |||||
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| * POSSIBILITY OF SUCH DAMAGE. | * POSSIBILITY OF SUCH DAMAGE. | ||||
| */ | */ | ||||
| #ifndef _SSP_STDIO_H_ | #ifndef _SSP_STDIO_H_ | ||||
| #define _SSP_STDIO_H_ | #define _SSP_STDIO_H_ | ||||
| #include <ssp/ssp.h> | #include <ssp/ssp.h> | ||||
| #if __SSP_FORTIFY_LEVEL > 0 && __EXT1_VISIBLE | |||||
| #include <sys/stdint.h> | |||||
| #endif | |||||
| __BEGIN_DECLS | __BEGIN_DECLS | ||||
| #if __SSP_FORTIFY_LEVEL > 0 | #if __SSP_FORTIFY_LEVEL > 0 | ||||
| #if __POSIX_VISIBLE | #if __POSIX_VISIBLE | ||||
| __ssp_redirect_raw(char *, ctermid, ctermid, (char *__buf), (__buf), | __ssp_redirect_raw(char *, ctermid, ctermid, (char *__buf), (__buf), | ||||
| __buf != NULL, __ssp_bos, L_ctermid); | __buf != NULL, __ssp_bos, L_ctermid); | ||||
| #if __BSD_VISIBLE | #if __BSD_VISIBLE | ||||
| __ssp_redirect_raw(char *, ctermid_r, ctermid_r, (char *__buf), (__buf), | __ssp_redirect_raw(char *, ctermid_r, ctermid_r, (char *__buf), (__buf), | ||||
| __buf != NULL, __ssp_bos, L_ctermid); | __buf != NULL, __ssp_bos, L_ctermid); | ||||
| #endif /* __BSD_VISIBLE */ | #endif /* __BSD_VISIBLE */ | ||||
| #endif /* __POSIX_VISIBLE */ | #endif /* __POSIX_VISIBLE */ | ||||
| __ssp_redirect(size_t, fread, (void *__restrict __buf, size_t __len, | __ssp_redirect(size_t, fread, (void *__restrict __buf, size_t __len, | ||||
| size_t __nmemb, FILE *__restrict __fp), (__buf, __len, __nmemb, __fp)); | size_t __nmemb, FILE *__restrict __fp), (__buf, __len, __nmemb, __fp)); | ||||
| __ssp_redirect(size_t, fread_unlocked, (void *__restrict __buf, size_t __len, | __ssp_redirect(size_t, fread_unlocked, (void *__restrict __buf, size_t __len, | ||||
| size_t __nmemb, FILE *__restrict __fp), (__buf, __len, __nmemb, __fp)); | size_t __nmemb, FILE *__restrict __fp), (__buf, __len, __nmemb, __fp)); | ||||
| #if __EXT1_VISIBLE | #if __EXT1_VISIBLE | ||||
| __ssp_redirect(char *, gets_s, (char *__buf, rsize_t __len), (__buf, __len)); | __ssp_redirect_raw_impl(char *, gets_s, gets_s, | ||||
| (char *buf, rsize_t len)) | |||||
| { | |||||
| char *retbuf; | |||||
| size_t bufsz; | |||||
| int need_fail = 0; | |||||
| /* | |||||
| * If we would have overwritten our buffer, we want to fail the check | |||||
| * only if these arguments wouldn't have triggered a constraint | |||||
| * violation. | |||||
| */ | |||||
kevans: Actually, I think I may backtrack slightly on this: still immediate `__chk_fail` if `len` is… | |||||
| bufsz = __ssp_bos(buf); | |||||
| if (bufsz != (size_t)-1 && (size_t)len > bufsz) { | |||||
| if (len <= RSIZE_MAX) | |||||
| __chk_fail(); | |||||
| need_fail = 1; | |||||
| } | |||||
| retbuf = __ssp_real(gets_s)(buf, len); | |||||
| if (need_fail && retbuf != NULL) | |||||
Not Done Inline ActionsThis feels a bit dubious since by this point some hypothetical memory corruption would have already happened, so one can't count on need_fail having been preserved, say. But I'm not sure what else you can do, and if the gets_s() implementation behaves as specified then this isn't a concern. markj: This feels a bit dubious since by this point some hypothetical memory corruption would have… | |||||
Done Inline ActionsRight, that's what I noted in the update comment here, my hope was:
We do have test coverage to be sure that we're handling it in a reasonable manner, so it's really just a layer of paranoia more than anything kevans: Right, that's what I noted in the update comment here, my hope was:
> but hopefully we would… | |||||
| __chk_fail(); | |||||
| return (retbuf); | |||||
| } | |||||
| #endif /* __EXT1_VISIBLE */ | #endif /* __EXT1_VISIBLE */ | ||||
| __ssp_redirect_raw(char *, tmpnam, tmpnam, (char *__buf), (__buf), 1, | __ssp_redirect_raw(char *, tmpnam, tmpnam, (char *__buf), (__buf), 1, | ||||
| __ssp_bos, L_tmpnam); | __ssp_bos, L_tmpnam); | ||||
| #endif | #endif | ||||
| int __sprintf_chk(char *__restrict, int, size_t, const char *__restrict, ...) | int __sprintf_chk(char *__restrict, int, size_t, const char *__restrict, ...) | ||||
| __printflike(4, 5); | __printflike(4, 5); | ||||
| int __vsprintf_chk(char *__restrict, int, size_t, const char *__restrict, | int __vsprintf_chk(char *__restrict, int, size_t, const char *__restrict, | ||||
| ▲ Show 20 Lines • Show All 45 Lines • Show Last 20 Lines | |||||
Actually, I think I may backtrack slightly on this: still immediate __chk_fail if len is within bounds, but set a local need_error if we still know len is too high and assert or __chk_fail if it doesn't error out as expected.