Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(676)

Side by Side Diff: sandbox/linux/suid/sandbox.c

Issue 10492006: Setuid sandbox API versioning (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase on current state of tree Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sandbox/linux/suid/linux_util.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox 5 // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox
6 6
7 #include "sandbox.h" 7 #include "sandbox.h"
8 8
9 #define _GNU_SOURCE 9 #define _GNU_SOURCE
10 #include <asm/unistd.h> 10 #include <asm/unistd.h>
(...skipping 24 matching lines...) Expand all
35 35
36 #if !defined(CLONE_NEWPID) 36 #if !defined(CLONE_NEWPID)
37 #define CLONE_NEWPID 0x20000000 37 #define CLONE_NEWPID 0x20000000
38 #endif 38 #endif
39 #if !defined(CLONE_NEWNET) 39 #if !defined(CLONE_NEWNET)
40 #define CLONE_NEWNET 0x40000000 40 #define CLONE_NEWNET 0x40000000
41 #endif 41 #endif
42 42
43 static const char kSandboxDescriptorEnvironmentVarName[] = "SBX_D"; 43 static const char kSandboxDescriptorEnvironmentVarName[] = "SBX_D";
44 static const char kSandboxHelperPidEnvironmentVarName[] = "SBX_HELPER_PID"; 44 static const char kSandboxHelperPidEnvironmentVarName[] = "SBX_HELPER_PID";
45
46 // Should be kept in sync with base/linux_util.h
47 static const long kSUIDSandboxApiNumber = 0;
48 static const char kSandboxEnvironmentApiRequest[] = "SBX_CHROME_API_RQ";
49 static const char kSandboxEnvironmentApiProvides[] = "SBX_CHROME_API_PRV";
50
45 // This number must be kept in sync with common/zygote_commands_linux.h 51 // This number must be kept in sync with common/zygote_commands_linux.h
46 static const int kZygoteIdFd = 7; 52 static const int kZygoteIdFd = 7;
47 53
48 // These are the magic byte values which the sandboxed process uses to request 54 // These are the magic byte values which the sandboxed process uses to request
49 // that it be chrooted. 55 // that it be chrooted.
50 static const char kMsgChrootMe = 'C'; 56 static const char kMsgChrootMe = 'C';
51 static const char kMsgChrootSuccessful = 'O'; 57 static const char kMsgChrootSuccessful = 'O';
52 58
53 static bool DropRoot(); 59 static bool DropRoot();
54 60
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 setenv(envvar, value, 1 /* overwrite */); 360 setenv(envvar, value, 1 /* overwrite */);
355 unsetenv(saved_envvar); 361 unsetenv(saved_envvar);
356 } 362 }
357 363
358 free(saved_envvar); 364 free(saved_envvar);
359 } 365 }
360 366
361 return true; 367 return true;
362 } 368 }
363 369
370 bool CheckAndExportApiVersion() {
371 // Check the environment to see if a specific API version was requested.
372 // assume version 0 if none.
373 long api_number = -1;
374 char *api_string = getenv(kSandboxEnvironmentApiRequest);
375 if (!api_string) {
376 api_number = 0;
377 } else {
378 errno = 0;
379 char* endptr = NULL;
380 api_number = strtol(api_string, &endptr, 10);
381 if (!endptr || *endptr || errno != 0)
382 return false;
383 }
384
385 // Warn only for now.
386 if (api_number != kSUIDSandboxApiNumber) {
387 fprintf(stderr, "The setuid sandbox provides API version %ld, "
388 "but you need %ld\n"
389 "Please read "
390 "https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment."
391 "\n\n",
392 kSUIDSandboxApiNumber,
393 api_number);
394 }
395
396 // Export our version so that the sandboxed process can verify it did not
397 // use an old sandbox.
398 char version_string[64];
399 snprintf(version_string, sizeof(version_string), "%ld",
400 kSUIDSandboxApiNumber);
401 if (setenv(kSandboxEnvironmentApiProvides, version_string, 1)) {
402 perror("setenv");
403 return false;
404 }
405
406 return true;
407 }
408
364 int main(int argc, char **argv) { 409 int main(int argc, char **argv) {
365 if (argc <= 1) { 410 if (argc <= 1) {
366 if (argc == 0) { 411 if (argc <= 0) {
367 return 1; 412 return 1;
368 } 413 }
369 414
370 fprintf(stderr, "Usage: %s <renderer process> <args...>\n", argv[0]); 415 fprintf(stderr, "Usage: %s <renderer process> <args...>\n", argv[0]);
371 return 1; 416 return 1;
372 } 417 }
373 418
419 // Allow someone to query our API version
420 if (argc == 2 && 0 == strcmp(argv[1], kSuidSandboxGetApiSwitch)) {
421 printf("%ld\n", kSUIDSandboxApiNumber);
422 return 0;
423 }
424
374 // In the SUID sandbox, if we succeed in calling MoveToNewNamespaces() 425 // In the SUID sandbox, if we succeed in calling MoveToNewNamespaces()
375 // below, then the zygote and all the renderers are in an alternate PID 426 // below, then the zygote and all the renderers are in an alternate PID
376 // namespace and do not know their real PIDs. As such, they report the wrong 427 // namespace and do not know their real PIDs. As such, they report the wrong
377 // PIDs to the task manager. 428 // PIDs to the task manager.
378 // 429 //
379 // To fix this, when the zygote spawns a new renderer, it gives the renderer 430 // To fix this, when the zygote spawns a new renderer, it gives the renderer
380 // a dummy socket, which has a unique inode number. Then it asks the sandbox 431 // a dummy socket, which has a unique inode number. Then it asks the sandbox
381 // host to find the PID of the process holding that fd by searching /proc. 432 // host to find the PID of the process holding that fd by searching /proc.
382 // 433 //
383 // Since the zygote and renderers are all spawned by this setuid executable, 434 // Since the zygote and renderers are all spawned by this setuid executable,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 if (argc == 3 && (0 == strcmp(argv[1], kAdjustLowMemMarginSwitch))) { 470 if (argc == 3 && (0 == strcmp(argv[1], kAdjustLowMemMarginSwitch))) {
420 char* endptr = NULL; 471 char* endptr = NULL;
421 errno = 0; 472 errno = 0;
422 unsigned long margin_mb = strtoul(argv[2], &endptr, 10); 473 unsigned long margin_mb = strtoul(argv[2], &endptr, 10);
423 if (!endptr || *endptr || errno != 0) 474 if (!endptr || *endptr || errno != 0)
424 return 1; 475 return 1;
425 return AdjustLowMemoryMargin(margin_mb); 476 return AdjustLowMemoryMargin(margin_mb);
426 } 477 }
427 #endif 478 #endif
428 479
480 // Protect the core setuid sandbox functionality with an API version
481 if (!CheckAndExportApiVersion()) {
482 return 1;
483 }
484
429 if (!MoveToNewNamespaces()) 485 if (!MoveToNewNamespaces())
430 return 1; 486 return 1;
431 if (!SpawnChrootHelper()) 487 if (!SpawnChrootHelper())
432 return 1; 488 return 1;
433 if (!DropRoot()) 489 if (!DropRoot())
434 return 1; 490 return 1;
435 if (!SetupChildEnvironment()) 491 if (!SetupChildEnvironment())
436 return 1; 492 return 1;
437 493
438 execv(argv[1], &argv[1]); 494 execv(argv[1], &argv[1]);
439 FatalError("execv failed"); 495 FatalError("execv failed");
440 496
441 return 1; 497 return 1;
442 } 498 }
OLDNEW
« no previous file with comments | « sandbox/linux/suid/linux_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698