delorie.com/archives/browse.cgi   search  
Mail Archives: geda-user/2023/03/27/21:33:29

X-Authentication-Warning: delorie.com: mail set sender to geda-user-bounces using -f
X-Recipient: geda-user AT delorie DOT com
Date: Tue, 28 Mar 2023 03:13:27 +0200 (CEST)
From: Roland Lutz <rlutz AT hedmen DOT org>
To: "Girvin Herr (gherrl2 AT fastmail DOT com) [via geda-user AT delorie DOT com]" <geda-user AT delorie DOT com>
Subject: Re: [geda-user] Changing gschem backup file permissions
In-Reply-To: <f29c048b-5eb9-2b1f-1d42-05dfaec7f269@fastmail.com>
Message-ID: <e834187-ef19-da25-7ae8-a466e0ab5bef@grinsen-ohne-katze.de>
References: <4772851a-fca0-4370-d6bb-ef854127e604 AT fastmail DOT com> <d443f011-965-fc1-5762-2c42e1c804e AT grinsen-ohne-katze DOT de> <f29c048b-5eb9-2b1f-1d42-05dfaec7f269 AT fastmail DOT com>
MIME-Version: 1.0
Reply-To: geda-user AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: geda-user AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

On Mon, 27 Mar 2023, Girvin Herr (gherrl2 AT fastmail DOT com) [via 
geda-user AT delorie DOT com] wrote:
> That is what I was afraid of. I was hoping it could be done in a 
> configuration file somewhere. Thanks for the info, though.

Well ... if you don't want do re-build gEDA/gaf from source, you could 
always binary-patch the library.

Go to the directory (e.g., /usr/local) where you installed gEDA/gaf. 
Make a backup copy of your libgeda library:

$ cp -i lib/libgeda.so.47.0.0 lib/libgeda.so.47.0.0.backup

Look at the disassembled library to find the relevant code location:

$ objdump -d lib/libgeda.so.47.0.0 | less

You can use "/f_save<RET>" to search for the function name and "n" to skip 
over the procedure linkage table entry (we are not interested in that) 
until you get to the actual function.  This should look something like 
this:

0000000000023a20 <f_save>:
    23a20:       41 57                   push   %r15
    23a22:       41 56                   push   %r14
    23a24:       41 55                   push   %r13
(and so on)

Now, look for the AND instruction ("/and<RET>") that clears the write bits 
in the permissions (ug-wx o-x = 0446 = 0x126).  There are two AND 
instructions in f_save; in my case, the relevant one is the second one. 
It should look something like this:

    23e44:       31 ff                   xor    %edi,%edi
    23e46:       e8 15 1a ff ff          callq  15860 <umask AT plt>
    23e4b:       48 8b 7c 24 10          mov    0x10(%rsp),%rdi
    23e50:       89 c6                   mov    %eax,%esi
    23e52:       89 44 24 1c             mov    %eax,0x1c(%rsp)
    23e56:       f7 d6                   not    %esi
    23e58:       81 e6 26 01 00 00       and    $0x126,%esi
    23e5e:       e8 1d f2 fe ff          callq  13080 <chmod AT plt>

The previous umask is stored in %esi, inverted, masked with 0x126, and 
passed to chmod.  We want to change the permission mask, so it is the 
address of the AND instruction we are interested in (0x23e58 in my case, 
but yours will be different), as well as the exact machine text (81 e6 26 
01 00 00 in my case).

Copy that information, close the disassembly ("q") and run Python.  Open 
the shared library, seek to the position you determined and see if you get 
the bytes you saw in the disassembly (make sure to enter the extra newline 
after the third line of code to tell Python the block is over):

$ python3
>>> with open('lib/libgeda.so.47.0.0', 'rb') as f:
...     f.seek(0x23e58)  # <-- replace with your value
...     f.read(6)
... 
147032
b'\x81\xe6&\x01\x00\x00'

Looks good!  The ampersand is ASCII 0x26, so it's displayed as a visual 
character, but it is the correct value.  Now replace the mask with the one 
we want (ugo-x = 0666 = 0x1b6), otherwise using the exact same bytes as 
seen in your disassembly:

>>> with open('lib/libgeda.so.47.0.0', 'r+b') as f:
...     f.seek(0x23e58)  # <-- replace with your value
...     f.write(b'\x81\xe6\xb6\x01\x00\x00')  # <-- this too
... 
147032
6
>>> ^D

(For Python 2, you need to omit the "b" before the byte string.)

You're done!  Now verify that you did indeed change the correct 
instruction.  You should see exactly one changed byte (from 26 to b6):

$ diff <(objdump -d lib/libgeda.so.47.0.0.backup) <(objdump -d lib/libgeda.so.47.0.0)
2c2
< lib/libgeda.so.47.0.0.backup:     file format elf64-x86-64
---
> lib/libgeda.so.47.0.0:     file format elf64-x86-64
19164c19164
<    23e58:     81 e6 26 01 00 00       and    $0x126,%esi
---
>    23e58:     81 e6 b6 01 00 00       and    $0x1b6,%esi

If this is what you see, the binary patch has succeeded, and you should 
have the file permissions you want the next time you run gschem.  If you 
see changes different than that (or no changes at all), DELETE the botched 
library and restore it from the backup.

Hope that helps!

Roland

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019