From b409ddcec8c7ae304a7985e450b723fbb95cf4e9 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Thu, 24 Jun 2021 16:04:57 +0200 Subject: libfstree: guard against possible overflow in readlink() *in theory*, say on a 32 bit system, we could have a 32 bit size_t and a 64 bit off_t. If the filesystem permitted this, we *could* then have a symlink with a target > 4G. Or the target is exacetely 4G, but adding a null-terminator could exceed addressable memory. This commit adds a check to guard against such an overflow and throw an error, instead of silently wrapping around. Signed-off-by: David Oberhollenzer --- lib/fstree/fstree_from_dir.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/fstree/fstree_from_dir.c b/lib/fstree/fstree_from_dir.c index 9f8e3ba..e0ea600 100644 --- a/lib/fstree/fstree_from_dir.c +++ b/lib/fstree/fstree_from_dir.c @@ -358,12 +358,25 @@ static int populate_dir(int dir_fd, fstree_t *fs, tree_node_t *root, continue; if (S_ISLNK(sb.st_mode)) { - extra = calloc(1, sb.st_size + 1); + size_t size; + + if ((sizeof(sb.st_size) > sizeof(size_t)) && + sb.st_size > SIZE_MAX) { + errno = EOVERFLOW; + goto fail_rdlink; + } + + if (SZ_ADD_OV((size_t)sb.st_size, 1, &size)) { + errno = EOVERFLOW; + goto fail_rdlink; + } + + extra = calloc(1, size); if (extra == NULL) goto fail_rdlink; if (readlinkat(dir_fd, ent->d_name, - extra, sb.st_size) < 0) { + extra, (size_t)sb.st_size) < 0) { goto fail_rdlink; } -- cgit v1.2.3