From 645b1184ec996696f24a65c1ad39fc50a1e5cbb2 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 24 Jul 2022 16:14:09 -0700 Subject: Correctly handle readlink overflow. * safepath.h (SAFEPATH_TOOLONG): New enum constant. * safepath.c (safepatch_check): Don't ignore the truncation situation from readlink. Use the full buffer length, and if readlink returns 256, then diagnose overflow using the new SAFEPATH_TOOLONG error code and bail. (safepath_strerr): Map SAFEPATH_TOOLONG. --- safepath.c | 10 ++++++++-- safepath.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/safepath.c b/safepath.c index 7d9f6fc..ce95740 100644 --- a/safepath.c +++ b/safepath.c @@ -248,11 +248,16 @@ int safepath_check(const char *name) goto free_out; } - if ((len = readlink(copy, link, sizeof link - 1)) < 0) { + if ((len = readlink(copy, link, sizeof link)) < 0) { ret = safepath_err(errno); goto free_out; } + if (len == sizeof link) { + ret = SAFEPATH_TOOLONG; + goto free_out; + } + link[len] = 0; /* Resolve the symlink, using two different cases based @@ -352,7 +357,8 @@ const char *safepath_strerr(int err) [SAFEPATH_NOTDIR] = "path contains non-directory component", [SAFEPATH_INVAL] = "path is syntactically invalid", [SAFEPATH_NOMEM] = "out of memory", - [SAFEPATH_LOOP] = "too many symlink resolutions" + [SAFEPATH_LOOP] = "too many symlink resolutions", + [SAFEPATH_TOOLONG] = "path component or symlink target too long" }; const char *ret = "SAFEPATH_BAD_ERROR_CODE"; diff --git a/safepath.h b/safepath.h index 766a163..99786b1 100644 --- a/safepath.h +++ b/safepath.h @@ -45,6 +45,7 @@ enum { SAFEPATH_INVAL, /* path is invalid */ SAFEPATH_NOMEM, /* out of memory */ SAFEPATH_LOOP, /* more than 8 levels of symlink */ + SAFEPATH_TOOLONG, /* component or symlink target too long */ }; int safepath_check(const char *name); -- cgit v1.2.3