How to change tty group on Linux (build with buildroot) - linux

I'm working on Linux Kernel 3.14.28 build with Buildroot for an embedded device.
In /dev/, all ttys are root:root and not root:dialout like a standard Linux. So it is not possible to access any ttyX without being logged as root.
How can I change the tty group permanently to root:dialout? I try to change it with chown command, but it became root:root again on reboot.

TL;DR: choose mdev as your device manager, and use the tty group instead of dialout.
The kernel's devtmpfs creates device nodes with a default name, owner and permissions. It also sends out a uevent when the node is created, which allows a uevent handler to change the name, ownership or permissions, or do anything else it wants. Previously this was called the hotplug system, but nowadays it's much more generic.
Buildroot offers the choice between three uevent handlers: mdev, which is part of busybox, eudev which is a standalone udev fork, and udev which is part of the systemd init system. These handlers are configured with rules files that specify what to do with a specific type of device when it appears.
For your specific need, mdev is the best choice since it is very simple, easy to understand, doesn't take up much space, and the default configuration is sufficient. In Buildroot's menuconfig, go to System configuration → /dev management and select Dynamic using mdev. Then rebuild your root filesystem. It will now be populated with the mdev binary (part of busybox), an init script to start it, and a default rules file in /etc/mdev.conf. This default file contains:
tty[0-9]* root:tty 660
This means that the tty devices will get their group changed to tty and their permissions to group read and write. So you can just make sure that the logged in user belongs to the tty group, and Bob's your uncle.
If the default mdev.conf file is not sufficient for you (for instance, if you really need the group to be dialout), then you can create a filesystem overlay, copy package/busybox/mdev.conf to /etc/mdev.conf and modify it as needed. Full documentation on the mdev.conf format can be found in the busybox sources.

devtmpfs always sets permissions to 0600 and makes it up to udev (or whatever runs after it) to maintain them. Its source confirms there's no way to override this explicitly (tty device driver overrides mode unconditionally in some cases).
Assuming you're using the Buildroot's default busybox as init, there's a way to do this with the following additional line in busybox's inittab (additional=must be present in addition to the essential lines (or their replacements) that are implied when there's no inittab - as they are no longer implied then there is):
::sysinit:<path_to_your_script>
with the script calling chown and chmod in loop.
But, it's better to handle this within the existing /etc/init.d/rcS (which is also run by BusyBox's init at sysinit by default).
As you can see from the stock buildroot's /etc/init.d/rcS, all you need to do is create a script /etc/init.d/S<whatever>.sh (where "whatever" places it into the desired position in the /etc/init.d/S??* output) with your commands:
for tty in /dev/tty*; do
chown root:dialout "$tty"
chmod ug+rw "$tty" #do not touch other bits
done
unset tty

Related

Creating a named FIFO using systemd-tmpfiles as non-root user

I want to create a named FIFO using systemd-tmpfiles as specified in the manual at tmpfiles.d | p,p+. I am able to create the fifo but the issue is with the user and group of that named fifo. Here is how I am defining it in conf file:
p+ /run/reboot 0644 system system - -
But the fifo is always created as root.root even if I specify it as system system in the conf file.
If I run the systemd-tmpfiles-setup.service script after bootup, then it the fifo is with system.system privileges.
/bin/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev
So, either systemd-tmpfiles is creating it as root.root at bootup or some other service is changing permissions (not systemd-udev-trigger - tried masking this but no change).
For debug purpose, I ran this script (lsing) as ExecStartPort of systemd-tmpfiles-setup.service which does ls -la on /run and writes to /run/lsing.txt. Even there, I see the fifo is root.root,
ExecStartPost=/sbin/lsing
Need some help in debugging this issue. I am quite new to systemd.

modify kernel parameters in linux without using sysctl

I have an embedded system. An old linux OS runs on it. When i enter "uname -r" command i get the version information as "3.3.8-3.4".
I want to modify some of network kernel parameters (increase tcp receive buffer size etc.) in /proc/sys. But sysctl command does not exist in this old linux kernel version. Also sysctl.conf does not exist under /etc directory
I tried changing kernel parameter files manually but system does not allow this operation even for super user.
How can i modify kernel parameters in this linux version?
You can use /proc/sys. For example the following command:
echo 1 > /proc/sys/net/ipv4/ip_forward
... is basically the same as
sysctl -w net.ipv4.ip_forward=1
However, you'll need to make sure on your own that parameters will be set on boot.

Buildroot - built a file system, how to login? boot hangs

Can someone help me to understand how I need to configure buildroot, so that I will be able to successfully boot my own file system and login to it ?
I have a (seemingly) working kernel, and now I created my own file system (didn't change any settings in build root really, except set console to ttyAMA0), but the boot process just seems to hang without any problems to this:
....
[ 3.130000] VFS: Mounted root (ext3 filesystem) on device 179:2.
[ 3.140000] Freeing init memory: 144K
Starting logging: OK
Starting network...
ip: RTNETLINK answers: Operation not permitted
ip: SIOCSIFFLAGS: Permission denied
Whole boot log is visible here: http://paste.ubuntu.com/1364407/
I understand that /etc/inittab controls the boot process, the contents looks like this:
# Startup the system
null::sysinit:/bin/mount -t proc proc /proc
null::sysinit:/bin/mount -o remount,rw / # REMOUNT_ROOTFS_RW
null::sysinit:/bin/mkdir -p /dev/pts
null::sysinit:/bin/mkdir -p /dev/shm
null::sysinit:/bin/mount -a
null::sysinit:/bin/hostname -F /etc/hostname
# now run any rc scripts
::sysinit:/etc/init.d/rcS
# Put a getty on the sttyAMA0::respawn:/sbin/getty -L ttyAMA0 115200 vt100 # GENERIC_SERIAL
# Stuff to do for the 3-finger salute
::ctrlaltdel:/sbin/reboot
# Stuff to do before rebooting
null::shutdown:/etc/init.d/rcK
null::shutdown:/bin/umount -a -r
null::shutdown:/sbin/swapoff -a
Any advice on what is wrong in my configuration ?
Any tips on where I could get a good overview of "the usual necessary configurations" needed when creating my own linux system ?
This problem was raised by the submitter on the Buildroot mailing list. The solution was that the submitter was using Buildroot the contents of output/target directory directly as its root filesystem, even though the Buildroot documentation explicitly tells not to do so. This is because Buildroot does not run as root, and therefore cannot create device files or adjust permissions/ownerships properly in output/target. These steps are done when creating the root filesystem images, thanks to a magic tool called fakeroot.
Therefore, if someone wants the root filesystem to extract on a SD card partition or something like that, one should ask Buildroot to generate a tar image, and then extract it as root in the SD card partition.
Since this problem was quite common, we have now added a file in output/target called THIS_IS_NOT_YOUR_ROOT_FILESYTEM which contains details about this issue. See http://git.buildroot.net/buildroot/commit/?id=9226a9907c4eb0fffab777f50e88b74aa14d1737.

Accessing the GPIO (of a raspberry pi) without ``sudo``

This question might not be specific to the raspberry pi, of course. Also, I'm relatively new to Linux.
I want to write a little library (in node.js, if that matters) to access the GPIO of the raspberry pi using the sysfs. However, accessing the sysfs requires sudo access, and that's bad for obvious reasons.
Quick2Wire seems to have a solution, but I want to understand it better and not just blindly use it. They've used C of course, but from what I understand, the code isn't complex, and probably can be pulled off with just bash, even if less elegantly. However, more than anything, I'm not sure why it works.
Any help will be great.
Edit: Thanks for the comments. It's clear I need to rephrase the question. Here goes:
How is it that once installed (as root), the app doesn't require any more root perms to use? How does adding someone to a group help in this case? /sys/devices/virtual/gpio isn't the location where the gpio sysfs is available, so what's the trickery with that? I'm really a n00b, so these questions might be n00b-ish, so please bear with me.
Rakesh, I've just been trying to figure out exactly the same thing, and I think I've solved it.
You don't need to understand much of the makefile at all. The important lines are the following, which are executed in bash when you run sudo make install
install: install-files
groupadd -f --system gpio
chgrp gpio $(DESTDIR)/bin/gpio-admin
chmod u=rwxs,g=rx,o= $(DESTDIR)/bin/gpio-admin
groupadd -f --system gpio creates a system group called gpio. chgrp gpio $(DESTDIR)/bin/gpio-admin changes the group of the binary (which the C file gpio-admin.c was compiled to) to gpio. The owner of the binary is still root (since you're running make as root.) chmod u=rwxs,g=rx,o= $(DESTDIR)/bin/gpio-admin does two important things. Firstly, it lets a member of the gpio group run gpio-admin. Secondly, it sets the setuid bit on gpio-admin.
When you add yourself to the gpio group, you can run gpio-admin, without using sudo, but gpio admin will act like it is being run under sudo. This allows it to write to the /sys/class/gpio/export file. It also allows it to change the owner of the files /sys/class/gpio/gpio[pin number]/direction etc. that get created.
Even if you change the group of /sys/class/gpio/export to gpio, and set permissions to allow you to write to it
sudo chgrp gpio /sys/class/gpio/export /sys/class/gpio/unexport
sudo chmod g+rwx /sys/class/gpio/export /sys/class/gpio/unexport
you can export a pin without superuser powers
echo 22 > /sys/class/gpio/export
but the files /sys/class/gpio/gpio22/direction etc. will still be create with root as the owner and group, and you'll need to use sudo to change them. Also, ownership of the export and unexport files will revert to root after each reboot.

udev: device connected at boot time

I'm using udev to detect USB drive connection and disconnection on my Ubuntu 10.04 LTS x64 server. Everything works fine when USB devices are connected while the machine is running, but if one is already present at boot time, my script does not complete, apparently because mkdir /tmp/blah doesn't work.
If I subsequently type sudo udevadm trigger at the terminal, everything is okay.
I'm assuming that at the point that udev first evaluates connected devices against its rules, the root filesystem has not been mounted.
My questions are therefore:
Have I correctly identified the problem?
Is there a standard way to solve it - i.e. is there an alterative to /tmp/ that I can use both
before and after / has been mounted?
The root filesystem is mounted, but is read-only at the time. /dev/shm (an in-memory filesystem) should be available; newer linux distributions may also have a /run ramdisk. You can also pick a permanent directory somewhere, mount a tmpfs over it in your script, and do your work there.
One solution to this problem is to write a script that's called by your udev rules that immediately detaches, and waits for some event to occur to ensure the system is "booted enough" to create mount points, etc. to mount your devices. The person who answered the following post (http://superuser.com/questions/53978/ubuntu-automatically-mount-external-drives-to-media-label-on-boot-without-a-u) wrote a script that checks if "httpd" is running before continuing on. I'm sure there are probably other "better" ways to do this too.
1- I don't know, even in the initramfs, before the root filesystem is mounted, there is a writable /tmp directory.
True, when the real root is mounted this /tmp will be discarded and the final /tmp will be empty. Are you sure that the mkdir /tmp/blah command is failing? Or do you assume that because it is not there when you look for it?
2- In Ubuntu (I don't know of other distros) you have a hidden directory in /dev/.initramfs for these kind of needs. Since /dev is a tmpfs (or devtmpfs) mountpoint preserved in final root filesystem you will still have it there.

Resources