Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Dell travaille sur des pilotes de « boutons de confidentialité » physiques pour désactiver le microphone et la caméra sur Linux
Ils seront livrés avec ses ordinateurs en 2021

Le , par Stéphane le calme

10PARTAGES

7  0 
Dès l’année prochaine, Dell va fournir des « boutons de confidentialité » matériels pour désactiver la prise en charge du microphone et de la caméra. En vue de la mise sur le marché d'autres ordinateurs portables Dell dotés de ces boutons, un pilote de confidentialité Dell est en cours de préparation pour le noyau Linux.

Ces nouveaux boutons de confidentialité Dell sont essentiellement des interrupteurs d'arrêt matériels pour le flux audio du microphone et vidéo de la caméra. Le pilote de confidentialité Dell envoyé mardi par Perry Yuan (Software Principal Engineer chez Dell) aux responsables du noyau Linux consiste à manipuler les voyants appropriés et à suivre l'état des commandes matérielles, tandis que le basculement (switch) réel du support audio / vidéo est géré par le matériel.

Dans sa forme actuelle, le pilote de confidentialité Dell prend en charge la caméra et le microphone, mais le patch note également un bit "PRIVACY_SCREEN_STATUS". Vraisemblablement, Dell a l’intention d’étendre ce pilote de confidentialité à la gestion d’un filtre de confidentialité (il s’agit d’une protection qui se place devant un écran afin de restreindre la vision des données affichées de part et d’autre de l’axe de vision), ce qui n'est pas sans rappeler le PrivacyGuard de Lenovo et le code pour le filtre de confidentialité sur lequel Google travaille avec les Chromebooks Intel.


Perry Yuan indique dans son courriel : « Ajout de la prise en charge du pilote de confidentialité Dell pour la conception de confidentialité matérielle des unités Dell, qui protège la confidentialité des utilisateurs de l'audio et de la caméra à partir du hardware. Une fois le mode de confidentialité audio ou caméra activé, aucune application ne recevra de flux audio ou vidéo. Lorsque l'utilisateur appuie sur la touche de raccourci ctrl + F4, le mode de confidentialité audio est activé et la touche de raccourci de désactivation de la caméra est ctrl + F9 ».

Voici le code envoyé par les ingénieurs Dell :

Code C : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
 drivers/platform/x86/Kconfig             |  12 ++
 drivers/platform/x86/Makefile            |   4 +-
 drivers/platform/x86/dell-laptop.c       |  41 ++--
 drivers/platform/x86/dell-privacy-acpi.c | 139 ++++++++++++
 drivers/platform/x86/dell-privacy-wmi.c  | 259 +++++++++++++++++++++++
 drivers/platform/x86/dell-privacy-wmi.h  |  23 ++
 drivers/platform/x86/dell-wmi.c          |  90 ++++----
 7 files changed, 513 insertions(+), 55 deletions(-)
 create mode 100644 drivers/platform/x86/dell-privacy-acpi.c
 create mode 100644 drivers/platform/x86/dell-privacy-wmi.c
 create mode 100644 drivers/platform/x86/dell-privacy-wmi.h
 
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 40219bba6801..0cb6bf5a9565 100644
 a/drivers/platform/x86/Kconfig
 b/drivers/platform/x86/Kconfig
@@ -454,6 +454,18 @@ config DELL_WMI_LED
 	  This adds support for the Latitude 2100 and similar
 	  notebooks that have an external LED.
 
config DELL_PRIVACY
        tristate "Dell Hardware Privacy Support"
        depends on ACPI
        depends on ACPI_WMI
        depends on INPUT
        depends on DELL_LAPTOP
        select DELL_WMI
        help
          This driver provides a driver to support messaging related to the
          privacy button presses on applicable Dell laptops from 2021 and
          newer.
 
 config AMILO_RFKILL
 	tristate "Fujitsu-Siemens Amilo rfkill support"
 	depends on RFKILL
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 5f823f7eff45..111f7215db2f 100644
 a/drivers/platform/x86/Makefile
 b/drivers/platform/x86/Makefile
@@ -47,7 +47,9 @@ obj-$(CONFIG_DELL_WMI)			+= dell-wmi.o
 obj-$(CONFIG_DELL_WMI_DESCRIPTOR)	+= dell-wmi-descriptor.o
 obj-$(CONFIG_DELL_WMI_AIO)		+= dell-wmi-aio.o
 obj-$(CONFIG_DELL_WMI_LED)		+= dell-wmi-led.o
 
obj-$(CONFIG_DELL_PRIVACY)              += dell-privacy.o
dell-privacy-objs                       := dell-privacy-wmi.o \
	                                   dell-privacy-acpi.o
 # Fujitsu
 obj-$(CONFIG_AMILO_RFKILL)	+= amilo-rfkill.o
 obj-$(CONFIG_FUJITSU_LAPTOP)	+= fujitsu-laptop.o
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 5e9c2296931c..12b91de09356 100644
 a/drivers/platform/x86/dell-laptop.c
 b/drivers/platform/x86/dell-laptop.c
@@ -30,6 +30,7 @@
 #include <acpi/video.h>
 #include "dell-rbtn.h"
 #include "dell-smbios.h"
+#include "dell-privacy-wmi.h"
 
 struct quirk_entry {
 	bool touchpad_led;
@@ -90,6 +91,7 @@ static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
 static struct rfkill *wwan_rfkill;
 static bool force_rfkill;
+static bool privacy_valid;
 
 module_param(force_rfkill, bool, 0444);
 MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models");
@@ -2202,20 +2204,25 @@ static int __init dell_init(void)
 	debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL,
 			    &dell_debugfs_fops);
 
-	dell_laptop_register_notifier(&dell_laptop_notifier);
-
-	if (dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE) &&
-	    dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE)) {
-		micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE);
-		ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev);
-		if (ret < 0)
-			goto fail_led;
-	}
-
-	if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
-		return 0;
-
-	token = dell_smbios_find_token(BRIGHTNESS_TOKEN);
+    dell_laptop_register_notifier(&dell_laptop_notifier);
+
+    if (dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE) &&
+            dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE)) {
+#if IS_ENABLED(CONFIG_DELL_PRIVACY)
+        privacy_valid = dell_privacy_valid() == -ENODEV;
+#endif
+        if (!privacy_valid) {
+            micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE);
+            ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev);
+            if (ret < 0)
+                goto fail_led;
+        }
+    }
+
+    if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
+        return 0;
+
+    token = dell_smbios_find_token(BRIGHTNESS_TOKEN);
 	if (token) {
 		struct calling_interface_buffer buffer;
 
@@ -2257,7 +2264,8 @@ static int __init dell_init(void)
 fail_get_brightness:
 	backlight_device_unregister(dell_backlight_device);
 fail_backlight:
-	led_classdev_unregister(&micmute_led_cdev);
+    if (!privacy_valid)
+        led_classdev_unregister(&micmute_led_cdev);
 fail_led:
 	dell_cleanup_rfkill();
 fail_rfkill:
@@ -2278,7 +2286,8 @@ static void __exit dell_exit(void)
 		touchpad_led_exit();
 	kbd_led_exit();
 	backlight_device_unregister(dell_backlight_device);
-	led_classdev_unregister(&micmute_led_cdev);
+    if (!privacy_valid)
+        led_classdev_unregister(&micmute_led_cdev);
 	dell_cleanup_rfkill();
 	if (platform_device) {
 		platform_device_unregister(platform_device);
diff --git a/drivers/platform/x86/dell-privacy-acpi.c b/drivers/platform/x86/dell-privacy-acpi.c
new file mode 100644
index 000000000000..516cd99167c3
--- /dev/null
+++ b/drivers/platform/x86/dell-privacy-acpi.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Dell privacy notification driver
+ *
+ * Copyright (C) 2021 Dell Inc. All Rights Reserved.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+#include <linux/wmi.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include "dell-privacy-wmi.h"
+
+#define PRIVACY_PlATFORM_NAME  "dell-privacy-acpi"
+#define ACPI_PRIVACY_DEVICE	"\\_SB.PC00.LPCB.ECDV"
+#define ACPI_PRIVACY_EC_ACK	ACPI_PRIVACY_DEVICE ".ECAK"
+
+static struct platform_device *privacy_acpi_pdev;
+
+struct privacy_acpi_priv {
+    struct device *dev;
+    struct acpi_device *acpi_dev;
+    struct input_dev *input_dev;
+    struct platform_device *platform_device;
+};
+
+static int micmute_led_set(struct led_classdev *led_cdev,
+               enum led_brightness brightness)
+{
+    acpi_status status;
+
+    status = acpi_evaluate_object(NULL, ACPI_PRIVACY_EC_ACK, NULL, NULL);
+    if (ACPI_FAILURE(status)) {
+        dev_err(led_cdev->dev, "Error setting privacy audio EC ack value: %d\n",status);
+        return -EIO;
+    }
+    return 0;
+}
+
+static struct led_classdev micmute_led_cdev = {
+    .name = "platform::micmute",
+    .max_brightness = 1,
+    .brightness_set_blocking = micmute_led_set,
+    .default_trigger = "audio-micmute",
+};
+
+static int privacy_acpi_remove(struct platform_device *pdev)
+{
+    dev_set_drvdata(&pdev->dev, NULL);
+    return 0;
+}
+
+static int privacy_acpi_probe(struct platform_device *pdev)
+{
+    struct privacy_acpi_priv *privacy;
+    acpi_handle handle;
+    acpi_status status;
+    int err;
+
+    privacy = kzalloc(sizeof(struct privacy_acpi_priv), GFP_KERNEL);
+    if (!privacy)
+        return -ENOMEM;
+
+    privacy->dev = &pdev->dev;
+    privacy->platform_device = pdev;
+    platform_set_drvdata(pdev, privacy);
+    /* Look for software micmute complete notification device */
+    status = acpi_get_handle(ACPI_ROOT_OBJECT,
+            ACPI_PRIVACY_DEVICE,
+            &handle);
+    if (ACPI_FAILURE(status)) {
+        dev_err(privacy->dev, "Unable to find Dell`s EC device %s: %d\n",
+                ACPI_PRIVACY_DEVICE, status);
+        return -ENXIO;
+    }
+
+    micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE);
+    err = led_classdev_register(&privacy_acpi_pdev->dev, &micmute_led_cdev);
+    if (err < 0)
+        return -EIO;
+
+    return 0;
+}
+
+static const struct acpi_device_id privacy_acpi_device_ids[] = {
+    {"PNP0C09", 0},
+    {"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, privacy_acpi_device_ids);
+
+static struct platform_driver privacy_platform_driver = {
+    .driver     = {
+        .name   = PRIVACY_PlATFORM_NAME,
+        .acpi_match_table = ACPI_PTR(privacy_acpi_device_ids),
+    },
+    .probe      = privacy_acpi_probe,
+    .remove     = privacy_acpi_remove,
+};
+
+int privacy_acpi_init(void)
+{
+    int err;
+
+    err = platform_driver_register(&privacy_platform_driver);
+    if (err)
+        return err;
+
+    privacy_acpi_pdev = platform_device_register_simple(
+            PRIVACY_PlATFORM_NAME, -1, NULL, 0);
+    if (IS_ERR(privacy_acpi_pdev)) {
+        err = PTR_ERR(privacy_acpi_pdev);
+        goto err_platform;
+    }
+    return 0;
+
+err_platform:
+    platform_driver_unregister(&privacy_platform_driver);
+    return err;
+}
+
+void privacy_acpi_cleanup(void)
+{
+    platform_driver_unregister(&privacy_platform_driver);
+}
+
+MODULE_AUTHOR("Perry Yuan <perry_yuan@dell.com>");
+MODULE_DESCRIPTION("DELL Privacy ACPI Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/platform/x86/dell-privacy-wmi.c b/drivers/platform/x86/dell-privacy-wmi.c
new file mode 100644
index 000000000000..6c36b7ec44c6
--- /dev/null
+++ b/drivers/platform/x86/dell-privacy-wmi.c
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Dell privacy notification driver
+ *
+ * Copyright (C) 2021 Dell Inc. All Rights Reserved.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/acpi.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/wmi.h>
+#include "dell-privacy-wmi.h"
+
+#define DELL_PRIVACY_GUID "6932965F-1671-4CEB-B988-D3AB0A901919"
+#define MICROPHONE_STATUS		    BIT(0)
+#define CAMERA_STATUS		        BIT(1)
+#define PRIVACY_SCREEN_STATUS		BIT(2)
+
+static int privacy_valid = -EPROBE_DEFER;
+static LIST_HEAD(wmi_list);
+static DEFINE_MUTEX(list_mutex);
+
+struct privacy_wmi_data {
+    struct input_dev *input_dev;
+    struct wmi_device *wdev;
+    struct list_head list;
+    u32 features_present;
+    u32 last_status;
+};
+
+/*
+ * Keymap for WMI Privacy events of type 0x0012
+ */
+static const struct key_entry dell_wmi_keymap_type_0012[] = {
+    /* Privacy MIC Mute */
+    { KE_KEY, 0x0001, { KEY_MICMUTE } },
+    /* Privacy Camera Mute */
+    { KE_SW,  0x0002, { SW_CAMERA_LENS_COVER } },
+};
+
+bool dell_privacy_valid(void)
+{
+    bool ret;
+
+    mutex_lock(&list_mutex);
+    ret = wmi_has_guid(DELL_PRIVACY_GUID);
+    if (!ret){
+        return -ENODEV;
+    }
+    ret = privacy_valid;
+    mutex_unlock(&list_mutex);
+
+    return ret;
+}
+EXPORT_SYMBOL_GPL(dell_privacy_valid);
+
+void dell_privacy_process_event(int type, int code, int status)
+{
+    struct privacy_wmi_data *priv;
+    const struct key_entry *key;
+
+    mutex_lock(&list_mutex);
+    priv = list_first_entry_or_null(&wmi_list,
+            struct privacy_wmi_data,
+            list);
+    if (priv == NULL) {
+        pr_err("dell privacy priv is NULL\n");
+        goto error;
+    }
+
+    key = sparse_keymap_entry_from_scancode(priv->input_dev, (type << 16)|code);
+    if (!key) {
+        dev_dbg(&priv->wdev->dev, "Unknown key with type 0x%04x and code 0x%04x pressed\n",
+                type, code);
+        goto error;
+    }
+
+    switch (code) {
+        case DELL_PRIVACY_TYPE_AUDIO: /* Mic mute */
+            priv->last_status = status;
+            sparse_keymap_report_entry(priv->input_dev, key, 1, true);
+            break;
+        case DELL_PRIVACY_TYPE_CAMERA: /* Camera mute */
+            priv->last_status = status;
+            sparse_keymap_report_entry(priv->input_dev, key, 1, true);
+            break;
+        default:
+            dev_dbg(&priv->wdev->dev, "unknown event type %u /%u",
+                    type, code);
+    }
+error:
+    mutex_unlock(&list_mutex);
+    return;
+}
+EXPORT_SYMBOL_GPL(dell_privacy_process_event);
+
+static int get_current_status(struct wmi_device *wdev)
+{
+    struct privacy_wmi_data *priv = dev_get_drvdata(&wdev->dev);
+    union acpi_object *obj_present;
+    union acpi_object *obj_current;
+    int ret = 0;
+
+    if (priv == NULL) {
+        pr_err("dell privacy priv is NULL\n");
+        return -EINVAL;
+    }
+    /* get devices supported */
+    obj_present = wmidev_block_query(wdev, 0);
+    if (obj_present->type != ACPI_TYPE_INTEGER) {
+        ret = -EIO;
+        goto present_free;
+    }
+    priv->features_present = obj_present->integer.value;
+
+    /* get current state */
+    obj_current = wmidev_block_query(wdev, 1);
+    if (obj_current->type != ACPI_TYPE_INTEGER) {
+        ret = -EIO;
+        goto current_free;
+    }
+    priv->last_status = obj_current->integer.value;
current_free:
    kfree(obj_current);
present_free:
    kfree(obj_present);
    return ret;
}
 
static int dell_privacy_wmi_probe(struct wmi_device *wdev, const void *context)
{
    struct privacy_wmi_data *priv;
    struct key_entry *keymap;
    int ret, i, pos = 0;
 
    priv = devm_kzalloc(&wdev->dev, sizeof(struct privacy_wmi_data),
            GFP_KERNEL);
    if (!priv)
        return -ENOMEM;
 
    /* create evdev passing interface */
    priv->input_dev = devm_input_allocate_device(&wdev->dev);
    if (!priv->input_dev)
        return -ENOMEM;
 
    __set_bit(EV_KEY, priv->input_dev->evbit);
    __set_bit(KEY_MICMUTE, priv->input_dev->keybit);
    __set_bit(EV_MSC, priv->input_dev->evbit);
    __set_bit(MSC_SCAN, priv->input_dev->mscbit);
    keymap = kcalloc(
            ARRAY_SIZE(dell_wmi_keymap_type_0012) +
            1,
            sizeof(struct key_entry), GFP_KERNEL);
    if (!keymap) {
        ret = -ENOMEM;
        goto err_free_dev;
    }
    for (i = 0; i < ARRAY_SIZE(dell_wmi_keymap_type_0012); i++) {
        keymap[pos] = dell_wmi_keymap_type_0012[i];
        keymap[pos].code |= (0x0012 << 16);
        pos++;
    }
    ret = sparse_keymap_setup(priv->input_dev, keymap, NULL);
    if (ret)
        return ret;
 
    priv->input_dev->dev.parent = &wdev->dev;
    priv->input_dev->name = "Dell Privacy Driver";
    priv->input_dev->id.bustype = BUS_HOST;
 
    if (input_register_device(priv->input_dev)) {
        pr_debug("input_register_device failed to register! \n");
        return -ENODEV;
    }
 
    priv->wdev = wdev;
    dev_set_drvdata(&wdev->dev, priv);
    mutex_lock(&list_mutex);
    list_add_tail(&priv->list, &wmi_list);
    privacy_valid = true;
    if (get_current_status(wdev)) {
        goto err_free_dev;
    }
    mutex_unlock(&list_mutex);
    kfree(keymap);
    return 0;
 
err_free_dev:
    input_free_device(priv->input_dev);
    kfree(keymap);
    return ret;
}
 
static int dell_privacy_wmi_remove(struct wmi_device *wdev)
{
    struct privacy_wmi_data *priv = dev_get_drvdata(&wdev->dev);
 
    mutex_lock(&list_mutex);
    list_del(&priv->list);
    privacy_valid = -ENODEV;
    mutex_unlock(&list_mutex);
    return 0;
}
 
static const struct wmi_device_id dell_wmi_privacy_wmi_id_table[] = {
    { .guid_string = DELL_PRIVACY_GUID },
    { },
};
 
static struct wmi_driver dell_privacy_wmi_driver = {
    .driver = {
        .name = "dell-privacy",
    },
    .probe = dell_privacy_wmi_probe,
    .remove = dell_privacy_wmi_remove,
    .id_table = dell_wmi_privacy_wmi_id_table,
};
 
static int __init init_dell_privacy(void)
{
    int ret, wmi, acpi;
 
    wmi = wmi_driver_register(&dell_privacy_wmi_driver);
    if (wmi) {
        pr_debug("Failed to initialize privacy wmi driver: %d\n", wmi);
        return wmi;
    }
 
    acpi = privacy_acpi_init();
    if (acpi) {
        pr_debug("failed to initialize privacy wmi acpi driver: %d\n", acpi);
        return acpi;
    }
 
    return 0;
}
 
void exit_dell_privacy_wmi(void)
{
    wmi_driver_unregister(&dell_privacy_wmi_driver);
}
 
static void __exit exit_dell_privacy(void)
{
    privacy_acpi_cleanup();
    exit_dell_privacy_wmi();
}
 
module_init(init_dell_privacy);
module_exit(exit_dell_privacy);
 
MODULE_DEVICE_TABLE(wmi, dell_wmi_privacy_wmi_id_table);
MODULE_AUTHOR("Perry Yuan <perry_yuan@dell.com>");
MODULE_DESCRIPTION("Dell Privacy WMI Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/dell-privacy-wmi.h b/drivers/platform/x86/dell-privacy-wmi.h
new file mode 100644
index 000000000000..94af81d76e44
 /dev/null
 b/drivers/platform/x86/dell-privacy-wmi.h
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Dell privacy notification driver
 *
 * Copyright (C) 2021 Dell Inc. All Rights Reserved.
 */
 
#ifndef _DELL_PRIVACY_WMI_H_
#define _DELL_PRIVACY_WMI_H_
#include <linux/wmi.h>
 
bool dell_privacy_valid(void);
void dell_privacy_process_event(int type, int code, int status);
int  privacy_acpi_init(void);
void privacy_acpi_cleanup(void);
 
/* DELL Privacy Type */
enum {
	DELL_PRIVACY_TYPE_UNKNOWN = 0x0,
	DELL_PRIVACY_TYPE_AUDIO,
	DELL_PRIVACY_TYPE_CAMERA,
};
#endif
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
index bbdb3e860892..44bb74e4df86 100644
 a/drivers/platform/x86/dell-wmi.c
 b/drivers/platform/x86/dell-wmi.c
@@ -27,6 +27,7 @@
 #include <acpi/video.h>
 #include "dell-smbios.h"
 #include "dell-wmi-descriptor.h"
#include "dell-privacy-wmi.h"
 
 MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
 MODULE_AUTHOR("Pali Rohár <pali@kernel.org>");
@@ -410,44 +411,57 @@ static void dell_wmi_notify(struct wmi_device *wdev,
 		if (buffer_end > buffer_entry + buffer_entry[0] + 1)
 			buffer_end = buffer_entry + buffer_entry[0] + 1;
 
	while (buffer_entry < buffer_end) {
 
		len = buffer_entry[0];
		if (len == 0)
			break;
 
		len++;
 
		if (buffer_entry + len > buffer_end) {
			pr_warn("Invalid length of WMI event\n");
			break;
		}
 
		pr_debug("Process buffer (%*ph)\n", len*2, buffer_entry);
 
		switch (buffer_entry[1]) {
		case 0x0000: /* One key pressed or event occurred */
		case 0x0012: /* Event with extended data occurred */
			if (len > 2)
				dell_wmi_process_key(wdev, buffer_entry[1],
						     buffer_entry[2]);
			/* Extended data is currently ignored */
			break;
		case 0x0010: /* Sequence of keys pressed */
		case 0x0011: /* Sequence of events occurred */
			for (i = 2; i < len; ++i)
				dell_wmi_process_key(wdev, buffer_entry[1],
						     buffer_entry[i]);
			break;
	default: /* Unknown event */
			pr_info("Unknown WMI event type 0x%x\n",
				(int)buffer_entry[1]);
			break;
		}
 
		buffer_entry += len;
 
	}
    while (buffer_entry < buffer_end) {
 
        len = buffer_entry[0];
        if (len == 0)
            break;
 
        len++;
 
        if (buffer_entry + len > buffer_end) {
            pr_warn("Invalid length of WMI event\n");
            break;
        }
 
        pr_debug("Process buffer (%*ph)\n", len*2, buffer_entry);
 
        switch (buffer_entry[1]) {
            case 0x0000: /* One key pressed or event occurred */
                if (len > 2)
                    dell_wmi_process_key(wdev, buffer_entry[1],
                            buffer_entry[2]);
                break;
            case 0x0010: /* Sequence of keys pressed */
            case 0x0011: /* Sequence of events occurred */
                for (i = 2; i < len; ++i)
                    dell_wmi_process_key(wdev, buffer_entry[1],
                            buffer_entry[i]);
                break;
            case 0x0012:
#if IS_ENABLED(CONFIG_DELL_PRIVACY)
                if (dell_privacy_valid()) {
                    dell_privacy_process_event(buffer_entry[1], buffer_entry[3], 
                            buffer_entry[4]);
                } else {
                    if (len > 2)
                        dell_wmi_process_key(wdev, buffer_entry[1], buffer_entry[2]);
                }
#else
                /* Extended data is currently ignored */
                if (len > 2)
                    dell_wmi_process_key(wdev, buffer_entry[1], buffer_entry[2]);
#endif
                break;
            default: /* Unknown event */
                pr_info("Unknown WMI event type 0x%x\n",
                        (int)buffer_entry[1]);
                break;
        }
 
        buffer_entry += len;
 
    }
 
 }

Source : liste de diffusion du kernel Linux

Et vous ?

Que pensez-vous de l'idée de disposer d'un outil physique pour couper l'accès au microphone et à la caméra ?

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de yoyo3d
Membre éprouvé https://www.developpez.com
Le 05/11/2020 à 9:26
l'idée est très bonne, le nombre de fois ou j'ai douté en voyant le led de ma webcam s'allumer sans raison....
mais en ce qui me concerne, je crois sincèrement que tout programme peut être hacké à un moment ou un autre. Pour moi, la solution la moins risquée, reste l'interrupteur physique. même si l'on est pas certain qu'il fonctionne vraiment.
pas de raccourci à retenir ,
pas de code corrompu,
pas de mise à jour de driver....
je coupe ma caméra et mon micro comme je coupe le wifi sur mon portable, grâce à un petit bouton.
6  0 
Avatar de defZero
Membre extrêmement actif https://www.developpez.com
Le 05/11/2020 à 15:13
Que pensez-vous de l'idée de disposer d'un outil physique pour couper l'accès au microphone et à la caméra ?

Que c'est nécessaire.

Mais pour pousser encore la réflexion, pourquoi une caméra et un micro doivent obligatoirement être inclus dans les laptops ?
La qualité et souvent médiocre voire à peine passable et ça rajoute des frais pour du matos qui ne servira que très peu voire pas du tout.
Alors pourquoi les imposer lorsque tous les smartphones sont déjà équipé du nécessaire ?

Franchement, sur laptop, le combo micro/caméra intégré, c'est vraiment gadget, alors autant le retiré, ça réduira les possibilités de hack et ça diminuera la facture.
6  1 
Avatar de Mimoza
Membre averti https://www.developpez.com
Le 05/11/2020 à 9:33
Des constructeur le font déjà avec de vrai intérrupteur qui coupe matériellement ces périphériques : https://puri.sm/products/librem-15/

@Picarunix : Ces raccourcis sont des interrupteurs logiciel, ce n'est donc que au niveau de l'OS que les périphériques sont coupés.
4  0 
Avatar de Picarunix
Membre régulier https://www.developpez.com
Le 05/11/2020 à 9:10
Ctrl+F4 et Ctrl+F9 qui va s'en souvenir ? Je veux parler des utilisateurs courants, dans une entreprise (puisque Dell vise plutôt cette clientèle), sauront-ils retenir ces raccourcis ?
Une touche supplémentaire, du genre Marche/Arrêt, bien reconnaissable, ne serait-elle pas plus adaptée ?

Sinon je trouve que cette idée est favorable à la protection, elle permet d'être certain de ne pas être ni vu ni écouté. Bravo à Dell.
2  0 
Avatar de archqt
Membre éprouvé https://www.developpez.com
Le 06/11/2020 à 9:46
Mais pour pousser encore la réflexion, pourquoi une caméra et un micro doivent obligatoirement être inclus dans les laptops ?
La qualité et souvent médiocre voire à peine passable et ça rajoute des frais pour du matos qui ne servira que très peu voire pas du tout.
Les gens demandent assez souvent d'avoir une webcam intégrée, mais est ce la majorité je ne sais pas. La qualité certes n'est pas excellente mais c'est souvent suffisant pour de la visioconférence.
0  0 
Avatar de champomy62
Membre averti https://www.developpez.com
Le 06/11/2020 à 16:25
Citation Envoyé par archqt Voir le message
Les gens demandent assez souvent d'avoir une webcam intégrée, mais est ce la majorité je ne sais pas. La qualité certes n'est pas excellente mais c'est souvent suffisant pour de la visioconférence.
Je suis pour degager la webcam et le micro. Je prefere acheter une webcam - assez petite en dimension - car actuellement:

Je dois obstruer la vue de ma webcam mais desfois a cause de ca, ca diminue la luminosite de mon ecran.
Le micro... bah c'est le micro - difficile a bloquer.

Avec macOS tu peux regler les permissions d'acces aux webcam/micro.
0  0