On Sun Sep 26, 2021 at 02:36:02PM +0200, Mark Kettenis wrote:
> > Date: Fri, 24 Sep 2021 19:36:21 +0200
> > From: Rafael Sadowski <raf...@sizeofvoid.org>
> > 
> > I'm trying to port the more KDE stuff so my question is from porter
> > perspective.
> > 
> > I need sigwaitinfo(2)/sigtimedwait(2) and I found both functions in
> > lib/libc/gen/sigwait.c with the comment "need kernel to fill in more
> > siginfo_t bits first". Is the comment still up to date? If no, is it
> > possible to unlock the functions?
> 
> Still true.  These functions are somewhat underspecified by POSIX so
> it isn't really obvious whatadditional bits need to be filled in.
> Having examples of code that use these interfaces from ports could
> help with that.
> 

One use-case from kscreenlocker-5.22.5/kcheckpass/kcheckpass.c

Full code:
https://github.com/KDE/kscreenlocker/blob/master/kcheckpass/kcheckpass.c

It tries to handle SIGUSR1 and SIGUSR2. I think this can be solved in
another way, so this is a bad example, isn't it?

    /* signal_info for sigwaitinfo() */
    siginfo_t signalInfo;

    // now lets block on the fd
    for (;;) {
        conv_server(ConvPutReadyForAuthentication, 0);

            keventData = kevent(keventQueue, NULL, 0, keventEvent, 1, NULL);
            if (keventData == -1) {
                /* Let's figure this out in the future, shall we */
                message("kevent() failed with %d\n", errno);
                return 1;
            } else if (keventData == 0) {
                /* Do we need to handle timeouts? */
                message("kevent timeout\n");
                continue;
            }
            // We know we got a SIGUSR1 or SIGUSR2, so fetch it via 
sigwaitinfo()
            // (otherwise, we could have used sigtimedwait() )
            int signalReturn = sigwaitinfo(&signalMask, &signalInfo);
            if (signalReturn < 0) {
                if (errno == EINTR) {
                    message("sigawaitinfo() interrupted by unblocked caught 
signal");
                    continue;
                } else if (errno == EAGAIN) {
                    /* This should not happen, as kevent notified us about such 
a signal */
                    message("no signal of type USR1 or USR2 pending.");
                    continue;
                } else {
                    message("Unhandled error in sigwaitinfo()");
                    conv_server(ConvPutAuthError, 0);
                    return 1;
                }
            }
            if (signalReturn == SIGUSR1) {
                if (signalInfo.si_pid != parentPid) {
                    message("signal from wrong process\n");
                    continue;
                }
                /* Now do the fandango */
                ret = Authenticate(method, username, conv_server);

                if (ret == AuthBad) {
                    message("Authentication failure\n");
                    if (!nullpass) {
                        openlog("kcheckpass", LOG_PID, LOG_AUTH);
                        syslog(LOG_NOTICE, "Authentication failure for %s 
(invoked by uid %d)", username, uid);
                    }
                }
                switch (ret) {
                case AuthOk:
                    conv_server(ConvPutAuthSucceeded, 0);
                    break;
                case AuthBad:
                    conv_server(ConvPutAuthFailed, 0);
                    break;
                case AuthError:
                    conv_server(ConvPutAuthError, 0);
                    break;
                case AuthAbort:
                    conv_server(ConvPutAuthAbort, 0);
                default:
                    break;
                }
                if (uid != geteuid()) {
                    // we don't support multiple auth for setuid kcheckpass
                    break;
                }
            } else if (signalReturn == SIGUSR2) {
                if (signalInfo.si_pid != parentPid) {
                    message("signal from wrong process\n");
                    continue;
                }
                break;
        }

Reply via email to