X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib.c;h=28162b63c044599589068e26e52a71378a2a81d0;hp=e5200c917ddcd299bf7f183ecab2b825ca208f56;hb=09093d8501628bfba8f4f4b206c48dd3b826237f;hpb=68a299bc56c990b4833db762e43ce0021d323d25 diff --git a/lib.c b/lib.c index e5200c9..28162b6 100644 --- a/lib.c +++ b/lib.c @@ -26,6 +26,10 @@ * some of our "standard" functions in external programs, too. */ +#if HAVE_CONFIG_H +# include "config.h" +#endif + #include #include #include @@ -155,6 +159,45 @@ char *safe_strdup (const char *s) return (p); } +char *safe_strcat (char *d, size_t l, const char *s) +{ + char *p = d; + + if (!l) + return d; + + l--; /* Space for the trailing '\0'. */ + + for (; *d && l; l--) + d++; + for (; *s && l; l--) + *d++ = *s++; + + *d = '\0'; + + return p; +} + +char *safe_strncat (char *d, size_t l, const char *s, size_t sl) +{ + char *p = d; + + if (!l) + return d; + + l--; /* Space for the trailing '\0'. */ + + for (; *d && l; l--) + d++; + for (; *s && l && sl; l--, sl--) + *d++ = *s++; + + *d = '\0'; + + return p; +} + + void mutt_str_replace (char **p, const char *s) { FREE (p); @@ -183,13 +226,33 @@ char *mutt_strlower (char *s) void mutt_unlink (const char *s) { + int fd; + int flags; FILE *f; - struct stat sb; + struct stat sb, sb2; char buf[2048]; + + /* Defend against symlink attacks */ + +#ifdef O_NOFOLLOW + flags = O_RDWR | O_NOFOLLOW; +#else + flags = O_RDWR; +#endif - if (stat (s, &sb) == 0) + if (lstat (s, &sb) == 0 && S_ISREG(sb.st_mode)) { - if ((f = fopen (s, "r+"))) + if ((fd = open (s, flags)) < 0) + return; + + if ((fstat (fd, &sb2) != 0) || !S_ISREG (sb2.st_mode) + || (sb.st_dev != sb2.st_dev) || (sb.st_ino != sb2.st_ino)) + { + close (fd); + return; + } + + if ((f = fdopen (fd, "r+"))) { unlink (s); memset (buf, 0, sizeof (buf));