ubuntuusers.de

Nach setcap werden dynamisch gelinkte Bibliotheken nicht mehr gefunden.

Status: Ungelöst | Ubuntu-Version: Ubuntu 18.04 (Bionic Beaver)
Antworten |

wentz89

Anmeldungsdatum:
9. Januar 2020

Beiträge: Zähle...

Mein System: 5.3.0-40-generic #32~18.04.1-Ubuntu SMP Mon Feb 3 14:05:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Für eine bestimmte Binary muss ich nach dem Comilieren den Befehl

1
sudo setcap cap_net_raw=ep <binary_name>

ausführen, damit diese für ihren Zweck funktionieren kann. Bevor ich den Befehl ausführe kann ich das Programm ohne Probleme ausführen (in einer Simulation). Danach bekomme ich jedoch immer die Fehlermeldung

1
</path/to/binary>: error while loading shared libraries: <libblablabla>.so: cannot open shared object file: No such file or directory

Dabei hat sich sonst nichts geändert. Ich habe den LD_LIBRARY_PATH überprüft, er stimmt und die Bibliothek ist im Pfad, ich habe mit ldd die dynamisch gelinkten Bibliotheken überprüft, diese stimmen und befinden sich im Pfad und ich habe ldconfig probiert aber hilft nicht.

Eine unschöne Lösung ist die Bibliothek aus dem Pfad nach /usr/lib zu kopieren (der Pfad ist im LD_LIBRARY_PATH enthalten). Ich müsste das aber für alle ~50 Bibliotheken machen und das ist wie gesagt unschön und sehr gefrikelt.

Kurz gesagt

Weiß jemand warum eine Binary die dymanisch gelinkten Bibliotheken (aus dem LD_LIBRARY_PATH) nicht mehr findet wenn man:

1
sudo setcap cap_net_raw=ep <binary_name>

ausgeführt hat? Und wie man dieses Problem beheben kann.

PS: Unter Ubuntu 16.04 gab es diese Problem komischerweise nicht!!

Nachdem mein Beitrag gemeldet wurde möchte ich noch hinzufügen, dass es sich bei setcap um ein Standardtool handelt (wie sed, cat, etc).

dingsbums

Anmeldungsdatum:
13. November 2010

Beiträge: 3790

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13205

wentz89 schrieb:

Weiß jemand warum eine Binary die dymanisch gelinkten Bibliotheken (aus dem LD_LIBRARY_PATH) nicht mehr findet wenn man:

1
sudo setcap cap_net_raw=ep <binary_name>

ausgeführt hat? Und wie man dieses Problem beheben kann.

Das Environment ändert sich. Probier mal dies in einer Shell:

1
2
sudo -v
diff -U3 <(env|sort) <(sudo env|sort) | less

Du kannst das z.B. so ändern:

1
sudo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" setcap cap_net_raw=ep <binary_name>

Wenn das das Problem sein sollte natürlich nur.

wentz89

(Themenstarter)

Anmeldungsdatum:
9. Januar 2020

Beiträge: 6

Vielen Dank für die schnellen Antworten. Ich habe wieder etwas neues gelernt, leider konnte das Problem nicht behoben werden.

Der Hinweis erschien mir sehr logisch:

rklm schrieb:

Das Environment ändert sich. Probier mal dies in einer Shell:

...

Du kannst das z.B. so ändern:

1
sudo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" setcap cap_net_raw=ep <binary_name>

funktionierte jedoch nicht. Ich bin darum einen Schritt weiter gegangen und habe die notwendigen Pfade in die /etc/environment eingetragen. Erfolglos.

Der Stackoverflow Post hat auch ein paar vielversprechende Hinweise: den gcc compiler/linker die Pfade mit -rpath="/path/to/libs" mitzuteilen. Ich kann das nicht direkt machen da ich das Catkin-Buildsystem mit Cmake verwende. Habe aber zwei Alternativen ausprobiert (in der CMakeLists.txt):

1
set(CMAKE_CXX_FLAGS "-Wall -Wno-dev -Wl,-rpath=/path/to/libs:/path/to/other/libs")

und

1
set(LDFLAGS = "-rpath=/path/to/libs:/path/to/other/libs")

leider beide erfolglos. Die Situation ist unverändert.

Ich habe noch festgestellt, dass es ausreicht Symbolic Links der Bibliothek(en) in /usr/lib anzulegen. Das ist leider immer noch eine sehr unschöne Lösung.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13205

wentz89 schrieb:

1
sudo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" setcap cap_net_raw=ep <binary_name>

funktionierte jedoch nicht.

Ich glaube, das war auch Blödsinn: wenn ich mir jetzt noch mal Dein Eingangsposting durchlese, dann kommt der Fehler ja nachher, also beim Ausführen des Programms. Das ist mir beim ersten Lesen durchgerutscht.

Ich glaube nicht, dass es an LD_LIBRARY_PATH liegt, denn der ist ja vermutlich unverändert. Möglicherweise verhindert etwas die Ausführung, weil ggf. die Shared Lib nicht dieselbe Capability hat? In dem Bereich kenne ich mich leider gar nicht aus. 😢 Du könntest ja mal die Capabilities der verlinkten Shared Libraries prüfen. Also mit ldd ermitteln und dann pro Lib setcap -v cap_net_raw=ep dateiname prüfen. Vielleicht ergibt das ja einen Hinweis.

wentz89

(Themenstarter)

Anmeldungsdatum:
9. Januar 2020

Beiträge: 6

Problem kommt vom dynamischen Linker siehe: http://man7.org/linux/man-pages/man8/ld.so.8.html Abschnitt Environment - Secure-execution mode:

"[...], if the dynamic linker determines that a binary should be run in secure-execution mode, the effects of some environment variables are voided or modified, and furthermore those environment variables are stripped from the environment, so that the program does not even see the definitions.[...]"

Ob eine Binary im secure-execution mode gestartet wird hängt von verschiedenen Bedingungen ab (z. B. geänderte Rechte) und wird im auxiliary vector gespeichert.

Sucht man ein wenig weiter findet sich diese man Page: http://man7.org/linux/man-pages/man3/getauxval.3.html und dass der auxiliary vector eines Prozess auch in /proc/<prozess_nummer>/auxv eigesehen werden kann (Mit cat bekommt man nur binäres Kauderwelch). Es gibt leider kein Kommandozeilenprogramm um dem Vektor auszulesen oder zu verändern.

So wie es aussieht lässt sich der Vektor nicht (ohne weiteres) von außen verändern. Ich werde bis ich mal wieder mehr Zeit habe auf den Quickhack zurückgreifen und alle Bibliotheken als symbolischer Link in /usr/lib anlegen. Dazu habe ich ein bash Skript angelegt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/env bash

echo "Source Path: " $1
echo "Destination Path: "$2

if [ $# -ne 2 ]
then
    echo "Expect 2 Arguments; Needs to run as super-user"
    echo "1: Source Path"
    echo "2: Destination Path"
    echo "This script creates symlinks of all files from source path in the destination path if the file/symlink not already exists in the destination path"
    exit -1
fi

for f in $1*; do
    if [ -d $f ];
    then
        echo $f "is a directory"
    else
        # f is a file
        fname=$(echo $f | awk 'BEGIN {FS="/lib/"}{print $2}')
        if echo $fname | grep -q .so;
        then
            destfile=$2$fname
            if [[ -f $destfile ]]
            then
                echo $fname "exists in destination path"
            else
                sudo ln -s $f $destfile
            fi
        else
            # quickhack or okay ??
            echo $fname "is not a dynamik library"
        fi
    fi
done

Falls jemand eine Lösung kennt, um das secure bit im auxiliary vector zu entfernen, wäre schön das zu teilen. Bei mir wird es ein wenig dauern bis ich dazu komme.

Antworten |