X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib.c;h=28162b63c044599589068e26e52a71378a2a81d0;hp=56d78b50c2685b125bc2b42b2609ae056b5cb9df;hb=09093d8501628bfba8f4f4b206c48dd3b826237f;hpb=1d7238dc43311c4545883dc1151bf5b142d88c0b diff --git a/lib.c b/lib.c index 56d78b5..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 */ - if (stat (s, &sb) == 0) +#ifdef O_NOFOLLOW + flags = O_RDWR | O_NOFOLLOW; +#else + flags = O_RDWR; +#endif + + 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)); @@ -363,7 +426,8 @@ int safe_open (const char *path, int flags) struct stat osb, nsb; int fd; - if ((fd = open (path, flags, 0600)) < 0) + umask(Umask); + if ((fd = open (path, flags, 0666)) < 0) return fd; /* make sure the file is not symlink */