Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Fredrik_T_
Beginner
105 Views

File operations via OCALLs - typedef FILE missing

Jump to solution

The SDK guide shows how untrusted standard lib functions can be exposed as OCALLS (.edl example on page 62):

untrusted {
    [cdecl, dllimport] FILE * fopen(
        [in,string] const char * filename,
        [in,string] const char * mode);

I have observed two problems with this code:

  1. The .edl example in the SDK is missing an `include "stdio.h"`, otherwise the `FILE` type remains unknown
  2. The stdlib for enclaves (`sgx_tstdc`, ported from OpenBSD) contains a subset of C99 features. `fopen()` etc. are missing from stdio.h, as documented in the SDK guide. The `FILE` typedef is also missing, however. The `.c` file generated from the `.edl` above will only compile, if the `typedef ... FILE` is made available inside the enclave.

I would suggest adding `typedef ... FILE` back into `sgx_tstdc\include\stdio.h`.

0 Kudos
1 Solution
Juan_d_Intel
Employee
105 Views

You're right. This EDL file should include a header file with the definition of FILE. However, FILE should be defined somewhere else other than in stdio.h.

We don't declare many functions and we don't define FILE in stdio.h because they aren't supported in SGX, i.e. you need OCALLs.

View solution in original post

3 Replies
Juan_d_Intel
Employee
106 Views

You're right. This EDL file should include a header file with the definition of FILE. However, FILE should be defined somewhere else other than in stdio.h.

We don't declare many functions and we don't define FILE in stdio.h because they aren't supported in SGX, i.e. you need OCALLs.

View solution in original post

Juan_d_Intel
Employee
105 Views

Consider the bug filed.

Juan_d_Intel
Employee
105 Views

We recommend minimizing the number of OCALL functions in an enclave.

This is an example of a header file that could be included to compile the sample EDL file from the documentation. As you will notice. As you’ll notice this header file contains definitions to ensure trusted and untrusted components have matching definitions.

#ifndef SGX_STDIO_WIN_STUBS_H
#define SGX_STDIO_WIN_STUBS_H

#ifndef _FILE_DEFINED
struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };
typedef struct _iobuf FILE;
#define _FILE_DEFINED
#endif

#ifndef _ERRNO_T_DEFINED
#define _ERRNO_T_DEFINED
typedef int errno_t;
#endif

#define _O_TEXT     0x4000  /* file mode is text (translated) */
#define _O_BINARY   0x8000  /* file mode is binary (untranslated) */

/* Seek method constants */
#define SEEK_CUR    1
#define SEEK_END    2
#define SEEK_SET    0

#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
DECLARE_HANDLE  (HWND);

#ifndef CONST
#define CONST  const
#endif
typedef char CHAR;
typedef CONST CHAR *LPCSTR, *PCSTR;
typedef LPCSTR PCTSTR, LPCTSTR, PCUTSTR, LPCUTSTR;
typedef unsigned int UINT;

#define WINAPI      __stdcall

#endif // SGX_STDIO_WIN_STUBS_H

 

Reply