Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use PCRE to speed up file system jail #424

Closed
wants to merge 5 commits into from
Closed

Use PCRE to speed up file system jail #424

wants to merge 5 commits into from

Conversation

quantum5
Copy link
Member

@quantum5 quantum5 commented Apr 10, 2019

To do:

  • add basic PCRE support for open-like system calls
  • properly handle relative paths (relative to /proc/$pid/cwd)
  • add support for openat-like system calls with AT_FDCWD
  • add support for openat-like system calls with arbitrary fds

@codecov-io
Copy link

codecov-io commented Apr 10, 2019

Codecov Report

Merging #424 into master will decrease coverage by 19.79%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #424      +/-   ##
==========================================
- Coverage   75.78%   55.98%   -19.8%     
==========================================
  Files         130      130              
  Lines        4790     4796       +6     
==========================================
- Hits         3630     2685     -945     
- Misses       1160     2111     +951
Impacted Files Coverage Δ
dmoj/cptbox/handlers.py 100% <100%> (ø) ⬆️
dmoj/cptbox/chroot.py 86.56% <100%> (+0.41%) ⬆️
dmoj/cptbox/sandbox.py 73.73% <100%> (+0.16%) ⬆️
dmoj/executors/VB.py 0% <0%> (-100%) ⬇️
dmoj/executors/RUBY19.py 0% <0%> (-100%) ⬇️
dmoj/executors/CS.py 0% <0%> (-100%) ⬇️
dmoj/executors/C11.py 0% <0%> (-100%) ⬇️
dmoj/wbox/__init__.py 0% <0%> (-100%) ⬇️
dmoj/executors/RUBY18.py 0% <0%> (-100%) ⬇️
dmoj/executors/CPP17.py 0% <0%> (-100%) ⬇️
... and 42 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update af50b9f...5fdc8d6. Read the comment docs.

Also test judge on python 3.7 and drop 3.4.

Groovy and Scala temporarily dropped because support is difficult.
@quantum5 quantum5 marked this pull request as ready for review April 11, 2019 06:48
@@ -341,13 +344,15 @@ cdef class Process:
cdef public unsigned int _cpu_time
cdef public int _nproc
cdef unsigned long _max_memory
cdef bytes _re_fs_read
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like this naming scheme, took several attempts before I parsed it correctly. _re_readable_fs?

if (!child.empty() && child[0] == '/') {
return child;
}
if (parent.empty() || parent.back() == '/') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline.

while (std::getline(stream, token, '/')) {
if (token.empty() || token == ".")
continue;
if (token != ".." || (!absolute && comps.empty()) ||
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline.

return ".";
}

bool absolute = path[0] == '/';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_absolute

@@ -67,6 +83,66 @@ int pt_process::set_handler(int syscall, int handler) {
return 0;
}

bool pt_process::set_re_fs_read(const char *pattern, int length, char *error,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably want to make this more generic, since we'll likely have the write equivalent of this in the future. Maybe have some struct wrapping all the pointers needed for a single regex?

@@ -12,9 +13,11 @@
#include <unistd.h>
#include <sys/ptrace.h>

#include <string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include order.

#include <set>

#include "ptbox.h"
#include "posixpath.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include order.

} else {
path += "/fd/" + std::to_string(fd);
}
int size = 1024;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PATH_MAX? pathconf?

} else {
path += "/fd/" + std::to_string(fd);
}
int size = 1024;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline.

@@ -219,4 +220,42 @@ void pt_debugger::freestr(char *buf) {
free(buf);
}

std::string pt_debugger::get_fd(int fd) {
std::string path = "/proc/" + std::to_string(getpid());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the correct PID?


int result;
unsigned long file_ptr = (unsigned long) debugger->arg0();
char *file = debugger->readstr(file_ptr, 4096);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this patchset, but this is a function that has failure conditions and should be able to return nullptr. But it doesn't; the underlying code will just segfault.

std::string path(file);

debugger->freestr(file);
if (path.empty() || path[0] != '/') {
Copy link
Member

@Xyene Xyene Apr 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced you should be able to open("") and have it succeed. It'll likely block the access later, but it should block it here, because that's not an alias for the current working directory as this code implies.

return false;
}

int result;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable.

return false;
}

int result;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable.

}

if (r < size) {
buffer[r] = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'\0' for semantics.

int result;
int dirfd = (int) debugger->arg0();
unsigned long file_ptr = (unsigned long) debugger->arg1();
char *file = debugger->readstr(file_ptr, 4096);
Copy link
Member

@Xyene Xyene Apr 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem safe to me. What if the system path max is greater than 4096? Then something like print open('./' * 2048 + '../../etc/secrets').read() will validate successfully. This should either fail loudly if the path is longer then 4096, or perform another read.

@@ -27,6 +27,7 @@

# Allow manually disabling seccomp on old kernels. WSL doesn't have seccomp.
has_seccomp = not is_wsl and os.environ.get('DMOJ_USE_SECCOMP') != 'no'
has_pcre = os.environ.get('DMOJ_USE_PCRE') != 'no'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is made optional, it should be added to the appropriate README.md section.

@Xyene
Copy link
Member

Xyene commented Aug 28, 2021

This has been superseded by the plans in #871.

@Xyene Xyene closed this Aug 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants