mk_hugefiles: simplify get_partition_start()
PATCH 1/1 mk_hugefiles: simplify get_partition_start()
From: Eric Biggers <[email protected]>
search_sysfs_block() is causing -Wformat-truncation warnings. These could be fixed by checking the return value of snprintf(), instead of doing buggy checks like 'strlen(p_de->d_name) > SYSFS_PATH_LEN - strlen(path) - 32', which has an integer underflow bug.
However, the only purpose of search_sysfs_block() is to find the sysfs directory for a block device by device number. That can trivially be done using /sys/dev/block/$major:$minor. So just do that instead. Also make get_partition_start() explicitly Linux-only, as it has never worked anywhere else.
Signed-off-by Eric Biggers <[email protected]>
--- misc/mk_hugefiles.c | 131 +++----------------------------------------- 1 file changed, 7 insertions(+), 124 deletions(-)
misc/mk_hugefiles.c +7 -124
@@ -2,13 +2,8 @@* mk_hugefiles.c -- create huge files */ -#define _XOPEN_SOURCE 600/* for inclusion of PATH_MAX in Solaris */ -#define _BSD_SOURCE/* for makedev() and major() */ -#define _DEFAULT_SOURCE/* since glibc 2.20 _BSD_SOURCE is deprecated */ -#include "config.h" #include <stdio.h> -#include <stdarg.h> #include <string.h> #include <strings.h> #include <fcntl.h>
@@ -68,141 +63,29 @@ static char *fn_buf;static char *fn_numbuf;int zero_hugefile =1 ; -#define SYSFS_PATH_LEN 300 -typedef char sysfs_path_t [SYSFS_PATH_LEN ]; - -#ifndef HAVE_SNPRINTF -/* -* We are very careful to avoid needing to worry about buffer -* overflows, so we don't really need to use snprintf() except as an -* additional safety check. So if snprintf() is not present, it's -* safe to fall back to vsprintf(). This provides portability since -* vsprintf() is guaranteed by C89, while snprintf() is only -* guaranteed by C99 --- which for example, Microsoft Visual Studio -* has *still* not bothered to implement. :-/ (Not that I expect -* mke2fs to be ported to MS Visual Studio any time soon, but -* libext2fs *does* get built on Microsoft platforms, and we might -* want to move this into libext2fs some day.) -*/ -static int my_snprintf (char *str,size_t size,const char *format, ...) -{ -va_list ap; -int ret; - -va_start (ap, format); - ret =vsprintf (str, format, ap); -va_end (ap); -return ret; -} - -#define snprintf my_snprintf -#endif - -/* -* Fall back to Linux's definitions of makedev and major are needed. -* The search_sysfs_block() function is highly unlikely to work on -* non-Linux systems anyway. -*/ -#ifndef makedev -#define makedev (maj, min) (((maj) << 8) + (min)) -#endif - -static char *search_sysfs_block (dev_t devno,sysfs_path_t ret_path) -{ -struct dirent *de, *p_de; -DIR *dir =NULL , *p_dir =NULL ; -FILE *f; -sysfs_path_t path, p_path; -unsigned int major, minor; -char *ret = ret_path; - - ret_path[0 ] =0 ; -if ((dir =opendir ("/sys/block" )) ==NULL ) -return NULL ; -while ((de =readdir (dir)) !=NULL ) { -if (!strcmp (de->d_name,"." ) || !strcmp (de->d_name,".." ) || -strlen (de->d_name) >sizeof (path)-32 ) -continue ; -snprintf (path,SYSFS_PATH_LEN , -"/sys/block/%s/dev" , de->d_name); - f =fopen (path,"r" ); -if (f && - (fscanf (f,"%u:%u" , &major, &minor) ==2 )) { -fclose (f); f =NULL ; -if (makedev (major, minor) == devno) { -snprintf (ret_path,SYSFS_PATH_LEN , -"/sys/block/%s" , de->d_name); - goto success; - } -#ifdef major -if (major (devno) != major) -continue ; -#endif - } -if (f) -fclose (f); - -snprintf (path,SYSFS_PATH_LEN ,"/sys/block/%s" , de->d_name); - -if (p_dir) -closedir (p_dir); -if ((p_dir =opendir (path)) ==NULL ) -continue ; -while ((p_de =readdir (p_dir)) !=NULL ) { -if (!strcmp (p_de->d_name,"." ) || - !strcmp (p_de->d_name,".." ) || - (strlen (p_de->d_name) > -SYSFS_PATH_LEN -strlen (path) -32 )) -continue ; -snprintf (p_path,SYSFS_PATH_LEN ,"%s/%s/dev" , - path, p_de->d_name); - - f =fopen (p_path,"r" ); -if (f && - (fscanf (f,"%u:%u" , &major, &minor) ==2 ) && - (((major <<8 ) + minor) == devno)) { -fclose (f); -snprintf (ret_path,SYSFS_PATH_LEN ,"%s/%s" , - path, p_de->d_name); - goto success; - } -if (f) -fclose (f); - } - } - ret =NULL ; -success: -if (dir) -closedir (dir); -if (p_dir) -closedir (p_dir); -return ret; -} -static blk64_t get_partition_start (const char *device_name) { +#ifdef __linux__unsigned long long start; -sysfs_path_t path; +char path[128 ];struct stat st;FILE *f; -char *cp;int n;if ((stat (device_name, &st) <0 ) || !S_ISBLK (st.st_mode))return 0 ; - cp =search_sysfs_block (st.st_rdev, path); -if (!cp) -return 0 ; -if (strlen (path) >SYSFS_PATH_LEN -sizeof ("/start" )) -return 0 ; -strcat (path,"/start" ); +sprintf (path,"/sys/dev/block/%d:%d/start" , +major (st.st_rdev),minor (st.st_rdev)); f =fopen (path,"r" );if (!f)return 0 ; n =fscanf (f,"%llu" , &start);fclose (f);return (n ==1 ) ? start :0 ; +#else +return 0 ; +#endif } static errcode_t create_directory(ext2_filsys fs, char *dir,
base-commit: 6695555e50a374f897965300568253f242a0b13b
Signature · 1 line
2.39.0