Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #include <sys/time.h> | |
| 2 #include <sys/resource.h> | |
| 3 | |
| 4 #include "SkCanvas.h" | |
| 5 #include "SkCommandLineFlags.h" | |
| 6 #include "SkData.h" | |
| 7 #include "SkForceLinking.h" | |
| 8 #include "SkGraphics.h" | |
| 9 #include "SkImageEncoder.h" | |
| 10 #include "SkImageInfo.h" | |
| 11 #include "SkStream.h" | |
| 12 #include "SkSurface.h" | |
| 13 | |
| 14 #include "seccomp_bpf.h" | |
| 15 | |
| 16 __SK_FORCE_IMAGE_DECODER_LINKING; | |
| 17 | |
| 18 DEFINE_string(out, "", "Filename of the PNG to write to."); | |
| 19 | |
| 20 static bool install_syscall_filter(void) { | |
|
mtklein
2014/04/09 15:03:00
Just FYI, you can legally write () instead of (voi
| |
| 21 struct sock_filter filter[] = { | |
| 22 /* Grab the system call number. */ | |
| 23 EXAMINE_SYSCALL, | |
| 24 /* List allowed syscalls. */ | |
| 25 ALLOW_SYSCALL(exit_group), | |
| 26 ALLOW_SYSCALL(exit), | |
| 27 ALLOW_SYSCALL(fstat), | |
| 28 ALLOW_SYSCALL(read), | |
| 29 ALLOW_SYSCALL(write), | |
| 30 ALLOW_SYSCALL(close), | |
| 31 ALLOW_SYSCALL(mmap), | |
| 32 ALLOW_SYSCALL(munmap), | |
| 33 ALLOW_SYSCALL(brk), | |
| 34 KILL_PROCESS, | |
| 35 }; | |
| 36 struct sock_fprog prog = { | |
| 37 SK_ARRAY_COUNT(filter), | |
| 38 filter, | |
| 39 }; | |
| 40 | |
| 41 // Lock down the app so that it can't get new privs, such as setuid. | |
| 42 // Calling this is a requirement for an unpriviledged process to use mode | |
| 43 // 2 seccomp filters, ala SECCOMP_MODE_FILTER, otherwise we'd have to be | |
| 44 // root. | |
| 45 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { | |
| 46 perror("prctl(NO_NEW_PRIVS)"); | |
| 47 goto failed; | |
| 48 } | |
| 49 // Now call seccomp and restrict the system calls that can be made to only | |
| 50 // the ones in the provided filter list. | |
| 51 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { | |
| 52 perror("prctl(SECCOMP)"); | |
| 53 goto failed; | |
| 54 } | |
| 55 return true; | |
| 56 | |
| 57 failed: | |
| 58 if (errno == EINVAL) | |
|
mtklein
2014/04/09 15:03:00
Wrap with {}? I've seen too many
if (errno ==
jcgregorio
2014/04/09 15:23:07
Done.
| |
| 59 fprintf(stderr, "SECCOMP_FILTER is not available. :(\n"); | |
| 60 return false; | |
| 61 } | |
| 62 | |
| 63 static void setLimits() { | |
| 64 struct rlimit n; | |
| 65 | |
| 66 // Limit to 5 seconds of CPU. | |
| 67 n.rlim_cur = 5; | |
| 68 n.rlim_max = 5; | |
| 69 if (setrlimit(RLIMIT_CPU, &n)) { | |
| 70 perror("setrlimit(RLIMIT_CPU)"); | |
| 71 } | |
| 72 | |
| 73 // Limit to 50M of Address space. | |
| 74 n.rlim_cur = 50000000; | |
| 75 n.rlim_max = 50000000; | |
| 76 if (setrlimit(RLIMIT_AS, &n)) { | |
| 77 perror("setrlimit(RLIMIT_CPU)"); | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 extern void draw(SkCanvas* canvas); | |
| 82 | |
| 83 int main(int argc, char** argv) { | |
| 84 SkCommandLineFlags::Parse(argc, argv); | |
| 85 SkAutoGraphics init; | |
| 86 | |
| 87 if (FLAGS_out.count() == 0) { | |
| 88 perror("The --out flag must have an argument."); | |
| 89 return 1; | |
| 90 } | |
| 91 SkFILEWStream stream(FLAGS_out[0]); | |
| 92 | |
| 93 SkImageInfo info = SkImageInfo::MakeN32(300, 300, kPremul_SkAlphaType); | |
| 94 SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info)); | |
| 95 SkCanvas* canvas = surface->getCanvas(); | |
| 96 | |
| 97 setLimits(); | |
| 98 | |
| 99 if (!install_syscall_filter()) { | |
| 100 return 1; | |
| 101 } | |
| 102 | |
| 103 draw(canvas); | |
| 104 | |
| 105 // Write out the image as a PNG. | |
| 106 SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); | |
| 107 SkAutoTUnref<SkData> data(image->encode(SkImageEncoder::kPNG_Type, 100)); | |
| 108 if (NULL == data.get()) { | |
| 109 printf("Failed to encode\n"); | |
| 110 exit(1); | |
| 111 } | |
| 112 stream.write(data->data(), data->size()); | |
| 113 } | |
| OLD | NEW |