Hi,

I am using screen to connect to  /dev/pts/X which is mapped to a VM's
serial port using QEMU.
The first time I connect to it, as a non-privilege user, the connection
went through.

However, if I connect to it again, screen immediately exists with the
"screen is terminating" message. The only way around it is sudo.

I notice also that if the first connection is with sudo, subsequent
connections as a non-privilege user also failed.

It is as if the /dev/pts/X port was put into a wrong state after initial
connection closes.

So I re-compiled with debug turned on which led me to this function where
the difference is made between the initial and the subsequent connection.

int secopen(char *name, int flags, int mode)
{
        int fd;

        xseteuid(real_uid);
        xsetegid(real_gid);
        fd = open(name, flags, mode);
        xseteuid(eff_uid);
        xsetegid(eff_gid);
        return fd;
}


The very first time I connection, open() succeeded, but subsequent ones
always return -1 with the errno of EBUSY, but I don't see anything holding
the file in lsof.
The open() API was called with the same arguments every time, so why the
different result?
I also tried using strace, but I don't see differences between the first
working connection and the subsequent failing connections.

One thing I couldn't understand is why we seteuid to real uid before
opening /dev/pts/X and reset it to effective uid afterwards? Should it be
the other way around? Set to effective uid first then reset to the real uid
?? However, this logic had been there for 5 years.. The secfopen() API also
has similar logic - set to real uid and reset to effective uid.

I took a stab and swap the seteuid order and it worked.

Is there a reason why /dev/pts/X can only be opened by a non-privilege user
once?
Am I running into a 5 years old bug?

thanks!

Reply via email to