X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib.c;h=fdbfb7475897e4ec4b4dde63ffb154e2a86a156c;hp=33d57571e3b8e9d07d89137bdf50096c053a559a;hb=2c311482c97a1b222ef240dae3383ce2e11a0c23;hpb=6833ce8bdca2d64e14485118f2a4417b7e1cb1b1 diff --git a/lib.c b/lib.c index 33d5757..fdbfb74 100644 --- a/lib.c +++ b/lib.c @@ -38,6 +38,8 @@ #include "lib.h" +extern short Umask; + void mutt_nocurses_error (const char *fmt, ...) { va_list ap; @@ -153,6 +155,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); @@ -181,13 +222,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)); @@ -361,7 +422,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 */ @@ -381,6 +443,8 @@ int safe_open (const char *path, int flags) */ FILE *safe_fopen (const char *path, const char *mode) { + /* first set the current umask */ + umask(Umask); if (mode[0] == 'w') { int fd;