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

Add basic Intel SGX support #2219

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
836cccb
Add configuration support for Intel SGX enclaves
hf Jan 7, 2020
2521275
Use DUK_SNPRINTF when formatting dates
hf Jan 7, 2020
497dd46
Use DUK_SNPRINTF in JSON enc/dec
hf Jan 7, 2020
e12db1e
Use DUK_SNPRINTF for symbols
hf Jan 7, 2020
bb8427a
Use DUK_SNPRINTF in numconv
hf Jan 7, 2020
f69ad97
Add .ccls-cache to .gitignore
hf Jan 7, 2020
1d6d59f
Add myself to AUTHORS.rst
hf Jan 7, 2020
0ec10b7
Add duk_encode_pointer_cstr, duk_decode_pointer_cstr
hf Jan 11, 2020
167efd7
Use pointer encode functions in JX/JC
hf Jan 11, 2020
6bacf10
Register DUK_USE_STANDARDIZED_POINTER_ENCODING option
hf Jan 11, 2020
ab5f62d
Add DUK_MAX_POINTER_ENCODING_SIZE and use it
hf Jan 11, 2020
ec5b638
Add guard for decoding ptr with JX only
hf Jan 11, 2020
994eb12
Add explicit cast to unsigned char
hf Jan 11, 2020
31af16f
Add better docs for DUK_USE_STANDARDIZED_POINTER_ENCODING
hf Jan 11, 2020
c7ce26c
Use pointer enc/dec functions everywhere
hf Jan 11, 2020
43fba82
Fix pointer decoding issue
hf Jan 11, 2020
307dba7
Change space-indent to tab
hf Jan 12, 2020
e09a947
Add setting ptr to NULL on failures
hf Jan 12, 2020
60c27b9
Fix ECMA tests failing on decode (improper impl)
hf Jan 12, 2020
9ca0bd7
Add runtests/package-lock.json to .gitignore
hf Jan 12, 2020
fa687f6
Add info in doc/json.rst for DUK_USE_STANDARDIZED_POINTER_ENCODING
hf Jan 12, 2020
c984c1f
Fix ...decode_pointer_cstr with DUK_USE_STANDARDIZED_POINTER_ENCODING
hf Jan 12, 2020
abe247f
Enable DUK_USE_STANDARDIZED_POINTER_ENCODING when in Intel SGX
hf Jan 12, 2020
9ca1f0b
Define INTELSGX to trigger DUK_F_INTELSGX
hf Jan 25, 2020
55bc9b6
Eliminate dead code
hf Jan 25, 2020
42fdfef
Rename to DUK_USE_MEMBASED_POINTER_ENCODING
hf Feb 4, 2020
1f43ea5
Add myself to code authors
hf Feb 4, 2020
3fc9a1a
Fix void* style and typos
hf Feb 4, 2020
a6226b4
Fix indentation issues
hf Feb 4, 2020
69d9561
Use duk_lc_digits instead of another static hex definition
hf Feb 4, 2020
0d7e9be
Fix all remaining void* style issues
hf Feb 4, 2020
d5b4c8c
Clarify symbol representation, assert
hf Feb 5, 2020
1e9402d
duk__bi_print with better snprintf
hf Feb 5, 2020
2688816
Use hex dectables to parse membased ptrs
hf Feb 5, 2020
06181e7
C99 compatibility
hf Feb 5, 2020
430a2fb
Fix indentation issues
hf Feb 12, 2020
345ab2d
Format void** to void **
hf Feb 29, 2020
ead8474
DUK_USE_MEMBASED_POINTER_ENCODING introduced in 3.0.0
hf Feb 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
/es5-tests.zip
/JS-Interpreter/
/runtests/node_modules/
/runtests/package-lock.json
/d067d2f0ca30.tar.bz2
/595a36b252ee97110724e6fa89fc92c9aa9a206a.zip
/regfuzz-0.1.tar.gz
Expand Down Expand Up @@ -90,3 +91,4 @@
/references/ECMA-262 5.1 edition June 2011.pdf
/references/ECMA-262.pdf
/tests/octane/octane
/.ccls-cache
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ and agreed to irrevocably license their contributions under the Duktape
* Rick Sayre (https://github.com/whorfin)
* Craig Leres (https://github.com/leres)
* Maurici Abad (https://github.com/mauriciabad)
* Stojan Dimitrovski (https://github.com/hf)

Other contributions
===================
Expand Down
3 changes: 3 additions & 0 deletions config/config-options/DUK_USE_DATE_GET_LOCAL_TZOFFSET.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ tags:
description: >
Mandatory macro for getting the local time offset for a given datetime,
see datetime.rst.

When used in Intel SGX enclaves it must be implemented by the enclave
developer, otherwise it will fail with a compilation error.
3 changes: 3 additions & 0 deletions config/config-options/DUK_USE_DATE_GET_NOW.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ description: >
If the time provided experiences time jumps or doesn't advance in realtime
(which is useful in some time virtualization scenarios), consider defining
DUK_USE_GET_MONOTONIC_TIME.

When used in Intel SGX enclaves it must be implemented by the enclave
developer, otherwise it will fail with a compilation error.
13 changes: 13 additions & 0 deletions config/config-options/DUK_USE_MEMBASED_POINTER_ENCODING.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
define: DUK_USE_MEMBASED_POINTER_ENCODING
introduced: 3.0.0
default: false
tags:
- ecmascript
description: >
All pointers that need to be encoded as string will be encoded in
lowercase hexadecimal encoding in the byte order they are laid out in
memory. Decoding will also work the same way. Using this will also
skip reliance on sscanf for platforms that don't support it.

When turned off, pointer encoding to string is done via the %p format
specifier in the printf and scanf family of functions.
13 changes: 13 additions & 0 deletions config/config-options/DUK_USE_STANDARDIZED_POINTER_ENCODING.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
define: DUK_USE_MEMBASED_POINTER_ENCODING
introduced: 2.7.0
hf marked this conversation as resolved.
Show resolved Hide resolved
default: false
tags:
- ecmascript
description: >
All pointers that need to be encoded as string will be encoded in
lowercase hexadecimal encoding in the byte order they are laid out in
memory. Decoding will also work the same way. Using this will also
skip reliance on sscanf for platforms that don't support it.

When turned off, pointer encoding to string is done via the %p format
specifier in the printf and scanf family of functions.
Copy link
Owner

Choose a reason for hiding this comment

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

This file should be removed from the squashed commit.

9 changes: 9 additions & 0 deletions config/helper-snippets/DUK_F_INTELSGX.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
Copy link
Owner

Choose a reason for hiding this comment

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

Trivia: no double star in comment style.

* Automatic Intel SGX detection is not possible at compile time.
* Therefore Intel SGX enclave developers wanting to use Duktape
* should either manually specify --platform=intelsgx to configure.py
* or manually define INTELSGX when compiling.
*/
#if defined(INTELSGX)
#define DUK_F_INTELSGX
#endif
4 changes: 4 additions & 0 deletions config/platforms.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ autodetect:
name: Durango (XboxOne)
check: DUK_F_DURANGO
include: platform_durango.h.in
-
name: Intel SGX # Keep this above Linux or Windows.
check: DUK_F_INTELSGX
include: platform_intelsgx.h.in
-
name: Windows
check: DUK_F_WINDOWS
Expand Down
74 changes: 74 additions & 0 deletions config/platforms/platform_intelsgx.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <endian.h>
#include <stdint.h>
#include <sys/types.h>
#include <mbusafecrt.h>

/*
* Intel SGX enclaves are completely isolated from the underlying
* kernel and therefore syscalls are not allowed by default. This
* means that getting the current time and locale information is
* impossible unless there is intervention by the enclave developers.
*
* Thus enclave developers must define DUK_USE_DATE_GET_NOW and
* DUK_USE_DATE_GET_LOCAL_TZOFFSET for their enclave either manually
* in duk_config.h or via other means (other config header, compiler
* flags). If these are not defined compilation will fail with a
* preprocessor error.
Copy link
Owner

Choose a reason for hiding this comment

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

This should just say "in duk_config.h", no other means are supported. So something like:

Enclave developers must provide DUK_USE_DATE_GET_NOW and DUK_USE_DATE_GET_LOCAL_TZOFFSET when configuring Duktape for build.

*
* DUK_USE_DATE_GET_NOW should return a duk_double_t value containing
* the current ECMASCript time.
* DUK_USE_DATE_GET_LOCAL_TZOFFSET should return a duk_int_t value
* containing the offset from UTC in seconds of the current time.
* See the datetime.rst file for more information, as well as the
* duk_bi_date.c, duk_bi_date_unix.c files for inspiration.
*
* DUK_USE_DATE_FORMAT_STRING and DUK_USE_DATE_PARSE_STRING macros are
* not mandatory and are therefore not defined here, but enclave
* developers are free to define them via duk_config.h or other means
* if they are implementing platform or locale scpecific date parsing
* and formatting.
*
* All related Duktape provided implementations regarding date and
* time are intentionally disabled, since date and time functions are
* not generally available in Intel SGX enclaves.
*/

#undef DUK_USE_DATE_FMT_STRFTIME
#undef DUK_USE_DATE_NOW_GETTIMEOFDAY
#undef DUK_USE_DATE_NOW_TIME
#undef DUK_USE_DATE_NOW_WINDOWS
#undef DUK_USE_DATE_NOW_WINDOWS_SUBMS
#undef DUK_USE_DATE_PRS_GETDATE
#undef DUK_USE_DATE_PRS_STRPTIME
#undef DUK_USE_DATE_TZO_GMTIME
#undef DUK_USE_DATE_TZO_GMTIME_R
#undef DUK_USE_DATE_TZO_GMTIME_S
#undef DUK_USE_DATE_TZO_WINDOWS
#undef DUK_USE_DATE_TZO_WINDOWS_NO_DST
Copy link
Owner

Choose a reason for hiding this comment

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

There should be no need to undefine any of these. Only platform files are intended to define the Date provider defines.


/*
* Intel SGX enclaves don't have access to sscanf, so pointer parsing must
* be without using sscanf.
*/
#define DUK_USE_MEMBASED_POINTER_ENCODING
Copy link
Owner

Choose a reason for hiding this comment

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

This probably won't work as expected: if this define appears here, it will prevent the emission of the default value for all platforms when duk_config.h default/forced options section is emitted. The problem is that the default/forced options section only knows that the define is forced in the preceding header, but it doesn't know (or care) that it is conditional to a platform.

So IMO this header should just say in its comments that DUK_USE_MEMBASED_POINTER_ENCODING is a required option for Intel SGX enclaves. There should be a better way to address this, but at present I don't think configure.py can do better.

One possible solution would be for platforms to optionally have a config check snippet at the end of duk_config.h where they could check that required options are met, so that they could #error out cleanly.


#define DUK_SNPRINTF(a,b,c,...) _snprintf_s(a,b,b,c,__VA_ARGS__)
#define DUK_VSNPRINTF(a,b,c,...) _vsnprintf_s(a,b,b,c,__VA_ARGS__)

#if defined(DUK_F_WINDOWS)
/*
* On Windows, assume we're little endian. Even Itanium which has a
* configurable endianness runs little endian in Windows.
*/
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 1
#endif
#endif

#if defined(DUK_F_WINDOWS)
#define DUK_USE_OS_STRING "intelsgx-windows"
#elif defined(DUK_F_LINUX)
#define DUK_USE_OS_STRING "intelsgx-linux"
#else
#error Intel SGX is supported only on Linux or Windows.
#endif
17 changes: 16 additions & 1 deletion doc/json.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ detection:
need to maintain yet another growing data structure for the stack, and don't
need to do linear stack scans to detect loops. The downside is relatively
large memory footprint and lots of additional string table operations.
However, these effects only come into play for very deep objects.
However, these effects only come into play for very deep objects. The option
``DUK_USE_MEMBASED_POINTER_ENCODING`` can be used to remove the reliance
on ``%p``, however pointer values will still be platform-dependent.

There's much room for improvement in the loop detection:

Expand Down Expand Up @@ -546,6 +548,8 @@ specific form, using the format ``(%p)``, e.g.::
(0x1ff0e10) // 32-bit Linux
(000FEFF8) // 32-bit Windows
(000000000026A8A0) // 64-bit Windows
(0d0c0b0a00000000) // 0x0A0B0C0D in 64-bit little-endian x64
// with DUK_USE_MEMBASED_POINTER_ENCODING

A pointer value parses back correctly when serialized and parsed by the same
program. Other than that there is no guarantee that a pointer value can be
Expand All @@ -561,6 +565,14 @@ an error.

(null)

By enabling the ``DUK_USE_MEMBASED_POINTER_ENCODING`` option you can make
the pointer encoding and decoding be "standard" across Duktape builds, but it
is still platform dependant. It would depend on the memory layout and size in
bytes of a pointer value, rather than ``%p``. Pointers can, therefore, be
parsed across different Duktape builds for the same platform. The pointers are
encoded in lowercase hex and there are 2 hex characters for each byte of the
pointer value, as it appears in memory, including heading / trailing 0s.

ASCII only output
-----------------

Expand Down Expand Up @@ -674,6 +686,9 @@ specific form, using the format ``%p``, but wrapped in a marker table::
Note that compared to JX, the difference is that there are no surrounding
parentheses outside the pointer value.

The option ``DUK_USE_MEMBASED_POINTER_ENCODING`` will also be used here as
well.

ASCII only output
-----------------

Expand Down
8 changes: 7 additions & 1 deletion src-input/duk_api_stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -3345,6 +3345,12 @@ DUK_INTERNAL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, d
return duk_to_int_clamped_raw(thr, idx, minval, maxval, NULL); /* out_clamped==NULL -> RangeError if outside range */
}

DUK_INTERNAL void duk_pointer_to_string(duk_hthread *thr, void *ptr) {
char ptrstr[DUK_MAX_POINTER_ENCODING_SIZE];
duk_size_t size = duk_encode_pointer_cstr(ptrstr, sizeof(ptrstr), (void *) ptr);
duk_push_lstring(thr, ptrstr, size);
}

DUK_EXTERNAL const char *duk_to_string(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;

Expand Down Expand Up @@ -3408,7 +3414,7 @@ DUK_EXTERNAL const char *duk_to_string(duk_hthread *thr, duk_idx_t idx) {
case DUK_TAG_POINTER: {
void *ptr = DUK_TVAL_GET_POINTER(tv);
if (ptr != NULL) {
duk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) ptr);
duk_pointer_to_string(thr, ptr);
} else {
/* Represent a null pointer as 'null' to be consistent with
* the JX format variant. Native '%p' format for a NULL
Expand Down
11 changes: 5 additions & 6 deletions src-input/duk_bi_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -957,8 +957,7 @@ DUK_LOCAL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_doub
return 1;
}

/* 'out_buf' must be at least DUK_BI_DATE_ISO8601_BUFSIZE long. */
DUK_LOCAL void duk__format_parts_iso8601(duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags, duk_uint8_t *out_buf) {
DUK_LOCAL void duk__format_parts_iso8601(duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags, duk_uint8_t *out_buf, duk_size_t bufsize) {
char yearstr[8]; /* "-123456\0" */
char tzstr[8]; /* "+11:22\0" */
char sep = (flags & DUK_DATE_FLAG_SEP_T) ? DUK_ASC_UC_T : DUK_ASC_SPACE;
Expand Down Expand Up @@ -1008,16 +1007,16 @@ DUK_LOCAL void duk__format_parts_iso8601(duk_int_t *parts, duk_int_t tzoffset, d
* is portable.
*/
if ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {
DUK_SPRINTF((char *) out_buf, "%s-%02d-%02d%c%02d:%02d:%02d.%03d%s",
DUK_SNPRINTF((char *) out_buf, bufsize, "%s-%02d-%02d%c%02d:%02d:%02d.%03d%s",
(const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY], (int) sep,
(int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],
(int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND], (const char *) tzstr);
} else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {
DUK_SPRINTF((char *) out_buf, "%s-%02d-%02d",
DUK_SNPRINTF((char *) out_buf, bufsize, "%s-%02d-%02d",
(const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY]);
} else {
DUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME);
DUK_SPRINTF((char *) out_buf, "%02d:%02d:%02d.%03d%s",
DUK_SNPRINTF((char *) out_buf, bufsize, "%02d:%02d:%02d.%03d%s",
(int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],
(int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND],
(const char *) tzstr);
Expand Down Expand Up @@ -1074,7 +1073,7 @@ DUK_LOCAL duk_ret_t duk__to_string_helper(duk_hthread *thr, duk_small_uint_t fla
/* Different calling convention than above used because the helper
* is shared.
*/
duk__format_parts_iso8601(parts, tzoffset, flags, buf);
duk__format_parts_iso8601(parts, tzoffset, flags, buf, sizeof(buf));
duk_push_string(thr, (const char *) buf);
return 1;
}
Expand Down
Loading