'Invoking xterm prompt through call_usermodehelper

Everyone,

I try to invoking xterm with the root privilege from a Linux kernel module by calling the function call_usermodehelper. My code is as follows:

char* envp[] = {"HOME=/", NULL};
char* argv[] = {"/usr/bin/xterm", NULL};

int ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);

printk(KERN_INFO "retval: %d\n", ret);

The result shows that ret is 256. I think the command is successfully carried out. However, I did not see the xterm window popped up.

Any one can help me about this issue? Or is there any other way to realize what I want?



Solution 1:[1]

I believe you are missing some necessary environment variables. Try this:

char* envp[] = {"HOME=/", "PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL};
char* argv[] = {"/usr/bin/xterm", NULL};

int ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);

printk(KERN_INFO "retval: %d\n", ret);

Solution 2:[2]

The likely reason is that the DISPLAY environment variable (along with some others) is dropped when you sudo'd to root. To work around this, you should either set the variable or pass the -display option on the command line.

You may also need to modify settings with xhost (though the usual advice seems to be simply to open it up to all, which is not good).

For related discussion:

and documentation:

Solution 3:[3]

Launching a terminal from a kernel module An example of solving the task of launching the terminal when pressing the "F12" key. Operating system CentOS Linux release 7.9.2009 (Core) [root@osi83 module_run_prog_key]# uname -r 3.10.0-1160.59.1.el7.x86_64

  1. ?reate a file scankey.c

    #include <linux/module.h>

#include <linux/init.h>

#include <linux/interrupt.h>

#include <asm/io.h> /* ??????? inb(port) */

#define SHARED_IRQ 1 //keyboard irq ... cat /proc/interrups

#define KBD_SCANCODE_MASK 0x7f

#define KBD_STATUS_MASK 0x80

static int irq = SHARED_IRQ, my_dev_id, irq_counter = 0;

module_param( irq, int, S_IRUGO );

static irqreturn_t my_interrupt( int irq, void *dev_id )

{

unsigned char scancode;

unsigned char status;

int value, valstatus;

int rc;

char *argv[] = { "/.1/gterm.sh", "\n", NULL };

char *envp[] = { "PATH=/sbin:/bin:/usr/sbin:/usr/bin", "DISPLAY=:0.0",NULL };

irq_counter++;

status = inb(0x64); // cat /proc/ioports | grep keyboard

scancode = inb(0x60);// cat /proc/ioports | grep keyboard

value = (int)scancode & KBD_SCANCODE_MASK;

valstatus = (int)scancode & KBD_STATUS_MASK;

printk( KERN_INFO "In the ISR: counter = %d, key=%d, status%d\n", irq_counter, value , valstatus);

    if(value==88) // Code of key "F12"

    {

         rc = call_usermodehelper( argv[0], argv, envp, 0 );

         printk(KERN_INFO "retval: %d\n", rc);

     if( rc )

     {

      printk( KERN_INFO "failed to execute : %s\n", argv[ 0 ] );

      return rc;

     }

         printk( KERN_INFO "execute : %s %s\n", argv[ 0 ], argv[ 1 ] );


    while(!valstatus)

    {

     scancode = inb(0x60);

     valstatus = (int)scancode & KBD_STATUS_MASK;

    }


    }

return IRQ_NONE; /* we return IRQ_NONE because we are just observing */

}

static int __init my_init( void )

{

if ( request_irq( irq, my_interrupt, IRQF_SHARED, "my_interrupt", &my_dev_id ) )

return -1;

printk( KERN_INFO "Successfully loading ISR handler on IRQ %d\n", irq );

return 0;

}

static void __exit my_exit( void )

{

synchronize_irq( irq );

free_irq( irq, &my_dev_id );

printk( KERN_INFO "Successfully unloading, irq_counter = %d\n", irq_counter );

}

module_init( my_init );

module_exit( my_exit );

MODULE_AUTHOR( "Osintsev Alexandr, Russian, Miass city" );

MODULE_DESCRIPTION( "Start gnome-terminal on pressing "F12" key" );

MODULE_LICENSE( "GPL v2" );


***END FILE scankey.c


  1. ?reate a file Makefile

CURRENT = $(shell uname -r)

KDIR = /lib/modules/$(CURRENT)/build

PWD = $(shell pwd)

DEST = /lib/modules/$(CURRENT)/misc

TARGET = scankey

obj-m:= $(TARGET).o

default:

$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:

@rm -f *.o .*.cmd .*.flags *.mod.c *.order

@rm -f .*.*.cmd *.symvers *~ *.*~ TODO.*

@rm -fR .tmp*

@rm -rf .tmp_versions

******* END Makefile ********


  1. Create a file /.1/gterm.sh

#!/bin/bash

gnome-terminal


**END gterm.sh file


  1. Building and running the module

[root@osi83 module_run_prog_key]# make clean;make;insmod ./scankey.ko irq=1

  1. Press key "F12"...

Note: [root@osi83 module_run_prog_key]# cat /proc/interrupts CPU0 CPU1
0: 10382613 0 IO-APIC-edge timer

1: 2222 25479 IO-APIC-edge i8042, my_interrupt

8: 0 1 IO-APIC-edge rtc0 ...

...

...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mauzel
Solution 2 Thomas Dickey
Solution 3