Chromium Code Reviews| Index: experimental/webtry/main.cpp |
| diff --git a/experimental/webtry/main.cpp b/experimental/webtry/main.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b5d0a8834527c9fb6d5724e22d75d1749a39f5fb |
| --- /dev/null |
| +++ b/experimental/webtry/main.cpp |
| @@ -0,0 +1,113 @@ |
| +#include <sys/time.h> |
| +#include <sys/resource.h> |
| + |
| +#include "SkCanvas.h" |
| +#include "SkCommandLineFlags.h" |
| +#include "SkData.h" |
| +#include "SkForceLinking.h" |
| +#include "SkGraphics.h" |
| +#include "SkImageEncoder.h" |
| +#include "SkImageInfo.h" |
| +#include "SkStream.h" |
| +#include "SkSurface.h" |
| + |
| +#include "seccomp_bpf.h" |
| + |
| +__SK_FORCE_IMAGE_DECODER_LINKING; |
| + |
| +DEFINE_string(out, "", "Filename of the PNG to write to."); |
| + |
| +static bool install_syscall_filter(void) { |
|
mtklein
2014/04/09 15:03:00
Just FYI, you can legally write () instead of (voi
|
| + struct sock_filter filter[] = { |
| + /* Grab the system call number. */ |
| + EXAMINE_SYSCALL, |
| + /* List allowed syscalls. */ |
| + ALLOW_SYSCALL(exit_group), |
| + ALLOW_SYSCALL(exit), |
| + ALLOW_SYSCALL(fstat), |
| + ALLOW_SYSCALL(read), |
| + ALLOW_SYSCALL(write), |
| + ALLOW_SYSCALL(close), |
| + ALLOW_SYSCALL(mmap), |
| + ALLOW_SYSCALL(munmap), |
| + ALLOW_SYSCALL(brk), |
| + KILL_PROCESS, |
| + }; |
| + struct sock_fprog prog = { |
| + SK_ARRAY_COUNT(filter), |
| + filter, |
| + }; |
| + |
| + // Lock down the app so that it can't get new privs, such as setuid. |
| + // Calling this is a requirement for an unpriviledged process to use mode |
| + // 2 seccomp filters, ala SECCOMP_MODE_FILTER, otherwise we'd have to be |
| + // root. |
| + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { |
| + perror("prctl(NO_NEW_PRIVS)"); |
| + goto failed; |
| + } |
| + // Now call seccomp and restrict the system calls that can be made to only |
| + // the ones in the provided filter list. |
| + if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { |
| + perror("prctl(SECCOMP)"); |
| + goto failed; |
| + } |
| + return true; |
| + |
| +failed: |
| + 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.
|
| + fprintf(stderr, "SECCOMP_FILTER is not available. :(\n"); |
| + return false; |
| +} |
| + |
| +static void setLimits() { |
| + struct rlimit n; |
| + |
| + // Limit to 5 seconds of CPU. |
| + n.rlim_cur = 5; |
| + n.rlim_max = 5; |
| + if (setrlimit(RLIMIT_CPU, &n)) { |
| + perror("setrlimit(RLIMIT_CPU)"); |
| + } |
| + |
| + // Limit to 50M of Address space. |
| + n.rlim_cur = 50000000; |
| + n.rlim_max = 50000000; |
| + if (setrlimit(RLIMIT_AS, &n)) { |
| + perror("setrlimit(RLIMIT_CPU)"); |
| + } |
| +} |
| + |
| +extern void draw(SkCanvas* canvas); |
| + |
| +int main(int argc, char** argv) { |
| + SkCommandLineFlags::Parse(argc, argv); |
| + SkAutoGraphics init; |
| + |
| + if (FLAGS_out.count() == 0) { |
| + perror("The --out flag must have an argument."); |
| + return 1; |
| + } |
| + SkFILEWStream stream(FLAGS_out[0]); |
| + |
| + SkImageInfo info = SkImageInfo::MakeN32(300, 300, kPremul_SkAlphaType); |
| + SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info)); |
| + SkCanvas* canvas = surface->getCanvas(); |
| + |
| + setLimits(); |
| + |
| + if (!install_syscall_filter()) { |
| + return 1; |
| + } |
| + |
| + draw(canvas); |
| + |
| + // Write out the image as a PNG. |
| + SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); |
| + SkAutoTUnref<SkData> data(image->encode(SkImageEncoder::kPNG_Type, 100)); |
| + if (NULL == data.get()) { |
| + printf("Failed to encode\n"); |
| + exit(1); |
| + } |
| + stream.write(data->data(), data->size()); |
| +} |