From 37f521494d785e7311008bc6553187cb91bddb18 Mon Sep 17 00:00:00 2001 From: IgnorantGuru Date: Sun, 3 Jun 2012 09:29:28 -0600 Subject: [PATCH] replace realpath.c with canonicalize.c --- src/Makefile.am | 2 +- src/Makefile.in | 26 ++--- src/{realpath.c => canonicalize.c} | 160 ++++++++++++++++++----------- src/canonicalize.h | 10 ++ src/device-info.h | 2 - src/realpath.h | 20 ---- src/udevil.c | 17 +-- 7 files changed, 134 insertions(+), 103 deletions(-) rename src/{realpath.c => canonicalize.c} (56%) create mode 100644 src/canonicalize.h delete mode 100644 src/realpath.h diff --git a/src/Makefile.am b/src/Makefile.am index fdedb85..707420a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ noinst_PROGRAMS = udevil -udevil_SOURCES = udevil.c device-info.c realpath.c +udevil_SOURCES = udevil.c device-info.c canonicalize.c bin_SCRIPTS = devmon diff --git a/src/Makefile.in b/src/Makefile.in index dbccd78..2bf7a22 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -65,7 +65,7 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am_udevil_OBJECTS = udevil-udevil.$(OBJEXT) \ - udevil-device-info.$(OBJEXT) udevil-realpath.$(OBJEXT) + udevil-device-info.$(OBJEXT) udevil-canonicalize.$(OBJEXT) udevil_OBJECTS = $(am_udevil_OBJECTS) am__DEPENDENCIES_1 = udevil_DEPENDENCIES = $(am__DEPENDENCIES_1) @@ -276,7 +276,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -udevil_SOURCES = udevil.c device-info.c realpath.c +udevil_SOURCES = udevil.c device-info.c canonicalize.c bin_SCRIPTS = devmon INSTALL_DIR = $(DESTDIR)/$(prefix)/bin INSTALL_SRC = $(top_builddir)/src @@ -378,8 +378,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udevil-canonicalize.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udevil-device-info.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udevil-realpath.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udevil-udevil.Po@am__quote@ .c.o: @@ -431,19 +431,19 @@ udevil-device-info.obj: device-info.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -c -o udevil-device-info.obj `if test -f 'device-info.c'; then $(CYGPATH_W) 'device-info.c'; else $(CYGPATH_W) '$(srcdir)/device-info.c'; fi` -udevil-realpath.o: realpath.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -MT udevil-realpath.o -MD -MP -MF $(DEPDIR)/udevil-realpath.Tpo -c -o udevil-realpath.o `test -f 'realpath.c' || echo '$(srcdir)/'`realpath.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/udevil-realpath.Tpo $(DEPDIR)/udevil-realpath.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='realpath.c' object='udevil-realpath.o' libtool=no @AMDEPBACKSLASH@ +udevil-canonicalize.o: canonicalize.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -MT udevil-canonicalize.o -MD -MP -MF $(DEPDIR)/udevil-canonicalize.Tpo -c -o udevil-canonicalize.o `test -f 'canonicalize.c' || echo '$(srcdir)/'`canonicalize.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/udevil-canonicalize.Tpo $(DEPDIR)/udevil-canonicalize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='canonicalize.c' object='udevil-canonicalize.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -c -o udevil-realpath.o `test -f 'realpath.c' || echo '$(srcdir)/'`realpath.c +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -c -o udevil-canonicalize.o `test -f 'canonicalize.c' || echo '$(srcdir)/'`canonicalize.c -udevil-realpath.obj: realpath.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -MT udevil-realpath.obj -MD -MP -MF $(DEPDIR)/udevil-realpath.Tpo -c -o udevil-realpath.obj `if test -f 'realpath.c'; then $(CYGPATH_W) 'realpath.c'; else $(CYGPATH_W) '$(srcdir)/realpath.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/udevil-realpath.Tpo $(DEPDIR)/udevil-realpath.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='realpath.c' object='udevil-realpath.obj' libtool=no @AMDEPBACKSLASH@ +udevil-canonicalize.obj: canonicalize.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -MT udevil-canonicalize.obj -MD -MP -MF $(DEPDIR)/udevil-canonicalize.Tpo -c -o udevil-canonicalize.obj `if test -f 'canonicalize.c'; then $(CYGPATH_W) 'canonicalize.c'; else $(CYGPATH_W) '$(srcdir)/canonicalize.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/udevil-canonicalize.Tpo $(DEPDIR)/udevil-canonicalize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='canonicalize.c' object='udevil-canonicalize.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -c -o udevil-realpath.obj `if test -f 'realpath.c'; then $(CYGPATH_W) 'realpath.c'; else $(CYGPATH_W) '$(srcdir)/realpath.c'; fi` +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -c -o udevil-canonicalize.obj `if test -f 'canonicalize.c'; then $(CYGPATH_W) 'canonicalize.c'; else $(CYGPATH_W) '$(srcdir)/canonicalize.c'; fi` mostlyclean-libtool: -rm -f *.lo diff --git a/src/realpath.c b/src/canonicalize.c similarity index 56% rename from src/realpath.c rename to src/canonicalize.c index bdbfcaf..ab32c10 100644 --- a/src/realpath.c +++ b/src/canonicalize.c @@ -1,5 +1,5 @@ /* - * realpath.c -- canonicalize pathname by removing symlinks + * canonicalize.c -- canonicalize pathname by removing symlinks * Copyright (C) 1993 Rick Sladkey * * This program is free software; you can redistribute it and/or modify @@ -11,53 +11,30 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library Public License for more details. + * */ -#define resolve_symlinks - /* * This routine is part of libc. We include it nevertheless, * since the libc version has some security flaws. + * + * TODO: use canonicalize_file_name() when exist in glibc */ - -/* - This file was taken from the source code for mount. -*/ - -#include /* for PATH_MAX */ -#include -#include -#include -#include #include -#include "realpath.h" -#include +#include +#include +#include +#include +#include -#define MAX_READLINKS 32 +#include "canonicalize.h" +#ifndef MAXSYMLINKS +# define MAXSYMLINKS 256 +#endif -/* A small malloc extension, from mount */ - -void * -xmalloc (size_t size) { - void *t; - - if (size == 0) - return NULL; - - t = malloc(size); - if(! t) - { - fprintf(stderr, _("Error: out of memory\n")); - exit(5); /* Memory allocation error */ - } - return t; -} - - - -char * -private_realpath(const char *path, char *resolved_path, int maxreslth) { +static char * +myrealpath(const char *path, char *resolved_path, int maxreslth) { int readlinks = 0; char *npath; char link_path[PATH_MAX+1]; @@ -68,17 +45,14 @@ private_realpath(const char *path, char *resolved_path, int maxreslth) { /* If it's a relative pathname use getcwd for starters. */ if (*path != '/') { - if (!getcwd(npath, maxreslth-2)) { - //g_warning("realpath: could not get current directory: %s", - // strerror(errno) ); - return NULL; - } - npath += strlen(npath); - if (npath[-1] != '/') - *npath++ = '/'; + if (!getcwd(npath, maxreslth-2)) + return NULL; + npath += strlen(npath); + if (npath[-1] != '/') + *npath++ = '/'; } else { - *npath++ = '/'; - path++; + *npath++ = '/'; + path++; } /* Expand each slash-separated pathname component. */ @@ -112,7 +86,7 @@ private_realpath(const char *path, char *resolved_path, int maxreslth) { } /* Protect against infinite loops. */ - if (readlinks++ > MAX_READLINKS) { + if (readlinks++ > MAXSYMLINKS) { errno = ELOOP; goto err; } @@ -125,8 +99,8 @@ private_realpath(const char *path, char *resolved_path, int maxreslth) { if (errno != EINVAL) goto err; } else { -#ifdef resolve_symlinks /* Richard Gooch dislikes sl resolution */ int m; + char *newbuf; /* Note: readlink doesn't add the null byte. */ link_path[n] = '\0'; @@ -140,13 +114,13 @@ private_realpath(const char *path, char *resolved_path, int maxreslth) { /* Insert symlink contents into path. */ m = strlen(path); - if (buf) - free(buf); - buf = xmalloc(m + n + 1); - memcpy(buf, link_path, n); - memcpy(buf + n, path, m + 1); - path = buf; -#endif + newbuf = malloc(m + n + 1); + if (!newbuf) + goto err; + memcpy(newbuf, link_path, n); + memcpy(newbuf + n, path, m + 1); + free(buf); + path = buf = newbuf; } *npath++ = '/'; } @@ -156,12 +130,76 @@ private_realpath(const char *path, char *resolved_path, int maxreslth) { /* Make sure it's null terminated. */ *npath = '\0'; - if (buf) - free(buf); + free(buf); return resolved_path; err: - if (buf) - free(buf); + free(buf); return NULL; } + +/* + * Converts private "dm-N" names to "/dev/mapper/" + * + * Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs + * provides the real DM device names in /sys/block//dm/name + */ +char * +canonicalize_dm_name(const char *ptname) +{ + FILE *f; + size_t sz; + char path[256], name[256], *res = NULL; + + snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname); + if (!(f = fopen(path, "r"))) + return NULL; + + /* read "\n" from sysfs */ + if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) { + name[sz - 1] = '\0'; + snprintf(path, sizeof(path), "/dev/mapper/%s", name); + res = strdup(path); + } + fclose(f); + return res; +} + +char * +canonicalize_path(const char *path) +{ + char canonical[PATH_MAX+2]; + char *p; + + if (path == NULL) + return NULL; + + if (!myrealpath(path, canonical, PATH_MAX+1)) + return strdup(path); + + + p = strrchr(canonical, '/'); + if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) { + p = canonicalize_dm_name(p+1); + if (p) + return p; + } + + return strdup(canonical); +} + + +#ifdef TEST_PROGRAM_CANONICALIZE +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "usage: %s \n", argv[0]); + exit(EXIT_FAILURE); + } + + fprintf(stdout, "orig: %s\n", argv[1]); + fprintf(stdout, "real: %s\n", canonicalize_path(argv[1])); + + exit(EXIT_SUCCESS); +} +#endif diff --git a/src/canonicalize.h b/src/canonicalize.h new file mode 100644 index 0000000..cd132e7 --- /dev/null +++ b/src/canonicalize.h @@ -0,0 +1,10 @@ +#ifndef CANONICALIZE_H +#define CANONICALIZE_H + +//#include "c.h" /* for PATH_MAX */ +#include /* for PATH_MAX */ + +extern char *canonicalize_path(const char *path); +extern char *canonicalize_dm_name(const char *ptname); + +#endif /* CANONICALIZE_H */ diff --git a/src/device-info.h b/src/device-info.h index 40c2396..6cb3683 100644 --- a/src/device-info.h +++ b/src/device-info.h @@ -18,8 +18,6 @@ // intltool #include -// use mount's realpath -#include "realpath.h" typedef struct device_t { diff --git a/src/realpath.h b/src/realpath.h deleted file mode 100644 index c16e21f..0000000 --- a/src/realpath.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _REAL_PATH_H -#define _REAL_PATH_H -/* a safer implementation of realpath. */ -extern char *private_realpath(const char *path, char *resolved_path, int m); - -#ifndef PATH_MAX -#define PATH_MAX 8192 -#endif - -/* And a macro to replace current calls, assuming that the buffer - size is PATH_MAX -*/ - -#ifdef realpath -#undef realpath -#endif -#define realpath(a,b) private_realpath(a,b,PATH_MAX) - - -#endif diff --git a/src/udevil.c b/src/udevil.c index 06708ca..3700004 100644 --- a/src/udevil.c +++ b/src/udevil.c @@ -51,8 +51,8 @@ // intltool #include -// use mount's realpath -#include "realpath.h" +// use mount's more secure version of realpath +#include "canonicalize.h" #include "device-info.h" @@ -1361,8 +1361,6 @@ static char* get_ip( const char* hostname ) static gboolean get_realpath( char** path ) { - char res_path[PATH_MAX]; - if ( !path || !*path || !( *path && *path[0] != '\0' ) ) { if ( path ) @@ -1373,10 +1371,17 @@ static gboolean get_realpath( char** path ) return FALSE; } - if ( realpath( *path, res_path ) && res_path[0] == '/' ) + char* res = canonicalize_path( *path ); + if ( res && res[0] != '/' ) + { + g_free( res ); + res = NULL; + } + + if ( res ) { g_free( *path ); - *path = g_strdup( res_path ); + *path = res; return TRUE; } else