[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#426000: libc6: an interrupted msgrcv() call seems to corrupt sscanf behaviour

Package: libc6
Version: 2.3.6.ds1-13
Severity: normal


I've found a behaviour difference in a C program, running correctly on 
Woody and don't in Sarge or Etch systems.

The problem is in a "%n" converter sometimes not honoured as it should 
be, this only after an interrupted IPC message receive.

I've built a testcase (see end of report) to let others reproduce it.
Running the original faulty program with electric-fence library
produced a core with a memory fault in sscanf(), but I didn't reproduce
it with the testcase.

I don't have a Sid computer to test it, but I'll try to build a chroot 
to do this.

Here is the C program testcase.c :

  Test case for a possible glibc bug.
  Frédéric Boiteux <fboiteux@calistel.com>

  Scan two times the same string for each word with a sscanf(). Between
  them, wait for an IPC message using msgrcv() ; someone should
  interrupt this message receive using SIGALRM signal, like with
  command : killall -ALRM testcase
  The second scan fails, the '%n' converter isn't honoured !

  Tested on i386 architecture :
  O.K.    on Debian GNU/Linux 3.0 (Woody), libc6 version 2.2.5-11.8
  Problem on Debian GNU/Linux 3.1 (Sarge), libc6 version 2.3.2.ds1-22sarge6
  Problem on Debian GNU/Linux 3.0 (Etch),  libc6 version 2.3.6.ds1-13

  Sample output :
string='Hello world!!!!', res=1, word='Hello', n=6
string='world!!!!', res=1, word='world!!!!', n=9
string='', res=-1, word='world!!!!', n=-1
msgrcv()=-1, errno=4
string='Hello world!!!!', res=1, word='Hello', n=6
string='world!!!!', res=1, word='world!!!!', n=-1


#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#include <errno.h>
#include <signal.h>
#include <stdio.h>

struct msgbuf {
        long int mtype;             /* type of received/sent message */
        char mtext[1];              /* text of the message */

void scan(char *string)
        int n, res;
        char word[100];

        do {
                n = -1;
                res = sscanf(string, "%s %n", word, &n);
                printf("string='%s', res=%d, word='%s', n=%d\n",
                       string, res, word, n);
                if (n >= 0) string += n;
                if ((res == 1) && (n < 0)) {
                        fprintf(stderr, "Problem!\n");
        } while (res == 1);

void nop(int sig) { }

void setsighandler(void)
        struct sigaction action;

        // set a no-op handler on SIGALRM signal
        action.sa_flags    = 0;
        action.sa_handler  = nop;
        if (sigaction(SIGALRM, &action, NULL) == -1)
                perror("Err in fonction sigaction !\n");

void msget()
        struct msgbuf msgp;
        int qid;
        int res;

        // create a message queue
	if ((qid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT)) < 0)
                perror("problem in msgget()");

        // wait for a message
	res = msgrcv(qid, &msgp, 1, 0, 0);
        // after signal receive, should return -1 and errno=4 (EINTR) 
        printf("msgrcv()=%d, errno=%d\n", res, errno);

int main(void)
        scan("Hello world!!!!"); // expected result


        scan("Hello world!!!!"); // fails

        return 0;

-- System Information:
Debian Release: 4.0
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-dev
Locale: LANG=fr_FR@euro, LC_CTYPE=fr_FR@euro (charmap=ISO-8859-15)

Versions of packages libc6 depends on:
ii  tzdata                        2007b-1    Time Zone and Daylight Saving Time

libc6 recommends no packages.

-- no debconf information

Reply to: