libbsd setmode/getmode give unexpected mode_t value possibly due to uninitialised value

Bug #1659068 reported by RJVB
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
libbsd (Ubuntu)
New
Undecided
Unassigned

Bug Description

Consider the following code from the implementation (InstallCmd()) of a Tcl extension function "xinstall" that mimics the /usr/bin/install command:

        case 'm': {
            if (!objc) {
                Tcl_WrongNumArgs(interp, 1, objv, "-m");
                return TCL_ERROR;
            }
            const char *modeString = Tcl_GetString(*(++objv));
            if (!(set = setmode(modeString))) {
                char errmsg[255];

                snprintf(errmsg, sizeof errmsg, "%s: error determining file mode %s: %s",
                     funcname, modeString, strerror(errno));
                Tcl_SetResult(interp, errmsg, TCL_VOLATILE);
                return TCL_ERROR;
            }
            mode = getmode(set, 0);
            if (verbose) {
                ui_debug(interp, "%s: mode=%s umask=0%o", funcname, modeString, mode);
            }
            free(set);
            objv++, objc -= 2;
            break;
        }

I use this function in a Tcl-based build/packaging/install system on KUbuntu 14.04 with kernel 4.8.15 .
When calling this as `xinstall -v -m 775 -d foo`there are intermittent conditions ("episodes") under which I see

```
:debug:destroot xinstall: mode=775 umask=0225
:error:destroot Failed to destroot qt5-kde-angel: error renaming "/opt/local/var/lnxports/build/_opt_local_site-ports_aqua_qt5-kde-angel/qt5-kde-angel/work/destroot/opt/local/libexec/qt5/lib/pkgconfig/Qt5X11Extras.pc" to "/opt/local/var/lnxports/build/_opt_local_site-ports_aqua_qt5-kde-angel/qt5-kde-angel/work/destroot/opt/local/lib/pkgconfig/Qt5X11Extras.pc": permission denied
```

and valgrind reports

```
==20578== 46 errors in context 11 of 13:
==20578== Conditional jump or move depends on uninitialised value(s)
==20578== at 0x77CD81C: getmode (setmode.c:123)
==20578== by 0x77D240B: InstallCmd (xinstall.c:254)
==20578== by 0x4E6E2B5: TclEvalObjvInternal (tclBasic.c:3727)
==20578== by 0x4EB4F8A: TclExecuteByteCode (tclExecute.c:2414)
==20578== by 0x4EB8D6A: TclCompEvalObj (tclExecute.c:1535)
==20578== by 0x4E6FDE8: TclEvalObjEx (tclBasic.c:5296)
==20578== by 0x4EF2670: Tcl_UplevelObjCmd (tclProc.c:945)
==20578== by 0x4E6E2B5: TclEvalObjvInternal (tclBasic.c:3727)
==20578== by 0x4EB4F8A: TclExecuteByteCode (tclExecute.c:2414)
==20578== by 0x4EF2F69: TclObjInterpProcCore (tclProc.c:1763)
==20578== by 0x4E6E2B5: TclEvalObjvInternal (tclBasic.c:3727)
==20578== by 0x4EB4F8A: TclExecuteByteCode (tclExecute.c:2414)
==20578== Uninitialised value was created by a heap allocation
==20578== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20578== by 0x77CD93F: setmode (setmode.c:218)
==20578== by 0x77D23F5: InstallCmd (xinstall.c:246)
==20578== by 0x4E6E2B5: TclEvalObjvInternal (tclBasic.c:3727)
==20578== by 0x4EB4F8A: TclExecuteByteCode (tclExecute.c:2414)
==20578== by 0x4EB8D6A: TclCompEvalObj (tclExecute.c:1535)
==20578== by 0x4E6FDE8: TclEvalObjEx (tclBasic.c:5296)
==20578== by 0x4EF2670: Tcl_UplevelObjCmd (tclProc.c:945)
==20578== by 0x4E6E2B5: TclEvalObjvInternal (tclBasic.c:3727)
==20578== by 0x4EB4F8A: TclExecuteByteCode (tclExecute.c:2414)
==20578== by 0x4EF2F69: TclObjInterpProcCore (tclProc.c:1763)
==20578== by 0x4E6E2B5: TclEvalObjvInternal (tclBasic.c:3727)
```

This error tends to go away after having tried various approaches to avoid it, which hints at the effects of an uninitialised variable, or a bounds-overwrite, hence running the script through valgrind.

Ubuntu 14.04 is still at libbsd 0.6 so I backported the latest available packaging from Launchpad (0.8.3-1). Initial results are encouraging: valgrind no longer complains about setmode or getmode called from InstallCmd().

I'd like to urge you to provide an official backport of this package; the process is trivial (see my ppa:rjvbertin/misc archive).

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.