On 2024-03-27, at 10:48:45 +0100, Dr. Burkard Lutz wrote:
> Am Dienstag, dem 26.03.2024 um 17:03 +0000 schrieb Jeremy Sowden:
> > [...]
> > 
> > The following should suffice:
> > 
> >   export DH_VERBOSE = 1
> >   export DEB_BUILD_MAINT_OPTIONS = hardening=+all
> >   export DEB_LDFLAGS_MAINT_APPEND = -lstdc++fs
> > 
> >   %:
> >           dh $@ --with autoreconf
> > 
> 
> So, this is exactly what I had initially.
> 
> > Running the build one can see:
> > 
> >   g++ [...] -D_FORTIFY_SOURCE=2 [...]
> > 
> > so the right argument is being passed to the compiler. 
> >  There is a list
> > of the functions that are fortified here:
> > 
> >  
> > https://www.gnu.org/software/libc/manual/html_node/Source-Fortification.html
> > 
> > Does the software use any of these?  If not, this is a false
> > positive.
> > 
> > J.
> 
> Galvani only uses "open" for file operations and "read" to read from
> usb devices.
> 
> I'm a bit confused now. The output of "blhc galvani_0.34-1_amd64.build"
> is empty, but "hardening-check -vR /usr/bin/galvani" gives:
> ------------------------------------
> /usr/bin/galvani:
>  Position Independent Executable: yes
>  Stack protected: yes
>  Fortify Source functions: no, only unprotected functions found!
>       unprotected: read
>       unprotected: memcpy
>       unprotected: readlink
>       unprotected: vsnprintf
>       unprotected: memset
>       unprotected: memmove
>       unprotected: realpath
>       unprotected: getcwd
>  Read-only relocations: yes
>  Immediate binding: yes
>  Stack clash protection: unknown, no -fstack-clash-protection
> instructions found
>  Control flow integrity: no, not found!
> --------------------------------------
> followed by a long list.

I've take a closer look and I don't think you have anything to worry
about.  Lintian's complaint relates to five unfortified function symbols
in the galvani binary:

    getcwd
    read
    vsnprintf
    realpath
    readlink

hardening-check(1) lists an additional three.  Of the eight, the galvani
source itself only includes one of them: read(2).  The other are
presumably being pulled in via inline functions or templates from header
files or similar mechanisms.  Furthermore, the hardening-check(1) man-
page explains that:

    When an executable was built such that the fortified versions of the
    glibc functions are not useful (e.g. use is verified as safe at
    compile time, or use cannot be verified at runtime), this check will
    lead to false alarms.

There is one read(2) call (in mess.cxx):

    std::string Multimeter::readfrom_dmm ()
    {
        std::string mwert, extra_str;
        std::string error_str;
        char buffer[1024];
        std::string poll;

        if (scpi) 
        {
            dmm_polling = true;
            poll = "MEAS?"; 
        }
        else poll = "D";
        
        if (usb)
        {
            if (dmm_polling) writeto_dmm (poll);
            int result = read(usb_port, buffer, 1024);

and it is straightforward for the compiler to verify that it will not
overrun the buffer.

I believe your original rules file was fine.  The correct hardening
flags were being passed.  The fact that there were unfortified function
symbols in the resulting binary was down to the tool-chain and not
anything you were doing wrong.

J.

Attachment: signature.asc
Description: PGP signature

Reply via email to