maemo.org - Talk

maemo.org - Talk (https://talk.maemo.org/index.php)
-   SailfishOS (https://talk.maemo.org/forumdisplay.php?f=52)
-   -   [BETA] prepatch a system-wide patching system (alternative to patchmanager) (https://talk.maemo.org/showthread.php?t=100243)

jakibaki 2018-03-11 23:08

[BETA] prepatch a system-wide patching system (alternative to patchmanager)
 
2 Attachment(s)
Update:
Coderus is working on integrating the preload-method into patchmanger 3!

This will make prepatch pretty much redundant so I recommend every patch-dev to wait for pm3 instead of porting their patch as prepatch won't be maintained anymore when pm3 releases.

Patchmanager 3 is currently in closed alpha and you can request access by following the instructions here.

This is still in beta!
You may (or may not) still encounter issues. (please report them if you do)

What is this?

Prepatch is an alternative to patchmanager.
However unlike patchmanager prepatch doesn't modify any files on disk but instead replaces the "open"/"open64" function in order to make applications think that those files were modified.

Why should I use/not use prepatch instead of patchmanger?

Advantages
  • Undoing patches is never a problem even if multiple patches were applied to a single file.
  • Patches don't have to be reapplied if the patched file has been updated.
  • System-Updates no longer break stuff if patches are applied and all patches which still work after the update will instantly be working again (no reenabling patches).
  • An "apply-order" can be specified if patches which patch the same file need it.
  • Prepatch can replace/add files if you're confident that the patched file should stay the same even if jolla updates it.
  • It's generally "cleaner" to leave files of other applications alone.
Disadvantages
  • Because of the way it works prepatch will slow down the opening of all files a (small) bit since it has to check if patches have to be applied and, if necessary, apply them. Patchmanager doesn't suffer from this, since it applies the patch to the real files.
  • No gui (at the moment) to install/toggle patches. However this will likely change in the future.
  • Patchmanager has a lot more patches availible. However porting them to prepatch should be trivial in the vast majority of cases.

How does it work?

Prepatch works by preloading a library into every binary (don't worry, the overhead is much smaller then it sounds) and replaces the open+open64 function in there.

If an application tries to open a file which doesn't have a patch (or tries to open the file for writing/as any user other then nemo) the replaced open function will just behave like the normal open function.

However if an application tries to open a file for which a patch has been installed (in most cases an qml-file) prepatch will apply the patch(es) to a temporary copy of the file and then open that one instead of the one the application requested.

That way the application will think that the file has been patched and behave that way while in reality the real file stays unmodified.

How do I install it?

Just install the prepatch package from openrepos.

How do I uninstall it?

To uninstall prepatch simply remove the prepatch package and you're done. No additional cleanup needed!

How do I install patches?

Just find the patch on openrepos and install it :)

For example here's my keyboard-swipe-patch.

In some cases restarting lipstick might be required.

How do I develop patches?

Developing patches for prepatch is easy :)

I'll explain it with my keyboard-swipe-patch as the example. Replace the names/path with yours as needed.

First we'll create the patch-folder (which will be placed into /usr/share/prepatch after we're done creating the patch).

Code:

mkdir 050-prepatch-keyboard-swipe
The 050 is there to make it easy to specify the order in which the patches shall be loaded.

If for example an other patch modifies the same file as yours but only works if your patch is applied before the other one you simply choose an lower number and your patch will always be applied first.

Don't cd into it yet.

First create two copies of the file which you want to modify.
One will stay the same and the other one will be modified.

Code:

cp /usr/share/maliit/plugins/com/jolla/KeyboardBase.qml KeyboardBase-Original.qml
cp /usr/share/maliit/plugins/com/jolla/KeyboardBase.qml KeyboardBase-Modified.qml

Please note that, if there's already a prepatch patch applied on this file you'll get the modified version when trying to copy it (as prepatch is loaded into cp).
If that's the case temporarily disable the other patch until you're done with this step.

Now edit the KeyboardBase-Modified.qml file according to your needs.

After that create the directory in which your patch will be located in.

In my case I have to run

Code:

mkdir -p 050-prepatch-keyboard-swipe/usr/share/maliit/plugins/com/jolla/
Now run diff -u old new > 050-yourpatch/path/to/orig.qml.patch.

Im my case:

Code:

diff -u KeyboardBase-Original.qml KeyboardBase-Modified.qml > 050-prepatch-keyboard-swipe/usr/share/maliit/plugins/com/jolla/KeyboardBase.qml.patch
Repeat this process with all the files you want to patch (you can place multiple patches in the same 050-prepatch-folder).

If you want to add/completely replace a file instead of patching it you can simply place it inside the folder without the .patch extension. Please note that new files will not appear in directory-listings so ls /path/to/fakefile will not show the file but running cat /path/to/fakefile/file will print out its contents.

Now simply copy the 050-prepatch* folder to /usr/share/prepatch and your patch will be applied the next time the modified file is loaded!

If you want to package your patch you can take a look at my keyboard-swipe-repo, modify the folders+spec to your needs and package it by following this guide.

If you need to add an settings-page to your patch you can take the way it's done in this patch as a reference.

How do I convert patches from patchmanager to prepatch?

I've written a script which can automatically split patchmanager-patches into the prepatch-format.

Obviously the patch you're trying to port has to work with the SailfishOS-version you're on.

This script requires you to have patchutils installed on your computer (or your phone if you want to port this with your device :) ).

If you don't it's most likely availible in your package-sources on the os of your choice.
For example here's how you install patchutils on SailfishOS:
Code:

devel-su pkcon install patchutils
I'll explain it with my button-vibrate-patch which was originally made for patchmanager (that patch has already been ported to prepatch by me so if you want to use that you can do that already without following this tutorial).

First create a working directory and cd there (not necessary but recommended).
Code:

mkdir portpatch; cd portpatch
Now download my convert.sh script and mark it as executabe.
Code:

curl -O https://raw.githubusercontent.com/jakibaki/prepatch/master/convert.sh && chmod +x convert.sh
Now obtain the unified_diff.patch from the patch that you want to port to prepatch and place it in the working directory. In my case I can get it from the zip on the patchmanager-page .
Convert the unified_diff.patch to a patchmanager-patch like this:
Code:

./convert.sh unified_diff.patch 050-prepatch-silica-button-vibrate
Now you can activate the patch by copying it to /usr/share/prepatch.
Code:

devel-su cp -r 050-prepatch-silica-button-vibrate /usr/share/prepatch
The patch is now applied. Restart lipstick if necessary.
If you want to create an rpm for publishing you can follow my development-instructions and just skip until after creating the patch.

If the patch has any settings-pages included you'll need to manually install them by creating an settings-page entry information like
this one and place it in /usr/share/jolla-settings/entries and place the main.qml file in /usr/share/jolla-settings/pages/YOUR_PAGE_NAME/main.qml and the icon (if there is any) in /usr/share/jolla-settings/pages/YOUR_PAGE_NAME/ICON_NAME.png.

Is it possible to run this alongside with patchmanager?

Yes it is. However all patches that are applied using prepatch will be "applied" after the patchmanager-patches.

What bugs/issues are currently known?
  • Fixed in 0.2.2-1 //For some reason lipstick crashes when trying to click on the weather-applet in the notification-center. (thanks to cy8aer for reporting this)
  • Fixed in 0.2.0-1! //For some reason after starting/restarting lipstick it keeps loading for about 20 seconds.
    After that everything goes back to normal and performance doesn't seem to be affected in other apps so I suspect that this is caused by a bug in prepatch.

I want to help! How can I help?
  • There's no graphical interface for toggeling patches yet (not particularly urgent).
  • Update: There is one now! Many thanks to Fellfrosch! //Prepatch has no icon yet.

What patches are availible?
  • keyboard-swipe-cursor A simple patch which allows you to move the cursor on the keyboard by swiping it to the left/right.
  • silica-button-vibrate A patch which makes silica-buttons and icon-buttons vibrate when touched or released.

If you want your patch listed here please open an issue on github or ask in this thread.

UPDATES:
  1. Added packaging for patches.
  2. Added prepatch package!
  3. Fixed the loading-screen bug! (0.2.0-1) Prepatch should now be usable on older devices!
  4. Added script to convert patchmanager-patches to prepatch-patches.
  5. Added icon! Many thanks to Fellfrosch for creating it!
  6. Fixed the weather-applet-issue (0.2.2-1)

juiceme 2018-03-12 06:03

Re: [WIP] prepatch a system-wide patching system (alternative to patchmanager)
 
This is absolutely ingenious way of applying patches and beats patchmanager hands down :p
Congratulations, a fine idea indeed!

tortoisedoc 2018-03-12 07:44

Re: [WIP] prepatch a system-wide patching system (alternative to patchmanager)
 
I don't want to think about the security implications of this; but
great idea!

bocephus 2018-03-12 10:25

Re: [WIP] prepatch a system-wide patching system (alternative to patchmanager)
 
Looking forward to trying this. Very good work on a very good idea. Taking a small hit in speed is a small price to pay weighted against the advantages.

tortoisedoc 2018-03-12 12:38

Re: [WIP] prepatch a system-wide patching system (alternative to patchmanager)
 
Quote:

Originally Posted by bocephus (Post 1542264)
Looking forward to trying this. Very good work on a very good idea. Taking a small hit in speed is a small price to pay weighted against the advantages.

Hello? Security? Am I the only one worried here? :(

jakibaki 2018-03-12 12:59

Re: [WIP] prepatch a system-wide patching system (alternative to patchmanager)
 
Quote:

Originally Posted by tortoisedoc (Post 1542273)
Hello? Security? Am I the only one worried here? :(

If you have concerns please voice them.
I don't want to be shipping anything which compromises users security.

My code is obviously not perfect so there may be some attack-surface there but I don't see how it's worse than patchmanager in that regard.

For installing prepatch and patches for it you'll need root-permissions with which an attacker could do anything evil anyways.

jakibaki 2018-03-12 15:55

Re: [WIP] prepatch a system-wide patching system (alternative to patchmanager)
 
I packaged everything (my patch and prepatch itself) and uploaded them to openrepos. Installing/Removing prepatch and prepatch-patches is now as easy as with every other package! :)

jayki 2018-03-12 19:22

Re: [WIP] prepatch a system-wide patching system (alternative to patchmanager)
 
Very nice work :)
It would be even better if it could use coderus's Webcatalog, the patchfiles itself shouldn't be differnt, didn't they?
Maybe coderus can help integrating the api in your app and we all can call it patchmanger 2.5 or 3 ;)

jakibaki 2018-03-12 19:39

Re: [WIP] prepatch a system-wide patching system (alternative to patchmanager)
 
Quote:

Originally Posted by jayki (Post 1542290)
Very nice work :)
It would be even better if it could use coderus's Webcatalog, the patchfiles itself shouldn't be differnt, didn't they?
Maybe coderus can help integrating the api in your app and we all can call it patchmanger 2.5 or 3 ;)

Patchmanager patches have one patch file for all files that are going to be patched while prepatcher uses one patch-file for each file that's going to be patched in order to reduce the overhead that's caused by finding and applying a patch (which is done when the file loads so not spending too much time on that is vital).

However it should be trivial to write a tool which converts patchmanager-patches to prepatcher patches. (I might do so in the future).

Part of the point of prepatcher is that nothing special has to be done to enable/disable patches though so I don't see much of a reason not to simply distribute patches through openrepos since there's already a nice frontend for that (storeman).

cy8aer 2018-03-12 20:03

Re: [WIP] prepatch a system-wide patching system (alternative to patchmanager)
 
I tried the packaged version and rebooted. But I had some difficulties:

1st try: Unlocking froze the device
2nd try: After shutdown and start I was able to unlock but then lipstick was veeery slow (waiting circle on startup). I had a frozen screen when swiping but it came back.

Then I uninstalled both packages (prepatcher and the keyboard patch) and rebooted and every went smooth again.

JollaC 2.1.4.14


All times are GMT. The time now is 18:07.

vBulletin® Version 3.8.8