From: Benjamin Kaduk Date: Sat, 2 Feb 2019 18:49:07 +0000 (-0600) Subject: vol: check snprintf return values in namei_ops X-Git-Tag: upstream/1.8.6_pre1^2~22 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=2bb9dc093b65210a33ffa3b21e6173bbe0452a0c;p=packages%2Fo%2Fopenafs.git vol: check snprintf return values in namei_ops gcc8 is more aggressive about parsing format strings and computing bounds on the generated text from functions like snprintf. In this case it seems best to detect cases of truncation and error out, rather than trying to increase stack buffer sizes or switch to asprintf. These paths should be well-behaved since they are local to the fileserver, so this is mostly about appeasing the compiler's -Wformat-truncation checks to allow us to build with --enable-checking. Reviewed-on: https://gerrit.openafs.org/13463 Tested-by: BuildBot Reviewed-by: Cheyenne Wills Reviewed-by: Benjamin Kaduk (cherry picked from commit 8632f23d6718a3cd621791e82d1cf6ead8690978) Change-Id: Ie8f9005ad9cf7cdfd3eb472e01a6fdbde5b7e57e Reviewed-on: https://gerrit.openafs.org/13732 Reviewed-by: Andrew Deason Reviewed-by: Marcio Brito Barbosa Reviewed-by: Michael Meffie Tested-by: BuildBot Reviewed-by: Stephan Wiesand --- diff --git a/src/vol/namei_ops.c b/src/vol/namei_ops.c index aee57a3c3..ced434a50 100644 --- a/src/vol/namei_ops.c +++ b/src/vol/namei_ops.c @@ -2605,8 +2605,14 @@ namei_ListAFSSubDirs(IHandle_t * dirIH, #ifndef AFS_NT40_ENV /* This level missing on Windows */ /* Now we've got a next level subdir. */ - snprintf(path2, sizeof(path2), "%s" OS_DIRSEP "%s", - path1, dp1->d_name); + code = snprintf(path2, sizeof(path2), "%s" OS_DIRSEP "%s", + path1, dp1->d_name); + if (code < 0 || code >= sizeof(path2)) { + /* error, or truncated */ + closedir(dirp1); + ret = -1; + goto error; + } dirp2 = opendir(path2); if (dirp2) { while ((dp2 = readdir(dirp2))) { @@ -2614,13 +2620,22 @@ namei_ListAFSSubDirs(IHandle_t * dirIH, continue; /* Now we've got to the actual data */ - snprintf(path3, sizeof(path3), "%s" OS_DIRSEP "%s", - path2, dp2->d_name); + code = snprintf(path3, sizeof(path3), "%s" OS_DIRSEP "%s", + path2, dp2->d_name); #else /* Now we've got to the actual data */ - snprintf(path3, sizeof(path3), "%s" OS_DIRSEP "%s", - path1, dp1->d_name); + code = snprintf(path3, sizeof(path3), "%s" OS_DIRSEP "%s", + path1, dp1->d_name); #endif + if (code < 0 || code >= sizeof(path3)) { + /* error, or truncated */ +#ifndef AFS_NT40_ENV + closedir(dirp2); +#endif + closedir(dirp1); + ret = -1; + goto error; + } dirp3 = opendir(path3); if (dirp3) { while ((dp3 = readdir(dirp3))) { @@ -3128,8 +3143,13 @@ namei_ConvertROtoRWvolume(char *pname, VolumeId volumeId) t_ih.ih_dev = ih->ih_dev; t_ih.ih_vid = ih->ih_vid; - snprintf(oldpath, sizeof oldpath, "%s" OS_DIRSEP "%s", dir_name, - infoName); + code = snprintf(oldpath, sizeof oldpath, "%s" OS_DIRSEP "%s", dir_name, + infoName); + if (code < 0 || code >= sizeof(oldpath)) { + /* error, or truncated */ + code = -1; + goto done; + } fd = OS_OPEN(oldpath, O_RDWR, 0); if (fd == INVALID_FD) { Log("1 namei_ConvertROtoRWvolume: could not open RO info file: %s\n", @@ -3159,8 +3179,13 @@ namei_ConvertROtoRWvolume(char *pname, VolumeId volumeId) t_ih.ih_ino = namei_MakeSpecIno(ih->ih_vid, VI_SMALLINDEX); namei_HandleToName(&n, &t_ih); - snprintf(newpath, sizeof newpath, "%s" OS_DIRSEP "%s", dir_name, - smallName); + code = snprintf(newpath, sizeof newpath, "%s" OS_DIRSEP "%s", dir_name, + smallName); + if (code < 0 || code >= sizeof(newpath)) { + /* error, or truncated */ + code = -1; + goto done; + } fd = OS_OPEN(newpath, O_RDWR, 0); if (fd == INVALID_FD) { Log("1 namei_ConvertROtoRWvolume: could not open SmallIndex file: %s\n", newpath); @@ -3182,8 +3207,13 @@ namei_ConvertROtoRWvolume(char *pname, VolumeId volumeId) t_ih.ih_ino = namei_MakeSpecIno(ih->ih_vid, VI_LARGEINDEX); namei_HandleToName(&n, &t_ih); - snprintf(newpath, sizeof newpath, "%s" OS_DIRSEP "%s", dir_name, - largeName); + code = snprintf(newpath, sizeof newpath, "%s" OS_DIRSEP "%s", dir_name, + largeName); + if (code < 0 || code >= sizeof(newpath)) { + /* error, or truncated */ + code = -1; + goto done; + } fd = OS_OPEN(newpath, O_RDWR, 0); if (fd == INVALID_FD) { Log("1 namei_ConvertROtoRWvolume: could not open LargeIndex file: %s\n", newpath);