lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 27 Nov 2019 11:10:08 +0100
From:   Mathieu Maret <mathieu.maret@...il.com>
To:     dmitry.torokhov@...il.com, rydberg@...math.org,
        linux-input@...r.kernel.org
Cc:     linux-kernel@...r.kernel.org, mmaret@...ium-vision.com
Subject: BUG: ff_effects lost after a fork

Hi,

I'm using evdev for vibrator interface.
I can register ff_effect and play them.
But, if I do any kind of fork, all the effects are flush and cannot be
used.

You can find, below, an example of such a program.
>From some trace have put in the kernel, it's seems that at the end of
the system() call, evdev_flush get called.

evdev_flush() will call flush_effects() that will remove all the
registered effects.

I've only one device with vibrator and it's a imx6 4.1.15 kernel. But
code looks the same that in linus master that why I'm posting it here. I
hope that it will not waste people time

For the moment, I'm using this nasty workaround:

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index e578a75..6e6002d 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -415,6 +415,8 @@ static int evdev_release(struct inode *inode, struct file *file)
 	struct evdev_client *client = file->private_data;
 	struct evdev *evdev = client->evdev;

+	evdev_flush(file, NULL);
+
 	mutex_lock(&evdev->mutex);
 	evdev_ungrab(evdev, client);
 	mutex_unlock(&evdev->mutex);
@@ -1107,7 +1109,7 @@ static const struct file_operations evdev_fops = {
 	.compat_ioctl	= evdev_ioctl_compat,
 #endif
 	.fasync		= evdev_fasync,
-	.flush		= evdev_flush,
+//	.flush		= evdev_flush,
 	.llseek		= no_llseek,
 };


* C program example


#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

#define DEV_PATH "/dev/input/event1"

int main(int argc, char *argv[])
{
    int fd = open(DEV_PATH, O_RDWR);
    if (fd < 0) {
        printf("Cannot open " DEV_PATH);
    }

    // Register an effect
    struct ff_effect effects;
    memset(&effects, 0, sizeof(effects));
    effects.type                      = FF_RUMBLE;
    effects.id                        = -1;
    effects.u.rumble.strong_magnitude = 0x8000;
    effects.u.rumble.weak_magnitude   = 0;
    effects.replay.length             = 1000;
    effects.replay.delay              = 0;

    if (ioctl(fd, EVIOCSFF, &effects) < 0) {
        printf("Cannot upload effect %s\n", strerror(errno));
        return -1;
    }

    // Play this effect
    struct input_event input;
    memset(&input, 0, sizeof(input));
    input.type  = EV_FF;
    input.code  = effects.id;
    input.value = 1;
    if (write(fd, &input, sizeof(input)) != sizeof(input)) {
        printf("Cannot write %s\n", strerror(errno));
        return -1;
    }

    printf("Forking\n");
    system("sleep 1"); // Comment this line to have the second effect
    played

    // Play effect again : Nothing is played
    memset(&input, 0, sizeof(input));
    input.type  = EV_FF;
    input.code  = effects.id;
    input.value = 1;
    if (write(fd, &input, sizeof(input)) != sizeof(input)) {
        printf("Cannot write %s\n", strerror(errno));
        return -1;
    }


    close(fd);
    return 0;
}

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ