• omoikane 9 months ago

    Coincidentally, `ldd` has the same caveat on Cygwin, although there it's implemented as an executable instead of a shell script:

        ldd invokes the Windows loader on the file specified, then uses the Windows debugging interface to report DLLs loaded, and (for executables) to attempt to stop execution before the entrypoint. Thus, you should never use ldd on an untrusted file.
    
    https://cygwin.com/cygwin-ug-net/ldd.html
    • userbinator 9 months ago

      I wonder why they implemented it that way, since dynamic linking on Windows is much less of a mess than on *nix systems. dumpbin /imports and Depends have been the standard there for a long time.

      • pjmlp 9 months ago

        Note that Aix is a UNIX that shares the Windows dynamic libraries model.

        ELF like libraries are supported, but not the way most things are expected to work, with XCOFF and export description files.

        Symbian was another OS with similar model, but it wasn't a UNIX anyway, and PIPS was a compatible layer on top.

        • omoikane 9 months ago

          Maybe it's to get the addresses where the DLLs would be loaded? I think that information is not available until the process is created due to ASLR.

          • userbinator 9 months ago

            Due to ASLR, those addresses wouldn't be useful either as they would change with the next process created.

            • omoikane 9 months ago

              Well, the addresses won't be constant, but maybe some people find those addresses to be useful for something, e.g. they want to check if ASLR is enabled.

              I just tried this and I get different addresses every time I ran `ldd /bin/true` on Linux, but I always get back the same addresses on Windows.

      • ReleaseCandidat 9 months ago

        Each Elf executable can have its own "interpreter" (loader, which as default is `ld-linux. so`), so without calling the configured interpreter ldd can't know about the dependencies of such "special" executables. And the configured interpreter can be any program, AFAIK there are no limititations in the ELF format.

        • quotemstr 9 months ago

          Yes, but in the vast majority of cases the interpreter is ld-linux.so (or the Buonic/Musl equivalent) and a safe binary inspection tool can know for sure what that interpreter will do. It's okay for that tool to say "I don't know" 0.0001% of the time.

          • ReleaseCandidat 9 months ago

            It wasn't meant as an argument against not loading the interpreter, but an explanation why it is "normal" - but if course insecure - behavior for ldd to execute the configured interpreter.

          • therein 9 months ago

            I wonder what happens if it specifies itself as the interpreter.

            • rep_lodsb 9 months ago

              Tried it, seems to crash immediately:

                  $ strace ./true
                  execve("./true", ["./true"], 0x7ffc9993be20 /* 40 vars */) = 0
                  --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
                  +++ killed by SIGSEGV +++
              
              (hexedited copy of /bin/true; something different might happen with a specially crafted file which has no other data in it besides the name of the interpreter?)
          • krosaen 9 months ago

            I have found libtree to be nicer, sounds like it doesn’t suffer the same risk. But there is the added inconvenience of installing it - but usually mild given prebuilt binaries for common distributions.

            • quotemstr 9 months ago

              ldd's shortcomings have been well known for years, but here we are. Same with strncpy. It's remarkable how sticky some tools are in people's muscle memory and how hard it is to eradicate these bad tools even when drop in alternatives are within reach. Habit is powerful.

              • ReleaseCandidat 9 months ago

                > strncpy

                strncpy had been touted the "safe strcpy alternative" for years.

                • pjmlp 9 months ago

                  Which also isn't one, it only appears to be.

              • aleden 9 months ago

                Disentangling who loads what without actually running the app, i.e. allowing a sequence of dlopen() calls to succeed, seems impossible to accomplish in the presence of binary code which cannot be effectively scrutinized.

                • ReleaseCandidat 9 months ago

                  It's not about calling the app itself - that doesn't happen with ldd. ldd does not know about dlopened libraries.

                  • aleden 9 months ago

                    I guess I wasn't sure that DT_NEEDED entries covered everything. Sometimes you have stuff that happens in DT_INIT constructors.

                    • ReleaseCandidat 9 months ago

                      Dynamic dlopen calls do not appear in the ELF at all, these are "normal" function calls.

                      • sim7c00 9 months ago

                        correct. you cam call dlopen anywhere so loading it into memory or even executing all easy to reach paths wont guarantee you'd get that. you might do full symbolic execution but your 'ldd' might take days or weeks :'D

                        • aleden 9 months ago

                          My model for LDD in my head was, "run the app up until the entry point of the executable, print the loaded DSOs, and exit() before ever starting the exe." That'd get you potentially more libraries than if you just statically examine the needed libraries recursively.

                          • sim7c00 9 months ago

                            I think in this case, you might be able to resolve the ones in DT_NEEDED on the disk, and parse those elf headers, and do that until they don't have any DT_NEEDED in there anymore which you didn't touch.

                            The reason it doesn't find all with a simple elf-parse is that included libs might depend on other libs. I'd say if your linker can figure out before executing anything after the entry-point what to resolve, it has read it from ELF files it has seen by parsing the initial executable.

                            I was really surprised honestly to see LDD executes stuff, but I suppose it's a very old thing, from before 'untrusted' executables were really a (big) thing.

                • anthk 9 months ago

                                objdump -x /path/to/binary | grep NEEDED
                  • ReleaseCandidat 9 months ago

                    It's not same, as ldd does print transitive dependencies too. libtree is comparable to ldd

                    • anthk 9 months ago

                      True; but you can write a recursive parser with awk.

                  • ChoHag 9 months ago

                    [flagged]

                    • quotemstr 9 months ago

                      Nah. That's not GNU. It's just the industry. Proprietary stuff can be even worse. Remember how Windows conhost has a crappy rectangle text selection model for literally two decades until Microsoft overcame their stubbornness and fixed it? Being a stick in the mud isn't a feature of GNU in particular. It's an element of human nature.

                      • anthk 9 months ago

                        How does LDD behave in {net,open,free}bsd?

                      • Asooka 9 months ago

                        You are getting downvoted, but you're absolutely correct. This is the usual disposition of Unix devs in general I've found. People forever stuck in the mentality that the computer is a personal toy, only for running your code and OS code, who refuse to grow up and accept responsibility for maintaining software useful in the real world. When you point it out they just act like piss-babies, cry and shout until they get their way. We put up with using code that is, as their license reminds us, "without [...] FITNESS FOR A PARTICULAR PURPOSE", simply because the amount of basic operating system services we'd have to rewrite to get rid of them is an extremely daunting task. Hopefully the Rust project can spur some development into replacing GNU and other similar shit, so we can be rid of the drooling retards for good.

                        • anthk 9 months ago

                          Rust is no magic. A bug in the runtime = the whole castle rumbles down.

                          And GNU is no Unix. You are very confused about what GNU is. Is not Linux, Linux it's a transitional kernel. Hurd, to begin width, has modular drivers able to be run in userspace and it has namespaces (a la plan9) making it potentially far more secure and not needing neither SUID or group perms to achieve mundane tasks such as mounting a volume.

                          GNU was born to provide the ITS freedoms such as Emacs and Lisp on top of a more secure kernel based on Unix to solve random memory access violations potentially made from concurrent users running Lisp interpreters. ITS was like that, every user could capture and debug every other one's processes, even the system ones. But the 80's had a different mindset, and Unix ruled the academia and military.

                          GNU was made to give more power to the user, it has both a microkernel design and daemons/namespaces to be able to do more stuff by themselves without misconfiguring the system.

                          Linux was just a good enough kernel to put GNU in the 90's as Hurd wasn't (and still isn't albeit today it's a bit more usable) near complete. So, they began to promote GNU/Linux until GNU/Hurd got finished.

                          • kazinator 9 months ago

                            There's nothing in it for GNU, I'm giving it all to Liiinux.

                            Apologies to Billy Joel.

                          • quotemstr 9 months ago

                            Rust is a young ecosystem. Give it time. It'll ossify too, just like every other previous software ecosystem. We make progress only through continual cycles of replacement and renewal, usually by fresh eyes and fresh hands each cycle. It's always been this way and always will be. One day, Rust will be the difficult to replace ancestral crud.

                            • secondcoming 9 months ago

                              Have you tried to address any of these issues yourself, or are you just going to wait for someone else to do it?

                              • ChoHag 9 months ago

                                [dead]

                            • blueflow 9 months ago

                              Why do people a) have these preconceptions, b) have them be accurate enough to work at all, and c) get away with shouting "but POLA" when they don't work out?

                              • juped 9 months ago

                                I'm astonished that this melted sand performs computations, but Shockley closed my CVE "not a bug"