[MIR] ippusbxd

Bug #1455644 reported by Till Kamppeter
10
This bug affects 1 person
Affects Status Importance Assigned to Milestone
ippusbxd (Ubuntu)
Fix Released
High
Unassigned

Bug Description

Principally, this software is already in Ubuntu Main since Utopic, as part of the cups-filters source package, as the binary package cups-filters-ippusbxd. As it is an own upstream project independent of the cups-filters upstream project and Debian has recently created a dedicated Debian source package for ippusbxd, the Debian package got synced into Ubuntu Universe and we want to promote this package into Main and remove ippusbxd from the cups-filters source package then. The ippusbxd source in Wily's current cups-filters (1.0.67-0ubuntu2) and in Debian's/Ubuntu Universe's current ippusbxd (1.21.2-1) is the same.

Rationale: ippusbxd is an interface daemon to support the communication with printers, scanners, and other devices using the IPP-over-USB standard. These are devices which are connected via a USB cable but emulate the network protocol IPP (Internet Printing Protocol). With this the devices have advanced functionality which one usually encounters only in native network devices, especially the device can be configured using a web browser instead of proprietary software. Also standards for driverless which are originally defined for network devices can be made use of, especially the IPP Everywhere standard from the Printer Working Group PWG (http://www.pwg.org/) which allows printing without printer-model-specific software (drivers).

Many modern, even very cheap printers use this protocol nowadays. It replaces former proprietary protocols for packet-based USB communication and so is an important piece of hardware support, especially in the free software world where standard protocols are needed.

Availability: ippusbxd is already available as DEB package in Debian Unstable and Ubuntu Universe (starting from Wily on). It builds on all supported architectures (see Launchpad page of ippusbxd).

Security: No known security vulnerabilities on

- http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=ippusbxd
- http://secunia.com/advisories/search/?search=ippusbxd
- http://people.canonical.com/~ubuntu-security/cve/universe.html

There are no executables with SUID or GUID bits and no privileged ports opened.

The software is a daemon started by the UDEV-triggered /lib/udev/udev-configure-printer when a supported (IPP-over-USB) USB printer is connected and stopped whether the printer is unplugged again. One instance of ippusbxd is running for each IPP-over-USB printer which is currently connected. The daemon connects the USB connection to the printer with an unprivileged port on localhost, a different port for each connected printer. This port can be used on the local machine as it was a network printer. One can print via IPP and one can configure the printer via a web interface. ippusbxd errors out immediately if one tries to run it with an unsupported USB printer. ippusbxd is never running if no supported printer is connected. The system is protected against unwished access by ippusbxd through AppArmor. The configuration is installed as the /etc/apparmor.d/usr.sbin.ippusbxd file.

Quality assurance: The package is supposed to get installed with the standard installation of the system and ippusbxd gets automatically used if an IPP-over-USB printer is connected. There is no action required by the user, the printer will "just work".

The package does not use debconf at all. It is actively maintained upstream and in Debian (there by Debian's printing team where I am also part of). In case of discontinuation of upstream maintenance I will take the package into OpenPrinting.

There are no Debian bug reports concerning ippusbxd:
https://bugs.debian.org/cgi-bin/pkgreport.cgi?dist=unstable;package=ippusbxd

There are no Ubuntu bugs concerning ippusbxd:
https://bugs.launchpad.net/ubuntu/+source/ippusbxd

There is also nothing concerning the ippusbxd shipped as part of Ubuntu's cups-filters:
https://bugs.launchpad.net/ubuntu/+source/cups-filters

Upstream ippusbxd has no test suite, so we cannot use one for the package build. As it only runs with a supported printer connected it is also not easy to create a test suite to be run on build servers.

An active debian/watch file is included.

UI standards: ippusbxd has no user interface, it is automatically started and stopped in the background.

Dependencies: ippusbxd uses only standard libraries which are all in Main.

Standards compliance: All files are at there expected places and the packaging is done the standard Debian way.

Maintenace: The ippusbxd package is maintained by Debian's printing team (where I am also part of) and is usually synced into Ubuntu. When Debian is in freeze or we are after Feature Freeze I will also do Debian-independent package releases if needed.

Related branches

CVE References

Michael Terry (mterry)
Changed in ippusbxd (Ubuntu):
assignee: nobody → Jamie Strandboge (jdstrand)
Tyler Hicks (tyhicks)
Changed in ippusbxd (Ubuntu):
assignee: Jamie Strandboge (jdstrand) → Ubuntu Security Team (ubuntu-security)
Changed in ippusbxd (Ubuntu):
importance: Undecided → High
Tyler Hicks (tyhicks)
Changed in ippusbxd (Ubuntu):
assignee: Ubuntu Security Team (ubuntu-security) → Seth Arnold (seth-arnold)
Revision history for this message
Seth Arnold (seth-arnold) wrote :

Till, this binds to in6addr_any and has no access controls to determine who might be able to use the printer; is this intentional?

Thanks

Revision history for this message
Till Kamppeter (till-kamppeter) wrote :

The printer access is bound to localhost:<port>, so one can only access locally, not through the network. As print queues are system-wide and not per-user any local user can access to "normal" USB printers (using classic USB protocol with "usb" or "hp" CUPS backend). So using IPP-over-USB does not add any extra access possibilities.

Revision history for this message
Seth Arnold (seth-arnold) wrote :

Till, could you please double-check this? The code sure looks like it binds to the ipv6 wildcard address:

        struct sockaddr_in6 addr;
        memset(&addr, 0, sizeof addr);
        addr.sin6_family = AF_INET6;
        addr.sin6_port = htons(port);
        addr.sin6_addr = in6addr_any;

        // Bind to localhost
        if (bind(this->sd,
                (struct sockaddr *)&addr,
                sizeof addr) < 0) {
                ERR("Bind on port failed. "
                    "Requested port may be taken or require root permissions.");
                goto error;
        }

Is there any easy way to run this program without having a printer available? You say it should bind to localhost, and the comment says it should bind to localhost, but the code clearly uses in6addr_any rather than in6addr_loopback.

Please double-check with netstat, or let me know how I can double-check with netstat but without a printer...

Thanks

Revision history for this message
Till Kamppeter (till-kamppeter) wrote :

I will look into adding a mode for printer-less debugging, for example simply letting it show a simple HTML page when calling its URL with a browser.

Revision history for this message
Tyler Hicks (tyhicks) wrote :

Hi Till - Any luck with gathering the netstat output to verify that it is only listening to ipv6 localhost?

Revision history for this message
Till Kamppeter (till-kamppeter) wrote :

I have added said printer=less debugging mode to ippusbxd now. Please update to cups-filters-ippusbxd_1.0.71-1ubuntu3 and run

ippusbxd -d -N -P 60000

Then you can access with a web brower, using the URL

http://localhost:60000/

This way the TCP/IP interface of ippusbxd is available for any kind of test, like netstat and so on.

Revision history for this message
Till Kamppeter (till-kamppeter) wrote :

I have also tried to replace in6addr_any by in6addr_loopback, but with this I cannot even access via localhost:60000. With in6addr_any I can access also from my virtual machine, through the hosts IP (like http://192.168.122.204).

Revision history for this message
Seth Arnold (seth-arnold) wrote :

Thanks for adding the -N option, it's very handy to test the networking portion.

You're right, in6addr_loopback isn't going to work -- it is then only listening on ::1:60000 and connections to 127.0.0.1:60000 don't work.

I think this is going to take a more complicated fix, one of these options is needed:

- ensure cups is looking for ippusbxd printers over IPv6
- change ippusbxd to function over IPv4 only
- change ippusbxd to bind to two sockets, one for IPv6 in6addr_loopback and one for IPv4 INADDR_LOOPBACK. This would also require using select() to determine which of the two ports is connected each iteration through the loop. This also feels like the best solution.

We really can't continue with the current code -- it is currently open for all to connect to, on all interfaces that are configured on the system. I'll ask MITRE for a CVE for this later, once we're closer to having a patch.

Thanks Till.

Revision history for this message
Till Kamppeter (till-kamppeter) wrote :

I have now modified ippusbxd in the upstream GIT repository to listen on both IPv4 and IPv6 sockets using the select() function to watch both. On each socket I restrict to localhost in the proper way. I have tested that with

wget 'http://localhost:60000/'
wget 'http://[::1]:60000/'
wget '<Any other IP from "ifconfig" output>:60000'

and the first two download the short HTML message into the index.html file, any other gives "Connection refused".

For you to test I have uploaded cups-filters_1.0.71-1ubuntu4 to Wily. Please test and if it is OK, I will release this version of ippusbxd upstream and updated the ippusbxd package in Universe.

Revision history for this message
Till Kamppeter (till-kamppeter) wrote :
Changed in ippusbxd (Ubuntu):
status: New → In Progress
Revision history for this message
Till Kamppeter (till-kamppeter) wrote :

I did also a check with a printer (without "-N" option) now and the restriction works there, too.

Revision history for this message
Seth Arnold (seth-arnold) wrote :

Till, this looks great, confirmed that the -N variant listens on loopback for both ipv4 and ipv6. Very nice, thanks.

I am concerned to see a timeout on the select() statement; select_tut(2) strongly recommends writing code in a way that does not use the timeout:

       1. You should always try to use select() without a timeout.
           Your program should have nothing to do if there is no
           data available. Code that depends on timeouts is not
           usually portable and is difficult to debug.

Thanks

Revision history for this message
Till Kamppeter (till-kamppeter) wrote :

Seth, thanks for the hint. It works actually the same way without timeout and loop, making the code simpler.

I have uploaded this upstream as

https://github.com/tillkamppeter/ippusbxd/commit/a632841f8e65d402e13e81921515f5a1e2736c82

Do I need to add this to Wily's cups-filters for you to text, too? Or should I simply release upstream now, update the ippusbxd package in Universe and you promote it to Main?

Revision history for this message
Seth Arnold (seth-arnold) wrote :

Thanks Till, I've requested a CVE from MITRE: http://www.openwall.com/lists/oss-security/2015/08/11/1

Please include the CVE number in changelogs and announcements if one is available in time.

Revision history for this message
Seth Arnold (seth-arnold) wrote :

I reviewed ippusbxd version 1.21.2-1 as checked into wily; this shouldn't
be considered a full security audit but rather a quick gauge of
maintainability.

- ippusbxd implements the usb-ipp standardized printer bridge;
  udev rules start the daemon when a supported printer is plugged in,
  exposing the printer to loopback interfaces.
- Build-Depends: debhelper, libusb-1.0-0-dev, cmake, pkg-config, dh-apparmor
- Provides a daemon
- start_daemon() does not properly daemonize:
  - doesn't set umask()
  - doesn't setsid()
  - doesn't chdir(/)
  - doesn't set signals to expected dispositions
- pre,post inst,rm scripts all automatically generated
- No initscripts
- No dbus services
- No setuid executables
- One executable, /usr/sbin/ippusbxd
- No sudo fragments
- No udev rules -- they must be packaged elsewhere?
- No tests
- No cronjobs
- One warning in build log looks harmless

- No subprocesses spawned
- Memory management looked careful
- No files are written to
- Logging looked safe
- No environment variables
- No privileged operations
- No cryptography
- No privileged portions of code
- No temporary file use
- No WebKit
- No javascript
- No policykit
- Clean cppcheck

The code quality is good, with a few caveats: the software doesn't
properly daemonize at startup; and the AppArmor profile doesn't look
like it's been used lately.

Till was very responsive to the in6addr_any issue and associated
requests.

Here's the remaining issues that I found, they may or may not be important
enough to fix, though the AppArmor profile probably needs to be updated to
allow the daemon to function:

- AppArmor profile needs to be updated
- usb_conn_acquire(), typo in text that may be user-visible, "aloc"
- there appears to be no way to stop the usb_pump_events() thread
- Really should setsid(), chdir(/), and set signal dispositions for
  reliable operation (umask is less important since the daemon creates no files)

Security team ACK to promote ippusbxd to main.

Thanks

Revision history for this message
Seth Arnold (seth-arnold) wrote :

Till, please update the wily packaging and upstream releases as soon as convenient. Include the CVE if you can.

A note for the security team once the CVE comes through, ippusbxd is packaged in cups-filters in vivid, which is in main, and will also need to be updated. Double-check that it's been removed from cups-filters in wily when we get there.

Thanks

Changed in ippusbxd (Ubuntu):
assignee: Seth Arnold (seth-arnold) → nobody
Revision history for this message
Till Kamppeter (till-kamppeter) wrote :

Note that all software to start and stop the daemon with the correct options, and to create CUPS queues for the IPP-over-USB printers is in the system-config-printer-udev package.

Revision history for this message
Michael Terry (mterry) wrote :

Packaging wise, things look fine. But it does need a team bug subscriber.

Changed in ippusbxd (Ubuntu):
status: In Progress → Incomplete
Revision history for this message
Till Kamppeter (till-kamppeter) wrote :

Subscription created for Ubuntu Printing Team.

Changed in ippusbxd (Ubuntu):
status: Incomplete → In Progress
Revision history for this message
Michael Terry (mterry) wrote :

OK, fine from my side then. Seth, was that ACK for the version in wily as-is or did you want to only promote this once the fixes you've discussed here landed?

Revision history for this message
Seth Arnold (seth-arnold) wrote :

Michael, ACK now please, the other fixes can come whenever it is convenient for Till to work on them. Thanks.

Revision history for this message
Michael Terry (mterry) wrote :

You got it! Thanks Seth and Till!

Changed in ippusbxd (Ubuntu):
status: In Progress → Fix Committed
Revision history for this message
Matthias Klose (doko) wrote :

Override component to main
ippusbxd 1.21.2-1 in wily: universe/misc -> main
ippusbxd 1.21.2-1 in wily amd64: universe/comm/extra/100% -> main
ippusbxd 1.21.2-1 in wily arm64: universe/comm/extra/100% -> main
ippusbxd 1.21.2-1 in wily armhf: universe/comm/extra/100% -> main
ippusbxd 1.21.2-1 in wily i386: universe/comm/extra/100% -> main
ippusbxd 1.21.2-1 in wily powerpc: universe/comm/extra/100% -> main
ippusbxd 1.21.2-1 in wily ppc64el: universe/comm/extra/100% -> main
7 publications overridden.

Changed in ippusbxd (Ubuntu):
status: Fix Committed → Fix Released
Revision history for this message
Seth Arnold (seth-arnold) wrote :

MITRE has assigned the in6addr_any issue CVE-2015-6520: http://www.openwall.com/lists/oss-security/2015/08/18/11

Thanks

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.