• Compile words to alternative memory location

    From x4th@21:1/5 to All on Tue May 23 13:34:24 2023
    Hello everyone.

    I'd like to compile words to alternative memory locations for the purpose of protecting them from unintended writes. This should never happen in practice and of course this has _never_ happened to me, but just in case I want to exclude this possibility
    for some of my projects.

    I modified Gforth's allot to to ignore the dictionary bounds check and after that it happily compiles a word to a new mmap'd memory location. After compilation I memory protect that region with mprotect (PROT_READ PROT_EXEC or) and writes to that word
    are no longer possible and it still works as intended. The code is quite uninteresting so I'll only post it on request.

    Is there anything that would likely break because of this (ignore the bounds check for a moment) and is there alternatively a better way to do this, ideally also protecting Gforth's own words too? Primitives are protected but normal words are not.

    Similarily, is there a good use case for modifying words after they've already been compiled? I'd like to hear your use cases.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to x4th@i2pmail.org on Wed May 24 08:13:23 2023
    x4th@i2pmail.org (x4th) writes:
    [reformatted for Usenet-conventional lines of ~70 chars]
    I'd like to compile words to alternative memory locations for the
    purpose of protecting them from unintended writes. This should never
    happen in practice and of course this has _never_ happened to me, but
    just in case I want to exclude this possibility for some of my
    projects.

    I have considered it now and then, but never acted, because I did not experience such problems, either, so the benefit is small, while the
    cost exists.

    I modified Gforth's allot to to ignore the dictionary bounds check

    Better to check the bounds of the new memory section. Development
    Gforth definitely has support for that, because that's needed for
    Gforth's sections.

    and after that it happily compiles a word to a new mmap'd memory
    location. After compilation I memory protect that region with
    mprotect (PROT_READ PROT_EXEC or) and writes to that word are no
    longer possible and it still works as intended. The code is quite >uninteresting so I'll only post it on request.

    Is there anything that would likely break because of this

    I'll assume that you do this only for colon definitions, not for
    variables etc.

    There are some rarely-used features, such as the stepping debugger and REPLACE-WORD which write to the code of colon definitions, and which
    would break. Nothing else comes to my mind at the moment.

    MARKER is always a complication for everything, and whatever you do,
    it typically breaks by default, until you fix it.

    is there alternatively a better way to
    do this, ideally also protecting Gforth's own words too?

    There is no need to use PROT_EXEC for threaded code.

    You can mprotect() a part of an mmap()ed memory area, so if you manage
    to keep the threaded code (and maybe headers and constants) separated
    from the writable stuff, you can protect each page as soon as the next
    page is started.

    Gforth normally uses mmap() for the main dictionary, but also keeps
    writable stuff there, so you cannot protect that. New sections are
    ALLOCATEd, but once they have gone through an image, the sections are
    mmap()ed, and if you have a section consisting purely of read-only
    stuff, you can use that approach on that.

    Similarily, is there a good use case for modifying words after
    they've already been compiled? I'd like to hear your use cases.

    The stepping debugger writes to the threaded code in order to divert
    the execution back to the debugger. REPLACE-WORD writes to the
    threaded code in order to replace a colon definition with another one.

    - anton
    --
    M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
    comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
    New standard: https://forth-standard.org/
    EuroForth 2022: https://euro.theforth.net

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From x4th@21:1/5 to All on Thu May 25 10:02:55 2023
    I have considered it now and then, but never acted, because I did not >experience such problems, either, so the benefit is small, while the
    cost exists.

    For my application the cost would be very small so it seems worthwhile just for that. Gforth is a lot larger than my application so I'm also not sure if it's worthwhile modifying it for a small benefit.

    Better to check the bounds of the new memory section. Development
    Gforth definitely has support for that, because that's needed for
    Gforth's sections.

    Will do. I did skim the paper on Gforth's sections a while back, I'll have a more thorough read.

    I'll assume that you do this only for colon definitions, not for
    variables etc.

    There are some rarely-used features, such as the stepping debugger and >REPLACE-WORD which write to the code of colon definitions, and which
    would break. Nothing else comes to my mind at the moment.

    Yes, only colon definitions. Good to know, I never knew about the stepping debugger either, seems useful. Ideally these two would not be needed in production.

    There is no need to use PROT_EXEC for threaded code.

    This slipped my mind as I've been using Gforth's x86_64 assembler quite a bit lately :)
    Thank you for the thorough response, I now have a lot of new ideas to play with.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to x4th@i2pmail.org on Thu May 25 12:24:18 2023
    In article <f647fefb79b85b9dc7fd6d3dca63697f@rocksolidbbs.com>,
    x4th <x4th@i2pmail.org> wrote:
    Hello everyone.

    I'd like to compile words to alternative memory locations for the
    purpose of protecting them from unintended writes. This should never
    happen in practice and of course this has _never_ happened to me, but
    just in case I want to exclude this possibility for some of my projects.

    There is an other reason to compile words to alternative memory.
    That is temporary code. For example to load the floatingpoint
    I need the assembler. I compile the assembler to limbo/purgatory
    which is a classical PAD type area.
    : PAD HERE 276 + ;
    : limbo HERE UNUSED 2/ ALIGN + ;
    It is mandatory to forget the assembler afterwards.
    Also in defining a class an fake object is build in limbo,
    to calculate offsets of (what others would call) fields.

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)