diff options
| author | Chong Yidong | 2010-04-02 11:26:24 -0400 |
|---|---|---|
| committer | Chong Yidong | 2010-04-02 11:26:24 -0400 |
| commit | 51a91f9da64f25b68a1d3f752df6193c49c9b4fc (patch) | |
| tree | 6cfd08f009874dc66e3575a111829cc4297fb012 /lib-src | |
| parent | a9ae306fe491f75b43a9c70c8909c138c36765d5 (diff) | |
| download | emacs-51a91f9da64f25b68a1d3f752df6193c49c9b4fc.tar.gz emacs-51a91f9da64f25b68a1d3f752df6193c49c9b4fc.zip | |
Fix permissions handling (CVE-2010-0825).
* movemail.c (main): Check return values of setuid. Avoid
possibility of symlink attack when movemail is setgid mail
(CVE-2010-0825).
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 ad7ce6da3c2..11e603eab0f 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-04-02 Dan Nicolaescu <dann@ics.uci.edu> | 7 | 2010-04-02 Dan Nicolaescu <dann@ics.uci.edu> |
| 2 | 8 | ||
| 3 | Remove extern errno declarations. | 9 | Remove extern errno declarations. |
diff --git a/lib-src/movemail.c b/lib-src/movemail.c index a887eb216ac..ea307241351 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c | |||
| @@ -194,6 +194,9 @@ main (argc, argv) | |||
| 194 | # define ARGSTR "p" | 194 | # define ARGSTR "p" |
| 195 | #endif /* MAIL_USE_POP */ | 195 | #endif /* MAIL_USE_POP */ |
| 196 | 196 | ||
| 197 | uid_t real_gid = getgid(); | ||
| 198 | uid_t priv_gid = getegid(); | ||
| 199 | |||
| 197 | #ifdef WINDOWSNT | 200 | #ifdef WINDOWSNT |
| 198 | /* Ensure all file i/o is in binary mode. */ | 201 | /* Ensure all file i/o is in binary mode. */ |
| 199 | _fmode = _O_BINARY; | 202 | _fmode = _O_BINARY; |
| @@ -244,25 +247,6 @@ main (argc, argv) | |||
| 244 | if (*outname == 0) | 247 | if (*outname == 0) |
| 245 | fatal ("Destination file name is empty", 0, 0); | 248 | fatal ("Destination file name is empty", 0, 0); |
| 246 | 249 | ||
| 247 | /* Check access to output file. */ | ||
| 248 | if (access (outname, F_OK) == 0 && access (outname, W_OK) != 0) | ||
| 249 | pfatal_with_name (outname); | ||
| 250 | |||
| 251 | /* Also check that outname's directory is writable to the real uid. */ | ||
| 252 | { | ||
| 253 | char *buf = (char *) xmalloc (strlen (outname) + 1); | ||
| 254 | char *p; | ||
| 255 | strcpy (buf, outname); | ||
| 256 | p = buf + strlen (buf); | ||
| 257 | while (p > buf && !IS_DIRECTORY_SEP (p[-1])) | ||
| 258 | *--p = 0; | ||
| 259 | if (p == buf) | ||
| 260 | *p++ = '.'; | ||
| 261 | if (access (buf, W_OK) != 0) | ||
| 262 | pfatal_with_name (buf); | ||
| 263 | free (buf); | ||
| 264 | } | ||
| 265 | |||
| 266 | #ifdef MAIL_USE_POP | 250 | #ifdef MAIL_USE_POP |
| 267 | if (!strncmp (inname, "po:", 3)) | 251 | if (!strncmp (inname, "po:", 3)) |
| 268 | { | 252 | { |
| @@ -274,15 +258,12 @@ main (argc, argv) | |||
| 274 | exit (status); | 258 | exit (status); |
| 275 | } | 259 | } |
| 276 | 260 | ||
| 277 | setuid (getuid ()); | 261 | if (setuid (getuid ()) < 0) |
| 262 | fatal ("Failed to drop privileges", 0, 0); | ||
| 263 | |||
| 278 | #endif /* MAIL_USE_POP */ | 264 | #endif /* MAIL_USE_POP */ |
| 279 | 265 | ||
| 280 | #ifndef DISABLE_DIRECT_ACCESS | 266 | #ifndef DISABLE_DIRECT_ACCESS |
| 281 | |||
| 282 | /* Check access to input file. */ | ||
| 283 | if (access (inname, R_OK | W_OK) != 0) | ||
| 284 | pfatal_with_name (inname); | ||
| 285 | |||
| 286 | #ifndef MAIL_USE_MMDF | 267 | #ifndef MAIL_USE_MMDF |
| 287 | #ifndef MAIL_USE_SYSTEM_LOCK | 268 | #ifndef MAIL_USE_SYSTEM_LOCK |
| 288 | #ifdef MAIL_USE_MAILLOCK | 269 | #ifdef MAIL_USE_MAILLOCK |
| @@ -376,7 +357,8 @@ main (argc, argv) | |||
| 376 | time_t touched_lock, now; | 357 | time_t touched_lock, now; |
| 377 | #endif | 358 | #endif |
| 378 | 359 | ||
| 379 | setuid (getuid ()); | 360 | if (setuid (getuid ()) < 0 || setegid (real_gid) < 0) |
| 361 | fatal ("Failed to drop privileges", 0, 0); | ||
| 380 | 362 | ||
| 381 | #ifndef MAIL_USE_MMDF | 363 | #ifndef MAIL_USE_MMDF |
| 382 | #ifdef MAIL_USE_SYSTEM_LOCK | 364 | #ifdef MAIL_USE_SYSTEM_LOCK |
| @@ -402,6 +384,9 @@ main (argc, argv) | |||
| 402 | if (outdesc < 0) | 384 | if (outdesc < 0) |
| 403 | pfatal_with_name (outname); | 385 | pfatal_with_name (outname); |
| 404 | 386 | ||
| 387 | if (setegid (priv_gid) < 0) | ||
| 388 | fatal ("Failed to regain privileges", 0, 0); | ||
| 389 | |||
| 405 | /* This label exists so we can retry locking | 390 | /* This label exists so we can retry locking |
| 406 | after a delay, if it got EAGAIN or EBUSY. */ | 391 | after a delay, if it got EAGAIN or EBUSY. */ |
| 407 | retry_lock: | 392 | retry_lock: |
| @@ -495,6 +480,10 @@ main (argc, argv) | |||
| 495 | pfatal_and_delete (outname); | 480 | pfatal_and_delete (outname); |
| 496 | #endif | 481 | #endif |
| 497 | 482 | ||
| 483 | /* Prevent symlink attacks truncating other users' mailboxes */ | ||
| 484 | if (setegid (real_gid) < 0) | ||
| 485 | fatal ("Failed to drop privileges", 0, 0); | ||
| 486 | |||
| 498 | /* Check to make sure no errors before we zap the inbox. */ | 487 | /* Check to make sure no errors before we zap the inbox. */ |
| 499 | if (close (outdesc) != 0) | 488 | if (close (outdesc) != 0) |
| 500 | pfatal_and_delete (outname); | 489 | pfatal_and_delete (outname); |
| @@ -526,6 +515,10 @@ main (argc, argv) | |||
| 526 | } | 515 | } |
| 527 | #endif /* not MAIL_USE_SYSTEM_LOCK */ | 516 | #endif /* not MAIL_USE_SYSTEM_LOCK */ |
| 528 | 517 | ||
| 518 | /* End of mailbox truncation */ | ||
| 519 | if (setegid (priv_gid) < 0) | ||
| 520 | fatal ("Failed to regain privileges", 0, 0); | ||
| 521 | |||
| 529 | #ifdef MAIL_USE_MAILLOCK | 522 | #ifdef MAIL_USE_MAILLOCK |
| 530 | /* This has to occur in the child, i.e., in the process that | 523 | /* This has to occur in the child, i.e., in the process that |
| 531 | acquired the lock! */ | 524 | acquired the lock! */ |