Hi,

attached is a patch with a couple of related fixes to TTY handling. 
The patch was need to make DFB work in my setup when running DFB 
applications both as root and as unprivileged user and both from the 
physical terminal (/dev/tty1) and SSH login shell. Part of it is, I'm 
sorry to say, reversal of changes I suggested (these two revisions: 
http://directfb.org/index.php/viewcvs.cgi/DirectFB/systems/fbdev/fbdev.c.diff?r1=1.49&r2=1.51).

Here's more detailed description of the changes:

* Previously, the process attached itself to a new controlling TTY 
only if vt_switch option was on. This patch changes it to always 
(unless VT handling is completely disabled, of course) attach the 
process to the TTY being used by the app as the new controlling TTY. 
This is because we always need some controlling TTY, without it, there 
could be SIGHUP/SIGCONT signals (see e.g. my post about re-adding 
setpgid() call). Note that the patch moves TIOCSCTTY call outside 
of "if vt-switch" branch, but completely removes TIOCNOTTY - - that's 
because the latter is not needed, setsid() already detached the 
process from controlling TTY. So "vt-switch" now only 
controls "physical" change of the currently active console.

* /dev/tty? files are opened with O_NOCTTY. Linux kernel has a feature 
that if a process without controlling TTY opens a TTY device, it's 
made its controlling TTY, unless you use O_NOCTTY, so this change 
ensure that we only attach to the desired TTY explicitly using 
TIOCSCTTY.

* Moved TIOCSCTTY before KBSETMODE use, otherwise non-root users get 
EPERM from KBSETMODE ioctl(), because you can't do that operation on 
anything other than your controlling TTY normally.

* Removed setpgid() calls, because they interfered with setsid() later 
and weren't really necessary now that other cTTY problems were fixed. 
Ditto for the removed dfb_vt_detach() call (I couldn't find any 
information about why it was there in the first place, but everything 
works without it as far as I can tell).


I'm not sure if you'll want to include it in 1.0.0: on one hand, it 
fixes a serious problem with running as non-root user, on the other 
hand, it's not trivial change and may have some consequences I 
missed. I'd certainly appreciate a review of the patch, I'm still 
quite unfamiliar with the DFB code.

Regards,
Vaclav

-- 
PGP key: 0x465264C9, available from http://pgp.mit.edu/
Index: src/DirectFB/systems/fbdev/fbdev.c
===================================================================
--- src/DirectFB/systems/fbdev/fbdev.c	(revision 139)
+++ src/DirectFB/systems/fbdev/fbdev.c	(revision 143)
@@ -439,8 +439,6 @@
 
      shared->page_mask = page_size < 0 ? 0 : (page_size - 1);
 
-     setpgid( 0, 0 );
-
      ret = dfb_fbdev_open();
      if (ret)
           goto error;
@@ -613,8 +611,6 @@
      dfb_fbdev->core = core;
      dfb_fbdev->shared = shared;
 
-     setpgid( 0, 0 );
-
      /* Open framebuffer device */
      ret = dfb_fbdev_open();
      if (ret) {
@@ -833,9 +829,6 @@
      if (dfb_config->block_all_signals)
           direct_signals_block_all();
 
-     if (dfb_config->vt)
-          return dfb_vt_detach( false );
-
      return DFB_OK;
 }
 
Index: src/DirectFB/systems/fbdev/vt.c
===================================================================
--- src/DirectFB/systems/fbdev/vt.c	(revision 139)
+++ src/DirectFB/systems/fbdev/vt.c	(revision 143)
@@ -104,10 +104,10 @@
      dfb_vt = D_CALLOC( 1, sizeof(VirtualTerminal) );
 
      setsid();
-     dfb_vt->fd0 = open( "/dev/tty0", O_RDONLY );
+     dfb_vt->fd0 = open( "/dev/tty0", O_RDONLY | O_NOCTTY );
      if (dfb_vt->fd0 < 0) {
           if (errno == ENOENT) {
-               dfb_vt->fd0 = open( "/dev/vc/0", O_RDONLY );
+               dfb_vt->fd0 = open( "/dev/vc/0", O_RDONLY | O_NOCTTY );
                if (dfb_vt->fd0 < 0) {
                     if (errno == ENOENT) {
                          D_PERROR( "DirectFB/core/vt: Couldn't open "
@@ -325,7 +325,7 @@
           int            fd;
           struct vt_stat vt_state;
 
-          fd = open( "/dev/tty", O_RDONLY );
+          fd = open( "/dev/tty", O_RDONLY | O_NOCTTY );
           if (fd < 0) {
                if (errno == ENXIO)
                     return DFB_OK;
@@ -441,11 +441,11 @@
      /* FIXME: Opening the device should be moved out of this function. */
 
      snprintf(buf, 32, "/dev/tty%d", dfb_vt->num);
-     dfb_vt->fd = open( buf, O_RDWR );
+     dfb_vt->fd = open( buf, O_RDWR | O_NOCTTY );
      if (dfb_vt->fd < 0) {
           if (errno == ENOENT) {
                snprintf(buf, 32, "/dev/vc/%d", dfb_vt->num);
-               dfb_vt->fd = open( buf, O_RDWR );
+               dfb_vt->fd = open( buf, O_RDWR | O_NOCTTY );
                if (dfb_vt->fd < 0) {
                     if (errno == ENOENT) {
                          D_PERROR( "DirectFB/core/vt: Couldn't open "
@@ -466,6 +466,10 @@
           }
      }
 
+     /* attach to the new TTY before doing anything like KDSETMODE with it,
+        otherwise we'd get access denied error: */
+     ioctl( dfb_vt->fd, TIOCSCTTY, 0 );
+
      write( dfb_vt->fd, cursoroff_str, sizeof(cursoroff_str) );
      if (dfb_config->kd_graphics) {
           if (ioctl( dfb_vt->fd, KDSETMODE, KD_GRAPHICS ) < 0) {
@@ -478,11 +482,6 @@
           write( dfb_vt->fd, blankoff_str, sizeof(blankoff_str) );
      }
 
-     if (dfb_config->vt_switch) {
-          ioctl( dfb_vt->fd0, TIOCNOTTY, 0 );
-          ioctl( dfb_vt->fd, TIOCSCTTY, 0 );
-     }
-
      if (dfb_config->vt_switching) {
           struct vt_mode vt;
           struct sigaction sig_tty;
_______________________________________________
directfb-dev mailing list
[email protected]
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev

Reply via email to