22

I'm writing a program that displays various system information (on a CentOS system). For example, the processor type and speed (from /proc/cpuinfo), the last boot time (calculated from /proc/uptime), the IP address (from ifconfig output), and a list of installed printers (from lpstat output).

Currently, several pieces of data are obtained from the dmidecode program:

  • The platform type (dmidecode -s system-product-name)
  • The BIOS version (dmidecode -s bios-version)
  • The amount of physical memory (dmidecode -t17 | grep Size)

These are only available if my program is run as root (because otherwise the dmidecode subprocess fails with a /dev/mem: Permission denied error). Is there an alternative way to get this information, that a normal user can access?

user1024
  • 583

10 Answers10

12

Some of the information presented by dmidecode is available at /sys/devices/virtual/dmi/id.

Other information can be obtained by analysing /proc/cpuinfo, /proc/meminfo or /sys/system/node/node0/meminfo.

Mingye Wang
  • 1,181
OluaJho
  • 174
  • 1
    +1 for /sys/devices/virtual/dmi/id. Lots of platform-specific information is available there. For a handy script, see https://unix.stackexchange.com/questions/75750/how-can-i-find-the-hardware-model-in-linux/172334#172334 . For system information, your other sentence is good too. There are lots of utilities like free or even htop that can get you what you want. – Mike S Oct 25 '17 at 19:35
  • tail: cannot open '/sys/devices/virtual/dmi/id/board_serial' for reading: Permission denied I got this message. – Salem F Jul 09 '22 at 09:57
  • @SalemF Information like vendor/product/model identification and version numbers are readable for everyone, but uniquely identifying information such as serial numbers and UUIDs are available for root only. So the OP should be able to get the information they asked for. – telcoM Oct 26 '23 at 06:56
6
  1. I can read DMI information as User under /sys/class/dmi/id/. Not including serial numbers (which require root privileges to read).

    I guess this is intended behavior by privacy aware kernel developers.

  2. Regarding dmesg: dmesg is a command for accessing the kernel ring buffer. Ring buffer implies older information are overwritten by newer ones when the buffer is "overflowing". Also this is reading kernel module debug output which was never meant to be parseable.

  3. To access kernel output with systemd run:

     journalctl --quiet --system --boot SYSLOG_IDENTIFIER=kernel
    
  4. Regarding david-homer's and nils' answers: The file /dev/mem does not simply give memory information, but maps the whole physical memory into the userspace. Therefore one can access DMI memory addresses through it (and do much more nasty things).

  5. Regarding chgrp and chmod g+s of dmidecode in nils' answer: I guess this won't work as intended, because saving gid with chmod g+s doesn't make dmidecode use it's new privileges. dmidecode has to call setegid to set it's effective group id before it can access /dev/mem. Judging from it's source code, dmidecode doesn't do that.

thomas
  • 479
  • 1
    Addition to 3.: To access kernel output on systems without systemd just read /var/log/kern.log. If there's no such file while the system is still using syslogd, try looking for kern.* entries in /etc/syslog.conf to find out its location. – Ruslan Aug 27 '16 at 07:32
5

Try dmesg. I was able to get the info I wanted this way with a regular user account.

  • Not sure why you got voted down. I've placed a more verbose response based on your solution for everyone to see.

    I think your solution is fine.

    – wally Sep 03 '14 at 15:00
5

I'm not certain why @mtneagle got down-voted.

The three items the OP wanted are:

The platform type (dmidecode -s system-product-name)
The BIOS version (dmidecode -s bios-version)
The amount of physical memory (dmidecode -t17 | grep Size)

We can get each of these thusly:

dmesg | grep "DMI:" | cut -c "6-" | cut -d "," -f "1"
dmesg | grep "DMI:" | cut -c "6-" | cut -d "," -f "2"
dmesg | grep "Memory:" | cut -d '/' -f '2-' | cut -d ' ' -f '1'

(Or at least those work on the 4 different hardware servers I have, and cleanly returned nothing for BIOS or server type on a Xen guest.)

Have I missed something obvious?


Update: Thanks to @Ruslan for pointing out the obvious I missed.

Quoting:

Yes, you have. Kernel messages are stored in a ring buffer. When too many lines have been printed, first ones are deleted.

So if your machine has worked for multiple weeks, and you suspended/resumed it at least every day, high chances are that the information you grep for here will be no longer in the buffer.

(I have such a situation with uptime of 18 days here.) It may be better to look into /var/log/kern.log

Something like grep DMI: /var/log/kern.log | tail -n1

wally
  • 101
  • 3
    Yes, you have. Kernel messages are stored in a ring buffer. When too many lines have been printed, first ones are deleted. So if your machine has worked for multiple weeks, and you suspended/resumed it at least every day, high chances are that the information you grep for here will be no longer in the buffer. (I have such a situation with uptime of 18 days here.) It may be better to look into /var/log/kern.log. Something like grep DMI: /var/log/kern.log | tail -n1. – Ruslan Aug 26 '16 at 21:52
  • Thanks - I hope you don't mind, I've included your comment in my answer (with credit). – wally Aug 27 '16 at 15:30
5

I just checked on my CentOS 5 system - after:

chgrp kmem /usr/sbin/dmidecode
chmod g+s /usr/sbin/dmidecode

It is still not possible to get dmidecode working - the group kmem has only read-rights for /dev/mem - it seems there is a write involved to get to the BIOS information.

So some other options:

  1. Use sudo
  2. Use other information sources (e.g. /proc/meminfo )
  3. Use an init-script that writes the static output of dmidecode to a world-readable file
Nils
  • 18,492
4

We are using DMIDecode to read information from remote Linux systems and haven't found a workaround to this yet. I have logged a call on the dmidecode home page asking about this...

Using the command dmidecode -t system gives the error "/dev/mem: Permission denied" which is a problem as we don't want memory information (just manufacturer, model and serial number).

I notice that the smbios command running on SunOS works fine for this information without needing root privilege.

For now I'm going to replace our documentation stating to "use a specific account with the least required privilege" with "user root credentials".

Mat
  • 52,586
4

lshal contains a lot of that same information and does not require root privileges.

Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
  • I'm not sure why this was voted down, grepping it it gave me exactly the information I needed lshal | grep system.product for the system name, and even the dell service tag with lshal | grep smbios.system.serial – Mark Booth Mar 07 '14 at 16:08
  • 2
    @MarkBooth maybe because HAL is deprecated and not shipped in modern distributions. – Ruslan Aug 27 '16 at 17:14
  • lshal eventually went away completely in RHEL7 and I'm now using sudo cat /sys/devices/virtual/dmi/id/chassis_serial for getting at the Dell service tag, but this only works as I have access to cat through sudoers. – Mark Booth Dec 16 '19 at 17:02
2

To get the total amount of physical memory, you can parse /proc/meminfo, free, vmstat, etc. You could also parse the kernel message buffer, since it talks about it at 0 time.

The BIOS version is more difficult, I don't believe this is possible as a non-root user, but I may be wrong. It is possible that it (and the system product name) are exposed somewhere, maybe in /sys/ or /proc/, but I can't find anything.

Chris Down
  • 125,559
  • 25
  • 270
  • 266
  • 2
    The BIOS is also mentioned, so consult the kernel log or dmesg if it was not filled too much. Example line: [ 0.000000] DMI: CLEVO CO. B7130 /B7130 , BIOS 6.00 08/27/2010 – Lekensteyn Nov 09 '11 at 08:40
  • cat /sys/devices/virtual/dmi/id/bios_version ...Voila'! But YMMV. Not all architectures have this path. x86_64 Intel should. – Mike S Oct 25 '17 at 19:38
2

Our Linux services don't run as root. In the RPM post install script (which DOES run as root) we install a /etc/sudo.d file and setcap a few of our executables (e.g. for network broadcast priviledges).

0

root:

chmod a+r /sys/firmware/dmi/tables/DMI
dmidecode -s system-uuid

other user command:

dmidecode -t 1  < /sys/firmware/dmi/tables/DMI | awk "$1=="UUID:"{print $2}"
张馆长
  • 131