diff options
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/ChangeLog | 6 | ||||
| -rw-r--r-- | lib-src/movemail.c | 45 |
2 files changed, 25 insertions, 26 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index e97f2672074..826f5c4e6ad 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2010-04-02 Dan Rosenberg <dan.j.rosenberg@gmail.com> (tiny change) | ||
| 2 | |||
| 3 | * movemail.c (main): Check return values of setuid. Avoid | ||
| 4 | possibility of symlink attack when movemail is setgid mail | ||
| 5 | (CVE-2010-0825). | ||
| 6 | |||
| 1 | 2010-03-19 Tetsurou Okazaki <okazaki@be.to> (tiny change) | 7 | 2010-03-19 Tetsurou Okazaki <okazaki@be.to> (tiny change) |
| 2 | 8 | ||
| 3 | * Makefile.in (uninstall): Handle the case where archlibdir does | 9 | * Makefile.in (uninstall): Handle the case where archlibdir does |
diff --git a/lib-src/movemail.c b/lib-src/movemail.c index e0eb4d48b89..ae51df3d39c 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c | |||
| @@ -197,6 +197,9 @@ main (argc, argv) | |||
| 197 | # define ARGSTR "p" | 197 | # define ARGSTR "p" |
| 198 | #endif /* MAIL_USE_POP */ | 198 | #endif /* MAIL_USE_POP */ |
| 199 | 199 | ||
| 200 | uid_t real_gid = getgid(); | ||
| 201 | uid_t priv_gid = getegid(); | ||
| 202 | |||
| 200 | #ifdef WINDOWSNT | 203 | #ifdef WINDOWSNT |
| 201 | /* Ensure all file i/o is in binary mode. */ | 204 | /* Ensure all file i/o is in binary mode. */ |
| 202 | _fmode = _O_BINARY; | 205 | _fmode = _O_BINARY; |
| @@ -247,25 +250,6 @@ main (argc, argv) | |||
| 247 | if (*outname == 0) | 250 | if (*outname == 0) |
| 248 | fatal ("Destination file name is empty", 0, 0); | 251 | fatal ("Destination file name is empty", 0, 0); |
| 249 | 252 | ||
| 250 | /* Check access to output file. */ | ||
| 251 | if (access (outname, F_OK) == 0 && access (outname, W_OK) != 0) | ||
| 252 | pfatal_with_name (outname); | ||
| 253 | |||
| 254 | /* Also check that outname's directory is writable to the real uid. */ | ||
| 255 | { | ||
| 256 | char *buf = (char *) xmalloc (strlen (outname) + 1); | ||
| 257 | char *p; | ||
| 258 | strcpy (buf, outname); | ||
| 259 | p = buf + strlen (buf); | ||
| 260 | while (p > buf && !IS_DIRECTORY_SEP (p[-1])) | ||
| 261 | *--p = 0; | ||
| 262 | if (p == buf) | ||
| 263 | *p++ = '.'; | ||
| 264 | if (access (buf, W_OK) != 0) | ||
| 265 | pfatal_with_name (buf); | ||
| 266 | free (buf); | ||
| 267 | } | ||
| 268 | |||
| 269 | #ifdef MAIL_USE_POP | 253 | #ifdef MAIL_USE_POP |
| 270 | if (!strncmp (inname, "po:", 3)) | 254 | if (!strncmp (inname, "po:", 3)) |
| 271 | { | 255 | { |
| @@ -277,15 +261,12 @@ main (argc, argv) | |||
| 277 | exit (status); | 261 | exit (status); |
| 278 | } | 262 | } |
| 279 | 263 | ||
| 280 | setuid (getuid ()); | 264 | if (setuid (getuid ()) < 0) |
| 265 | fatal ("Failed to drop privileges", 0, 0); | ||
| 266 | |||
| 281 | #endif /* MAIL_USE_POP */ | 267 | #endif /* MAIL_USE_POP */ |
| 282 | 268 | ||
| 283 | #ifndef DISABLE_DIRECT_ACCESS | 269 | #ifndef DISABLE_DIRECT_ACCESS |
| 284 | |||
| 285 | /* Check access to input file. */ | ||
| 286 | if (access (inname, R_OK | W_OK) != 0) | ||
| 287 | pfatal_with_name (inname); | ||
| 288 | |||
| 289 | #ifndef MAIL_USE_MMDF | 270 | #ifndef MAIL_USE_MMDF |
| 290 | #ifndef MAIL_USE_SYSTEM_LOCK | 271 | #ifndef MAIL_USE_SYSTEM_LOCK |
| 291 | #ifdef MAIL_USE_MAILLOCK | 272 | #ifdef MAIL_USE_MAILLOCK |
| @@ -379,7 +360,8 @@ main (argc, argv) | |||
| 379 | time_t touched_lock, now; | 360 | time_t touched_lock, now; |
| 380 | #endif | 361 | #endif |
| 381 | 362 | ||
| 382 | setuid (getuid ()); | 363 | if (setuid (getuid ()) < 0 || setegid (real_gid) < 0) |
| 364 | fatal ("Failed to drop privileges", 0, 0); | ||
| 383 | 365 | ||
| 384 | #ifndef MAIL_USE_MMDF | 366 | #ifndef MAIL_USE_MMDF |
| 385 | #ifdef MAIL_USE_SYSTEM_LOCK | 367 | #ifdef MAIL_USE_SYSTEM_LOCK |
| @@ -405,6 +387,9 @@ main (argc, argv) | |||
| 405 | if (outdesc < 0) | 387 | if (outdesc < 0) |
| 406 | pfatal_with_name (outname); | 388 | pfatal_with_name (outname); |
| 407 | 389 | ||
| 390 | if (setegid (priv_gid) < 0) | ||
| 391 | fatal ("Failed to regain privileges", 0, 0); | ||
| 392 | |||
| 408 | /* This label exists so we can retry locking | 393 | /* This label exists so we can retry locking |
| 409 | after a delay, if it got EAGAIN or EBUSY. */ | 394 | after a delay, if it got EAGAIN or EBUSY. */ |
| 410 | retry_lock: | 395 | retry_lock: |
| @@ -498,6 +483,10 @@ main (argc, argv) | |||
| 498 | pfatal_and_delete (outname); | 483 | pfatal_and_delete (outname); |
| 499 | #endif | 484 | #endif |
| 500 | 485 | ||
| 486 | /* Prevent symlink attacks truncating other users' mailboxes */ | ||
| 487 | if (setegid (real_gid) < 0) | ||
| 488 | fatal ("Failed to drop privileges", 0, 0); | ||
| 489 | |||
| 501 | /* Check to make sure no errors before we zap the inbox. */ | 490 | /* Check to make sure no errors before we zap the inbox. */ |
| 502 | if (close (outdesc) != 0) | 491 | if (close (outdesc) != 0) |
| 503 | pfatal_and_delete (outname); | 492 | pfatal_and_delete (outname); |
| @@ -529,6 +518,10 @@ main (argc, argv) | |||
| 529 | } | 518 | } |
| 530 | #endif /* not MAIL_USE_SYSTEM_LOCK */ | 519 | #endif /* not MAIL_USE_SYSTEM_LOCK */ |
| 531 | 520 | ||
| 521 | /* End of mailbox truncation */ | ||
| 522 | if (setegid (priv_gid) < 0) | ||
| 523 | fatal ("Failed to regain privileges", 0, 0); | ||
| 524 | |||
| 532 | #ifdef MAIL_USE_MAILLOCK | 525 | #ifdef MAIL_USE_MAILLOCK |
| 533 | /* This has to occur in the child, i.e., in the process that | 526 | /* This has to occur in the child, i.e., in the process that |
| 534 | acquired the lock! */ | 527 | acquired the lock! */ |