Phil Perry | www.pendre.co.uk

Choosing a webcam for CentOS

December 1st, 2008
QuickCam Pro 9000

Finding a webcam that will work under Linux has always been a bit of a lottery. Sure, things are slowly improving, and drivers for many webcams are finally starting to appear in the mainline kernel, but on an Enterprise-class distro such as CentOS like we use at Pendre, support for webcams isn't top of the priority list - afterall CentOS is primarily a server OS and not that many servers actually need a webcam.

So after doing plenty of research, I finally settled on a Logitech QuickCam Pro 9000. This is a high-end webcam with integrated microphone boasting HD resolution from it's 2 Megapixel sensor, and a high quality Carl Zeiss lens with autofocus. The Logitech QuickCam Pro 9000 can be found for around £45 ($80-100US).

The QuickCam Pro 9000 uses the UVC driver which has recently been introduced into the mainline kernel. Unfortunately this has yet to be backported into CentOS 5, so I built the driver from source. This was relatively easy - just grab the latest tarball from linuxtv.org, extract, build and install (make && make install). Once built, the driver can be inserted into the kernel by running modprobe uvcvideo.

I tested the camera out using Skype and although the higher resolutions available with this webcam under Windows are not available to Linux users, the camera produces a very crisp clear picture and is clearly superior to that produced by most entry-level and midrange webcams. Sound is equally impressive from the built in microphone. Overall, highly recommended and you really do get what you pay for.

Building kernel modules: Part 3

July 24th, 2008

Previously we have seen how we can build kernel modules for CentOS (or RHEL) out of tree (Part 1; May 30th, 2008) or as DKMS modules (Part 2; July 18th, 2008). In this final part we will look at building kmod kernel modules packaged in RPM format and again we will use the coretemp module as an example.

The first thing we need to do is make sure we have all the kernel-devel packages installed for the currect kernel, including any xen and PAE variants. Next create a working directory containing the project source code and Makefile and create the Kbuild file by copying the Makefile. Finally, create a bzip2 compressed tarball of the source directory and copy the compressed tarball to the /SOURCES directory within your build environment.

[buildsys@Quad]$ rpm -qa kernel\* | sort
kernel-2.6.18-92.1.6.el5.x86_64
kernel-devel-2.6.18-92.1.6.el5.x86_64
kernel-headers-2.6.18-92.1.6.el5.x86_64
kernel-xen-devel-2.6.18-92.1.6.el5.x86_64
[buildsys@Quad]$ mkdir /usr/src/coretemp-1.0kmod/
[buildsys@Quad]$ cp coretemp.c Makefile /usr/src/coretemp-1.0kmod/
[buildsys@Quad]$ cd /usr/src/coretemp-1.0kmod
[buildsys@Quad]$ cp Makefile Kbuild
[buildsys@Quad]$ cd ..
[buildsys@Quad]$ tar -cf coretemp-1.0kmod.tar coretemp-1.0kmod/
[buildsys@Quad]$ bzip2 coretemp-1.0kmod.tar
[buildsys@Quad]$ cp coretemp-1.0kmod.tar.bz2 /usr/src/buildsys/SOURCES/
[buildsys@Quad]$

Now we make a copy the kmodtool script (located at /usr/lib/rpm/redhat/kmodtool) called kmodtool-coretemp in the SOURCES directory and edit it to include any dependencies for our kmod RPM package (thanks to Johnny Hughes for the tip). Creating a custom kmodtool script isn't strictly needed for building kmod packages if you don't need to specify any dependencies but I was unable to find a convenient way to pass package dependencies from the SPEC file to the kmodtool build script. Below is an excerpt of my kmodtool-coretemp script showing an additional dependency for lm_sensors >= 2.10.2 which may be obtained from ATrpms.

Requires(post): /sbin/depmod
Requires(postun): /sbin/depmod
Requires: lm_sensors >= 2.10.2
EOF

Finally we make a SPEC file for the project named coretemp-kmod.spec file in the /SPECS directory of our build environment:

# Sources:
Source0: coretemp-1.0kmod.tar.bz2
Source10: kmodtool-coretemp

# If kversion isn't defined on the rpmbuild line, build against the current kernel.
%{!?kversion: %define kversion %(uname -r)}

%define kmod_name coretemp
%define kmodtool sh %{SOURCE10}
%define kverrel %(%{kmodtool} verrel %{?kversion} 2>/dev/null)
%define kmodrel %(echo %{kverrel} | sed 's/2.6.18-//')

%define basevar ""
%ifarch i686
%define paevar PAE
%endif
%ifarch i686 x86_64
%define xenvar xen
%endif

%{!?kvariants: %define kvariants %{?basevar} %{?xenvar} %{?paevar}}

Name: %{kmod_name}-kmod
Version: 1.0
Release: 4.%{kmodrel}
Summary: Coretemp 1.0 CentOS-5 module
License: GPL v2
Group: System Environment/Kernel
URL: http://www.kernel.org/

BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
ExclusiveArch: i686 x86_64

%description
This package provides the coretemp kernel module for monitoring the core temperature
of Intel Core 2 Duo and Quad Core processors with the CentOS 5.2 series kernels.

# Magic hidden here:
%define kmp_version %{version}
%define kmp_release %{release}
%{expand:%(%{kmodtool} rpmtemplate_kmp %{kmod_name} %{kverrel} %{kvariants} 2>/dev/null)}

%prep
%setup -q -c -T -a 0
for kvariant in %{kvariants} ; do
cp -a coretemp-1.0kmod _kmod_build_$kvariant
done

%build
for kvariant in %{kvariants} ; do
ksrc=%{_usrsrc}/kernels/%{kverrel}${kvariant:+-$kvariant}-%{_target_cpu}
pushd _kmod_build_$kvariant
make -C "${ksrc}" modules M=$PWD
popd
done

%install
export INSTALL_MOD_PATH=$RPM_BUILD_ROOT
export INSTALL_MOD_DIR=extra/%{kmod_name}
for kvariant in %{kvariants} ; do
ksrc=%{_usrsrc}/kernels/%{kverrel}${kvariant:+-$kvariant}-%{_target_cpu}
pushd _kmod_build_$kvariant
make -C "${ksrc}" modules_install M=$PWD
popd
done

%clean
rm -rf $RPM_BUILD_ROOT

%changelog
* Tue Jul 15 2008 Alan J Bartlett
- Fixed bugs in spec file. 1.0-4.92.1.6.el5

* Sat Jul 12 2008 Philip J Perry
- Fixed dependencies. 1.0-3.92.1.6.el5

* Tue Jul 08 2008 Philip J Perry
- Fixed bug in spec file. 1.0-2.92.1.6.el5

* Tue Jul 08 2008 Philip J Perry
- Initial RPM build. 1.0-1.92.1.6.el5

Now we're ready to build our kmod packages using rpmbuild:

[buildsys@Quad SPECS]$ rpmbuild -bb --target=`uname -m` coretemp-kmod.spec
[buildsys@Quad SPECS]$

which will produce a set of kmod-coretemp RPMs in your /RPMS directory under the appropriate architecture. Additionally, our SPEC file allows us to specify from the command line at build time which kernel version to build against (e.g, --define 'kversion 2.6.18-92.el5') or which kernel-variant kmod packages to build (e.g, --define 'kvariants ""' would only build the base kernel package).

kmod coretemp packages for CentOS 5 may be downloaded below and installed with rpm:

http://www.pperry.f2s.com/linux/coretemp/

Alan has kindly updated the CentOS Wiki page on building kernel modules and I'd like to thank both Alan Bartlett and Akemi Yagi for helpful discussions, testing and encouragement whilst preparing this series of articles.

Building kernel modules: Part 2

July 18th, 2008

In an earlier article (Part 1; May 30th, 2008) I described how to build kernel modules for CentOS (or RHEL) out of tree and used the coretemp module as an example. My good friend and colleague, Alan Bartlett, had persuaded me to investigate packaging kernel modules, so herein we are going to look at how to package kernel modules in RPM format using the coretemp module as an example. I'd like to thank Alan for his technical assistance and encouragement without which this article wouldn't have been written.

There are two methods we can employ to build kernel module RPMs - DKMS and kmod. In this article we will look at Dynamic Kernel Module Support (DKMS) and in part 3 we will use kmod.

DKMS must be installed from RPMForge together with the necessary development packages.

We start by creating the necessary directory structure and copying the module source code and Makefile to that directory:

[root@Quad]# mkdir /usr/src/coretemp-1.00/
[root@Quad]# cp coretemp.c Makefile /usr/src/coretemp-1.00/
[root@Quad]#

Next create a dkms.conf file for the project and save it to /usr/src/coretemp-1.00/

PACKAGE_NAME="coretemp"
PACKAGE_VERSION="1.00"
BUILT_MODULE_NAME[0]="coretemp"
DEST_MODULE_LOCATION[0]="/kernel/drivers/hwmon/"
AUTOINSTALL="yes"

Now we are ready to invoke DKMS to add the coretemp module to the DKMS tree and build our RPM package:

[root@Quad]# dkms add -m coretemp -v 1.00

Creating symlink /var/lib/dkms/coretemp/1.00/source ->
/usr/src/coretemp-1.00

DKMS: add Completed.
[root@Quad]# dkms mkrpm --source-only -m coretemp -v 1.00

Using /etc/dkms/template-dkms-mkrpm.spec
rpmbuild...

Wrote: /var/lib/dkms/coretemp/1.00/rpm/coretemp-1.00-1dkms.src.rpm
Wrote: /var/lib/dkms/coretemp/1.00/rpm/coretemp-1.00-1dkms.noarch.rpm

DKMS: mkrpm Completed.
[root@Quad]#

Finally copy the created RPMs to somewhere safe and remove the coretemp module from the DKMS tree:

[root@Quad]# cp /var/lib/dkms/coretemp/1.00/rpm/coretemp*.rpm /usr/src/
[root@Quad]# dkms remove -m coretemp -v 1.00 --all

------------------------------
Deleting module version: 1.00
completely from the DKMS tree.
------------------------------
Done.
[root@Quad ~]#

Now we can install our newly created coretemp RPM as normal:

[root@Quad]# cd /usr/src/
[root@Quad]# rpm -Uvh coretemp-1.00-1dkms.noarch.rpm
Preparing...        ########################################### [100%]
[root@Quad]#

In part 3 I will describe how to build coretemp as a kmod kernel module RPM package for CentOS (or RHEL) and will make the RPMs available for download.

Building kernel modules: Part 1

May 30th, 2008

There are a number of reasons why you may wish to build Linux kernel modules. For example, you may need a driver that isn't present in the current kernel, or you may want to apply a patch to an existing driver that adds functionality or fixes an bug. There are a number of ways you can tackle such issues:

  • Build a new kernel based on the upstream vanilla sources that contain the required driver version
  • Rebuild your current distro kernel with a patch applied

Both of these methods require you to build a complete custom kernel which you then become responsible for maintaining. However, many drivers will build out of tree and may be loaded into your currently running kernel. This approach has a number of advantages in that you don't need to compile a complete kernel, you can continue to run your stable distro kernel and you don't have to worry about maintaining your own custom kernel.

Building modules out of tree

As an example, I'm going to build the coretemp module for CentOS 5 used for monitoring the core temperature from inside Intel Core series processors as this driver didn't make it into the 2.6.18 series kernel used in CentOS 5.

First we need to create a project directory and src directory in that:

[phil@Quad ~]$ mkdir coretemp
[phil@Quad ~]$ cd coretemp/
[phil@Quad coretemp]$ mkdir src
[phil@Quad coretemp]$ ls -l
total 4
drwxrwxr-x 2 phil phil 4096 May 30 18:58 src
[phil@Quad coretemp]$

and place your module source file in /src

Next we create a top level Makefile in the project directory ~/coretemp/

all: clean modules install

modules:
$(MAKE) -C src/ modules

clean:
$(MAKE) -C src/ clean

install:
$(MAKE) -C src/ install

and a Makefile in ~/coretemp/src/

KVER   := $(shell uname -r)
KDIR   := /lib/modules/$(KVER)/build
KMISC  := /lib/modules/$(KVER)/extra/
KEXT   := $(shell echo $(KVER) | sed -ne 's/^2\.[567]\..*/k/p')o
KFLAG  := 2$(shell echo $(KVER) | sed -ne 's/^2\.[4]\..*/4/p')x

modules:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD)/src modules

clean:
rm -rf *.o *.ko *~ .dep* .*.d .*.cmd *.mod.c *.a *.s .*.flags .tmp_versions Module.symvers

install:
install -m 644 -c coretemp.$(KEXT) $(KMISC)

obj-m += coretemp.o

Since coretemp isn't a module provided in the CentOS 5 kernel it makes sense to install our newly built module to /lib/modules/{uname -r}/extra.

So now we can build our new kernel module (you can build the module as a regular user, but make install will need root privileges):

[root@Quad coretemp]# make
make -C src/ clean
make[1]: Entering directory `/home/phil/coretemp/src'
rm -rf *.o *.ko *~ .dep* .*.d .*.cmd *.mod.c *.a *.s .*.flags .tmp_versions Module.symvers
make[1]: Leaving directory `/home/phil/coretemp/src'
make -C src/ modules
make[1]: Entering directory `/home/phil/coretemp/src'
make -C /lib/modules/2.6.18-92.el5/build SUBDIRS=/home/phil/coretemp/src modules
make[2]: Entering directory `/usr/src/kernels/2.6.18-92.el5-x86_64'
CC [M] /home/phil/coretemp/src/coretemp.o
Building modules, stage 2.
MODPOST
CC /home/phil/coretemp/src/coretemp.mod.o
LD [M] /home/phil/coretemp/src/coretemp.ko
make[2]: Leaving directory `/usr/src/kernels/2.6.18-92.el5-x86_64'
make[1]: Leaving directory `/home/phil/coretemp/src'
make -C src/ install
make[1]: Entering directory `/home/phil/coretemp/src'
install -m 644 -c coretemp.ko /lib/modules/2.6.18-92.el5/extra/
make[1]: Leaving directory `/home/phil/coretemp/src'
[root@Quad coretemp]#

and finally run depmod, load the module with modprobe and check it's loaded:

[root@Quad coretemp]# depmod -a
[root@Quad coretemp]# modprobe coretemp
[root@Quad coretemp]# lsmod | grep coretemp
coretemp 41344 0
hwmon 36553 2 coretemp,it87
[root@Quad coretemp]#

So let's have a look at coretemp in action, shown here monitoring all 4 cores of an Intel Q6600 quad core processor:

[root@Quad coretemp]# sensors

coretemp-isa-0000
Adapter: ISA adapter
Core 0: +38°C (high = +100°C)

coretemp-isa-0001
Adapter: ISA adapter
Core 1: +38°C (high = +100°C)

coretemp-isa-0002
Adapter: ISA adapter
Core 2: +36°C (high = +100°C)

coretemp-isa-0003
Adapter: ISA adapter
Core 3: +36°C (high = +100°C)

[phil@Quad coretemp]$

In part 2 I'll describe how to build dkms enabled kernel modules for CentOS/RHEL and package these in RPM format for distribution.

OpenSSL: Predictable PRNG in debian-based systems

May 13th, 2008

A critical bug has been found in the Pseudo Random Number Generator (PRNG) used in OpenSSL in debian Linux and it's derivative (e.g, Ubuntu etc) that renders random numbers predictable. The bug was introduced into debin unstable on September 17th, 2006 and has since propogated into the stable branch. All keys generated on affected systems should be considered compromised.

http://www.debian.org/security/2008/dsa-1571

http://www.ubuntu.com/usn/USN-612-1

I don't use debian (or Ubuntu), so how does this affect me?

The impact of this vulnerability is far reaching and goes way beyond debian-based systems. The vulnerability directly affects all debian-based systems using OpenSSL generated keys (OpenSSH, OpenVPN, website and mail server authentication by SSL/TLS, etc) and potentially affects anyone using SSL-based security or encryption.

OpenSSH

If you have a Linux server, then you almost certainly have SSH configured by default for remote access. If you use public/private key authentication and users have generated keys on affected systems, then brute-forcing those keys to gain remote access is trivial and there are already scripts available in the wild. The same applies to OpenVPN. The important facor here is the system the keys were generated on, not whether your server is running debian or other affected Linux distribution.

Additionally, all DSA keys that were ever used on a vulnerable debian-based system for signing or authentication should also be considered compromized due to a known attack on DSA keys.

System administrators are advised to conduct a full audit of all key pairs and regenerate new keys where appropriate.

SSL-encrypted websites and mail servers

Users of debian-based systems running SSL encrypted websites or mail servers using SSL/TLS certificates generated on affected systems should generate new certificates immediately. Additionally, if you have had your certificates signed by Root Certificate Authorities (eg, Twarte, VeriSign etc), then you will need to generate new certificates and get these resigned.

By definition, the public key is publicly known, and therefore it is trivial to generate a matching private key. It then becomes trivial to launch man-in-the-middle style attacks against encrypted or secured transactions such as credit card or other banking transactions or to obtain users login credentials. The potential for exploitation is huge and has the potential to affected all users of the Internet.

If you are at all unsure about how to generate new keys or certificates, please do not hesitate to contact us and we will be happy to assist in generating new OpenSSL keys or certificates for you.

vmsplice local privilege escalation in Linux kernel

February 11th, 2008

There is currently a local privilege escalation flaw in the current Linux Kernel, affecting all kernels from 2.6.17 to 2.6.24.1 inclusive.

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-0600

Exploit code for this vulnerability is available in the wild:

[phil@centos test]$ ls
exploit exploit.c
[phil@centos test]$ uname -a
Linux centos 2.6.18-53.1.6.el5 #1 SMP Wed Jan 23 11:30:20 EST 2008 i686 athlon i386 GNU/Linux
[phil@centos test]$ whoami
phil
[phil@centos test]$ ./exploit
-----------------------------------
Linux vmsplice Local Root Exploit
By qaaz
-----------------------------------
[+] mmap: 0x0 .. 0x1000
[+] page: 0x0
[+] page: 0x20
[+] mmap: 0x4000 .. 0x5000
[+] page: 0x4000
[+] page: 0x4020
[+] mmap: 0x1000 .. 0x2000
[+] page: 0x1000
[+] mmap: 0xb7f0c000 .. 0xb7f3e000
[+] root
[root@centos test]# whoami
root
[root@centos test]#

This vulnerability is not remotely exploitable so an attacker would first have to gain local access, however this could present significant risks for system administrators in shared environments with multiple system accounts.

Patches should be available shortly from distribution vendors and system administrators are advised to upgrade their kernel as soon as these become available.