-
Notifications
You must be signed in to change notification settings - Fork 254
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
Conversation
Codecov Report
@@ 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
Continue to review full report at Codecov.
|
Also test judge on python 3.7 and drop 3.4. Groovy and Scala temporarily dropped because support is difficult.
@@ -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 |
There was a problem hiding this comment.
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() == '/') { |
There was a problem hiding this comment.
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()) || |
There was a problem hiding this comment.
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] == '/'; |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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] != '/') { |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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' |
There was a problem hiding this comment.
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.
This has been superseded by the plans in #871. |
To do:
/proc/$pid/cwd
)AT_FDCWD