Linux device driver: how to assign group/user permission and use it? - linux-kernel

I know we can assign permission to device driver to run on root/group/user mode using udev config scripts but I am not sure how to run program which is using driver in Android HAL to run in specific user mode? I could execute program only after I executed chmod 777 on /dev/ttyOx.
I saw Bluetooth module in udev config in Android scripts using like this
chmod 0660 /dev/ttyO1
chown system system /dev/ttyS0
My question is , how can program using specific driver can be registered to specific group or user permission such as Bluetooth in above scripts and make only that specific program to use device driver?

Disclaimer:: I am not a Android programmer. I use Linux kernels only.
But I still believe, the drivers can be loaded in to kernel only by privileged user.i.e super user/ root.
/dev/ttyO1 and /dev/ttyS0 are device files only. which will be opened by user space applications. so setting permission to these device files is possible.
It is not possible to assign a particular driver to a specific group/user. All drivers are LKM(Loadable Kernel Modules) i.e inserted in to kernel.
Kernel runs in privileged mode. User has no direct dealing with kernel. It is restricted by space(User space/Kernel space).
In script you can check the current user and decide whether allow or not to load the blue-tooth driver.

Related

How to Enable/Disable a Device in Device Manager in Windows through its API?

I started learning AutoHotKey and wanted to know if it was possible to write a script that allows me to enable/disable a device in device manager without having to manually unplug/plug the device from the computer. I wasn't sure if I needed to run the script on the command line and somehow access the API of the Device Manager through there and write one/two lines of code that allows to enable/disable. I did stumble across the API: DeviceIoControl. I think I can get the handle of the device by using the CreateFile function that has the name of the device. The problem is I'm not sure how to properly use the name of the device in order to enable/disable it.

On macOS, is it possible to reserve input from an HID for a python program?

I want to give exclusive access to the input coming from a LASER barcode (point and trigger type) reader to a Python 3.6 program; that is, no other program should get input from the reader, regardless of UI focus (because the python program has already claimed the device for itself only.)
I've been able to this just fine on a Linux machine using Python 3.6 and pyusb library, but I can't replicate the funcionality in macOS, I get an error stating that I have insufficient permissions.
This actually happens in Linux too but it is easily worked-around by adding the current user to dialout group and creating udev rules file in /etc/udev/rules.d/99-usb.rules granting permissions to a user or group with this rule:
SUBSYSTEMS=="usb", ENV{DEVTYPE}=="usb_device", GROUP="dialout", MODE="0666"
How can equivalent permissions be granted on macOS?
Example code does exatcly what I want on Linux, but fails completely on macOS:
import usb.core
import usb.util
device = usb.core.find(idVendor=0x0519, idProduct=0x2017)
if device.is_kernel_driver_active(0):
device.detach_kernel_driver(0)
print("Kernel driver detached")
else:
print("Kernel driver already detached")
try:
device.set_configuration()
device.reset()
usb.util.claim_interface(device, 0) # error happens here
print("Claimed device")
except Exception as e:
print("Error when claiming device", e)
sys.exit(1)
From what I've found on the Web, It doesn't seem like macOS has an equivalent mechanism to grant this access.
Error on macOS:
[Errno 13] Access denied (insufficient permissions)
From what I've learned since this question was originally posted, you can reserve input from any USB device, as long as it supports "serial mode", if your device can be switched to this mode then the OS can treat it differently from the default HID mode, and you'll be able to grab it's input, even exclusively.
Disclaimer:
I havent' had a chance to fully test this as of posting this answer. Just wanted to give a quick update to any one interested.

Doing sector-level disk I/O in OS X with user privileges

I'm writing an application that is going to essentially be a sector-level disk eraser for external storage devices. It looks like the only way to do this is to work with the /dev/rdisk* devices in the filesystem. The problem is that only root can write to /dev/rdisk* so the application would have to be started with elevated privileges or it wouldn't work.
The thing is that Disk Utility is able to work at that level (because it can create filesystems) without any privilege escalation. I'm wondering how that is accomplished because I haven't really seen anything on Apple's website about it. Are they using some kind of trusted system call from Disk Utility down to the kernel level to enable this kind of functionality?
You'll need to have root permission to access the disk sectors. Disk Utility basically relies on storagekitd helper daemon which is running as root to do the low-level stuff.

How to remove /disable the 8250.o module and implement my own 8250 driver

I would like to disable or remove 8250.c (low level UART driver) module and to implement the same with basic functionally so as it will perform read and write request from user-space
Here are my questions :
How to remove / disable the 8250.0 module
If possible give me some reference links / examples to implement the 8250 driver with basic functionality.
I am newbie for Linux device driver, excuse myself if I am wrong. I have googled a lot but didn't get the proper solution
Answer 1)
If your current system has 8250 driver built as module, just unload it:
$ lsmod | grep 8250
# rmmod 8250-driver-name
(I don't checked the exact name of the driver)
If your current system has 8250 driver built within the kernel (or you are building the Linux kernel for a new system), you must compile the kernel. You must edit your current configuration end remove the driver. You can use:
$ make xconfig
or
$ make menuconfig
for a graphic interface (run one on these commands inside the Linux kernel source).
You can also manually edit the .config file and remove the driver
CONFIG_SERIAL_8250=n
or compile it as module by setting:
CONFIG_SERIAL_8250=m
(it is not recommended for this driver, read the documentation with xconfig or menuconfig)
If you already have a working configuration file, you can copy it in your kernel source as .config
cp /path/to/you/config/file /path/to/your/kernel/source/.config
then, edit the field CONFIG_SERIAL_8250 as above.
Answer 2) The best example that I can link is the 8250.c driver. But if you want learn how to develop Linux driver, you can read Linux Device Driver

Why is the root filesystem is loaded into a ramdisk?

I am studying the boot process in Linux. I came across this sentence "RAM is several orders of magnitude faster than a floppy disk, so system operation is fast from a ramdisk"
The kernel will anyway load the root filesystem in RAM for executing it. So my question why do we need a ramdisk for loading the root filesystem, if the kernel loads the root file system into RAM ?
The documentation for SUSE Linux provides a good explanation of why Linux is booted with a RAMDisk:
As soon as the Linux kernel has been
booted and the root file system (/)
mounted, programs can be run and
further kernel modules can be
integrated to provide additional
functions. To mount the root file
system, certain conditions must be
met. The kernel needs the
corresponding drivers to access the
device on which the root file system
is located (especially SCSI
drivers). The kernel must also contain
the code needed to read the file
system (ext2, reiserfs, romfs, etc.).
It is also conceivable that the root
file system is already encrypted. In
this case, a password is needed to
mount the file system.
For the problem of SCSI drivers, a
number of different solutions are
possible. The kernel could contain all
imaginable drivers, but this might be
a problem because different drivers
could conflict with each other. Also,
the kernel would become very large
because of this. Another possibility
is to provide different kernels, each
one containing just one or a few SCSI
drivers. This method has the problem
that a large number of different
kernels are required, a problem then
increased by the differently optimized
kernels (Athlon optimization, SMP).
The idea of loading the SCSI driver as
a module leads to the general problem
resolved by the concept of an initial
ramdisk: running user space programs
even before the root file system is
mounted.
This prevents a potential chicken-or-egg situation where the root file system cannot be loaded until the device on which it is located can be accessed, but that device can't be accessed until the root file system has been loaded:
The initial ramdisk (also called initdisk or initrd) solves precisely the problems described above. The Linux kernel provides an option of having a small file system loaded to a RAM disk and running programs there before the actual root file system is mounted. The loading of initrd is handled by the boot loader (GRUB, LILO, etc.). Boot loaders only need BIOS routines to load data from the boot medium. If the boot loader is able to load the kernel, it can also load the initial ramdisk. Special drivers are not required.
Of course, a RAMDisk is not strictly necessary for the boot process to take place. For example, you could compile a kernel that contained all necessary hardware drivers and modules to be loaded at startup. But apparently this is too much work for most people, and the RAMDisk proved to be a simpler, more scalable solution.
The reason that most Linux distributions use a ramfs (initramfs) when booting, is because its contents can be included in the kernel file, or provided by the bootloader. They are therefore available immediately at boot, without the kernel having to load them from somewhere.
That allows the kernel to run userspace programs that e.g. configure devices, load modules, setup that nifty RAID array that contains all filesystems or even ask the user for the password to his encrypted root filesystem.
When this configuration is done, the first script that is called just exec()s /sbin/init from the (now configured and available) root filesystem.
I have seen quite a few systems where the drivers themselvess for the disk controllers and the rootfs are loaded via modules in an initramfs, rather than being included in the kernel image.
You do not strictly need an initramfs to boot - if your kernel image contains all drivers necessary to access the rootfs and you don't need any special configuration or user input (like RAID arrays or encrypted filesystems) to mount it, it is often possible to directly start /sbin/init from the rootfs.
See also:
http://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
http://www.kernel.org/doc/Documentation/initrd.txt
As a side note, some systems (rescue disks, embedded and such) may use a ramfs as the root filesystem when the actual root filesystem is in a medium that may be removed or is not writable (CD, Flash MTDs etc).

Resources