QtSystemInfo fails when using ofono and there are DBus denials to ofono

Bug #1226844 reported by Jamie Strandboge
28
This bug affects 4 people
Affects Status Importance Assigned to Milestone
qtsystems-opensource-src (Ubuntu)
Won't Fix
High
Unassigned
Saucy
Won't Fix
High
Unassigned
Trusty
Won't Fix
High
Unassigned

Bug Description

= Background =
Applications in the Ubuntu appstore are packaged as click packages and run under confinement. Applications sometimes need to know if they are connected to the internet, on an expensive connection or disconnected. QtSystemInfo::NetworkInfo (via qtdeclarative5-systeminfo-plugin) provides this information to QML applications.

Attached is a simple QML application to test this and an apparmor profile. Save the qml file as /tmp/test-network.qml and the apparmor profile as /tmp/profile.

In one terminal, run:
$ tail -f /var/log/syslog | grep DEN

In another, run:
$ sudo apparmor_parser -r /tmp/profile && aa-exec -p test-network -- qmlscene /tmp/test-network.qml

On a desktop system, the application should say that it is connected to the home network (or similar) and there will be no apparmor denials for NetworkManager (there will be one for GConf, but that can be ignored). On a system with a working ofono (eg, Nexus 4 with up to date Ubuntu Touch), this the application will report an error. For the error to go away, the following ofono rules must be added to the apparmor profile:
# ofono
dbus (send)
     bus=system
     path=/
     interface=org.ofono.Manager
     member=GetModems
     peer=(name=org.ofono),
dbus (send)
     bus=system
     path=/ril_*
     interface=org.ofono.NetworkRegistration
     member=GetProperties
     peer=(name=org.ofono),
dbus (receive)
     bus=system
     path=/ril_*
     interface=org.ofono.NetworkRegistration
     member=PropertyChanged
     peer=(name=org.freedesktop.DBus),

Then rerun 'sudo apparmor_parser -r /tmp/profile && aa-exec -p test-network -- qmlscene /tmp/test-network.qml' and the application works correctly. Unfortunately, giving access to org.ofono.NetworkRegistration.GetProperties reveals far too much information to confined applications.

On the desktop system, /proc and /sys entries are consulted to see if online, but on a system with ofono, this is not enough. Ideally we would provide a simple dbus service (I think 'uconnectd' would be a great name-- feel free to use it ;) with methods like OnlineWired, OnlineWireless and OnlineCostlyNetwork. This dbus service would consult network manager and ofono, we could declare a simple QML plugin as the correct way to check for connectivity.

Right now, apparmor policy (correctly) denies access to ofono over DBus, but applications are unable to determine if they are on the network using standard APIs. To fix this in the short term, we can adjust to use what is in /proc and /sys and not throw an error if it gets an apparmor denial.

tags: added: application-confinement
summary: - ofonot-qt causes QtSystemInfo to fail when there are DBus denials
+ QtSystemInfo fails when using ofono and there are DBus denials to ofono
Changed in ofono-qt (Ubuntu Saucy):
assignee: nobody → Ricardo Salveti (rsalveti)
importance: Undecided → High
Changed in ofono-qt (Ubuntu Saucy):
assignee: Ricardo Salveti (rsalveti) → Tiago Salem Herrmann (tiagosh)
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

FYI, you can see what ofon is giving up with these commands:
dbus-send --system --print-reply --dest=org.ofono / org.ofono.Manager.GetModems
dbus-send --system --print-reply --dest=org.ofono /ril_0 org.ofono.NetworkRegistration.GetProperties

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

I forgot to attach the profile and QML. Instead, here is a click package. Install with:
$ adb shell
# sudo -H -u phablet -i
$ pkcon install-local /path/to/com.ubuntu.developer.jdstrand.test-network_0.1_all.click

Launch it under application confinement with:
$ start application APP_ID=com.ubuntu.developer.jdstrand.test-network_test-network_0.1

Launch it on its own in a terminal on the device with:
$ qmlscene /opt/click.ubuntu.com/com.ubuntu.developer.jdstrand.test-network/current/test-network.qml

Revision history for this message
Tiago Salem Herrmann (tiagosh) wrote :

qtdeclarative5-systeminfo-plugin does not use ofono-qt.
It handles all the ofono dbus communication in qofonowrapper.cpp:
https://qt.gitorious.org/qt/qtsystems/source/26ed19484e85fb814d2735fa4a98f1ad4c51199b:src/systeminfo/linux/qofonowrapper.cpp

This bug is more network/apparmor related.

Changed in ofono-qt (Ubuntu Saucy):
assignee: Tiago Salem Herrmann (tiagosh) → nobody
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Thanks for the analysis, I've retargeted the bug. This isn't apparmor related-- this is related to qtsystems-opensource-src not handling ofono errors like it does with network manager. Ie, on systems with network manager and not ofono (desktop and Nexus 7), qtsystems-opensource-src is able to find what it needs by looking through /proc and /sys. On a system with ofono, it errors out rather than using what it found in /proc and /sys.

affects: ofono-qt (Ubuntu Saucy) → qtsystems-opensource-src (Ubuntu Saucy)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

There's indeed one issue in the way qtsystems-opensource-src looks for oFono, as described bellow:
src/systeminfo/linux/qofonowrapper.cpp
...
bool QOfonoWrapper::isOfonoAvailable()
{
    // -1: Don't know if OFONO is available or not.
    // 0: OFONO is not available.
    // 1: OFONO is available.
    if (-1 == available) {
        if (QDBusConnection::systemBus().isConnected()) {
            QDBusReply<bool> reply = QDBusConnection::systemBus().interface()->isServiceRegistered(*OFONO_SERVICE());
            if (reply.isValid())
                available = reply.value();
            else
                available = 0;
        }
    }

    return available;
}

It assumes that the service is available if the interface is there, without knowing if it can really access the interface. This function would be the main one to change as it already checks internally for it everywhere before trying to grab data from oFono.

As a quick test, I just changed it to return 0 by default, but was unable to get your test application to work (even the unconfined one). After checking in more details, it fails even after stopping the ofono service (using the default qtsystems-opensource-src package), so I believe we're probably facing a different issue in here (and it seems getAllModems would still return empty even with the denials, which would probably be ok).

Revision history for this message
Ricardo Salveti (rsalveti) wrote :
Download full text (3.7 KiB)

The output of the manual tests for qtsystems:
phablet@ubuntu-phablet:~/qt/qtsystems-opensource-src-5.0~git20130712/tests/manual/sysinfo-tester$ ./sysinfo_tester deviceinfo
$DISPLAY not set, assuming :0

----( deviceinfo )----

deviceinfo.hasFeature(QDeviceInfo::BluetoothFeature) -> true
deviceinfo.hasFeature(QDeviceInfo::CameraFeature) -> false
deviceinfo.hasFeature(QDeviceInfo::FmRadioFeature) -> false
deviceinfo.hasFeature(QDeviceInfo::FmTransmitterFeature) -> false
deviceinfo.hasFeature(QDeviceInfo::InfraredFeature) -> false
deviceinfo.hasFeature(QDeviceInfo::LedFeature) -> true
deviceinfo.hasFeature(QDeviceInfo::MemoryCardFeature) -> true
deviceinfo.hasFeature(QDeviceInfo::UsbFeature) -> true
deviceinfo.hasFeature(QDeviceInfo::VibrationFeature) -> false
deviceinfo.hasFeature(QDeviceInfo::WlanFeature) -> true
deviceinfo.hasFeature(QDeviceInfo::SimFeature) -> false
deviceinfo.hasFeature(QDeviceInfo::PositioningFeature) -> false
deviceinfo.hasFeature(QDeviceInfo::VideoOutFeature) -> false
deviceinfo.hasFeature(QDeviceInfo::HapticsFeature) -> false
deviceinfo.hasFeature(QDeviceInfo::NfcFeature) -> false
deviceinfo.imei(0) -> ""
deviceinfo.manufacturer() -> ""
deviceinfo.model() -> ""
deviceinfo.productName() -> "saucy"
QFSFileEngine::open: No file name specified
deviceinfo.uniqueDeviceID() -> ""
deviceinfo.version(QDeviceInfo::Os) -> "13.10"
deviceinfo.version(QDeviceInfo::Firmware) -> "3.4.0-3-mako"
deviceinfo.thermalState() -> 1
phablet@ubuntu-phablet:~/qt/qtsystems-opensource-src-5.0~git20130712/tests/manual/sysinfo-tester$ ./sysinfo_tester networkinfo
$DISPLAY not set, assuming :0

----( networkinfo )----

networkinfo.cellId(0) -> ""
networkinfo.currentMobileCountryCode(0) -> ""
networkinfo.currentMobileNetworkCode(0) -> ""
networkinfo.homeMobileCountryCode(0) -> ""
networkinfo.homeMobileNetworkCode(0) -> ""
networkinfo.locationAreaCode(0) -> ""
networkinfo.currentCellDataTechnology(0) -> 0

NetworkMode: QNetworkInfo::UnknownMode
  networkinfo.currentNetworkMode() -> 0
  networkinfo.networkInterfaceCount() -> -1

NetworkMode: QNetworkInfo::GsmMode
  networkinfo.currentNetworkMode() -> 0
  networkinfo.networkInterfaceCount() -> -1

NetworkMode: QNetworkInfo::CdmaMode
  networkinfo.currentNetworkMode() -> 0
  networkinfo.networkInterfaceCount() -> -1

NetworkMode: QNetworkInfo::WcdmaMode
  networkinfo.currentNetworkMode() -> 0
  networkinfo.networkInterfaceCount() -> -1

NetworkMode: QNetworkInfo::WlanMode
  networkinfo.currentNetworkMode() -> 0
  networkinfo.networkInterfaceCount() -> 1
  networkinfo.interfaceForMode() -> QNetworkInterface(name = "wlan0", hardware address = "10:68:3F:FE:09:8F", flags = IsUp IsRunning CanBroadcast CanMulticast , entries = ((address = QHostAddress("192.168.2.61") , netmask = QHostAddress("255.255.255.0") , broadcast = QHostAddress("192.168.2.255") ) , (address = QHostAddress("fe80::1268:3fff:fefe:98f%wlan0") , netmask = QHostAddress("ffff:ffff:ffff:ffff::") ) ) )

  networkinfo.macAddress() -> "10:68:3f:fe:09:8f"
  networkinfo.networkStatus() -> 1
  networkinfo.networkName() -> "sheevanetN"
  networkinfo.networkSignalStrength() -> -1

Network...

Read more...

Revision history for this message
Ricardo Salveti (rsalveti) wrote :
Download full text (3.8 KiB)

NetworkMode: QNetworkInfo::WlanMode
  networkinfo.currentNetworkMode() -> 0

That means UnknownMode, even when connected, which is probably the issue.

The output when I have ofono running:

phablet@ubuntu-phablet:~/qt/qtsystems-opensource-src-5.0~git20130712/tests/manual/sysinfo-tester$ ./sysinfo_tester networkinfo
$DISPLAY not set, assuming :0

----( networkinfo )----

networkinfo.cellId(0) -> "12593173"
networkinfo.currentMobileCountryCode(0) -> "724"
networkinfo.currentMobileNetworkCode(0) -> "03"
networkinfo.homeMobileCountryCode(0) -> "724"
networkinfo.homeMobileNetworkCode(0) -> "03"
networkinfo.locationAreaCode(0) -> "50219"
networkinfo.currentCellDataTechnology(0) -> 3

NetworkMode: QNetworkInfo::UnknownMode
  networkinfo.currentNetworkMode() -> 8
  networkinfo.networkInterfaceCount() -> -1

NetworkMode: QNetworkInfo::GsmMode
  networkinfo.currentNetworkMode() -> 8
  networkinfo.networkInterfaceCount() -> 1
  networkinfo.interfaceForMode() -> QNetworkInterface(name = "", hardware address = "", flags = , entries = () )

  networkinfo.macAddress() -> ""
  networkinfo.networkStatus() -> 6
  networkinfo.networkName() -> "TIM"
  networkinfo.networkSignalStrength() -> 61

NetworkMode: QNetworkInfo::CdmaMode
  networkinfo.currentNetworkMode() -> 8
  networkinfo.networkInterfaceCount() -> 1
  networkinfo.interfaceForMode() -> QNetworkInterface(name = "", hardware address = "", flags = , entries = () )

  networkinfo.macAddress() -> ""
  networkinfo.networkStatus() -> 6
  networkinfo.networkName() -> "TIM"
  networkinfo.networkSignalStrength() -> 61

NetworkMode: QNetworkInfo::WcdmaMode
  networkinfo.currentNetworkMode() -> 8
  networkinfo.networkInterfaceCount() -> 1
  networkinfo.interfaceForMode() -> QNetworkInterface(name = "", hardware address = "", flags = , entries = () )

  networkinfo.macAddress() -> ""
  networkinfo.networkStatus() -> 6
  networkinfo.networkName() -> "TIM"
  networkinfo.networkSignalStrength() -> 61

NetworkMode: QNetworkInfo::WlanMode
  networkinfo.currentNetworkMode() -> 8
  networkinfo.networkInterfaceCount() -> 1
  networkinfo.interfaceForMode() -> QNetworkInterface(name = "wlan0", hardware address = "10:68:3F:FE:09:8F", flags = IsUp IsRunning CanBroadcast CanMulticast , entries = ((address = QHostAddress("192.168.2.61") , netmask = QHostAddress("255.255.255.0") , broadcast = QHostAddress("192.168.2.255") ) , (address = QHostAddress("fe80::1268:3fff:fefe:98f%wlan0") , netmask = QHostAddress("ffff:ffff:ffff:ffff::") ) ) )

  networkinfo.macAddress() -> "10:68:3f:fe:09:8f"
  networkinfo.networkStatus() -> 1
  networkinfo.networkName() -> "sheevanetN"
  networkinfo.networkSignalStrength() -> -1

NetworkMode: QNetworkInfo::EthernetMode
  networkinfo.currentNetworkMode() -> 8
  networkinfo.networkInterfaceCount() -> 0

NetworkMode: QNetworkInfo::BluetoothMode
  networkinfo.currentNetworkMode() -> 8
  networkinfo.networkInterfaceCount() -> -1

NetworkMode: QNetworkInfo::WimaxMode
  networkinfo.currentNetworkMode() -> 8
  networkinfo.networkInterfaceCount() -> -1

NetworkMode: QNetworkInfo::LteMode
  networkinfo.currentNetworkMode() -> 8
  networki...

Read more...

Changed in qtsystems-opensource-src (Ubuntu Saucy):
status: New → Confirmed
Revision history for this message
Ricardo Salveti (rsalveti) wrote :
Download full text (3.6 KiB)

Ok, so indeed two issues:
1) Applications unable to retrieve network status of ofono based modems:
That's because the only way to retrieve that information, currently, is indeed via ofono:
src/systeminfo/linux/qnetworkinfo_linux.cpp:
===
...
    case QNetworkInfo::GsmMode:
    case QNetworkInfo::CdmaMode:
    case QNetworkInfo::WcdmaMode:
    case QNetworkInfo::LteMode:
    case QNetworkInfo::TdscdmaMode:
#if !defined(QT_NO_OFONO)
        qDebug() << "getting network status for modem";
        if (QOfonoWrapper::isOfonoAvailable()) {
            if (!ofonoWrapper)
                ofonoWrapper = new QOfonoWrapper(this);
            QStringList modems = ofonoWrapper->allModems();
            if (interface < modems.size()) {
                QString modem = ofonoWrapper->allModems().at(interface);
                if (!modem.isEmpty())
                    return ofonoWrapper->networkStatus(modem);
            }
    }
#endif
        break;
===

Status, following the oFono doc:
        string Status [readonly]

            The current registration status of a modem.

            The possible values are:
                "unregistered" Not registered to any network
                "registered" Registered to home network
                "searching" Not registered, but searching
                "denied" Registration has been denied
                "unknown" Status is unknown
                "roaming" Registered, but roaming

Which is what we want indeed.

Now before we go and implement another method to provide the information we need, why do you think GetProperties reveals too much information for the apps?

2) The issue with Mako, when ofono is disabled, is that it returns NoNetworkAvailable for wlan because mako's driver fails to report the proper signal via /proc/net/wireless. As a quick workaround (due the broken drivers), I'd suggest trusting only on
/sys/class/net/wlan0/carrier instead.

Follows the patch:
diff --git a/src/systeminfo/linux/qnetworkinfo_linux.cpp b/src/systeminfo/linux/qnetworkinfo_linux.cpp
index effdc93..03649c1 100644
--- a/src/systeminfo/linux/qnetworkinfo_linux.cpp
+++ b/src/systeminfo/linux/qnetworkinfo_linux.cpp
@@ -869,8 +869,7 @@ QNetworkInfo::NetworkStatus QNetworkInfoPrivate...

Read more...

Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Opened bug 1231196 for the second issue (wlan and mako).

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

It is too much information as seen from this command:
$ dbus-send --system --print-reply --dest=org.ofono /ril_0 org.ofono.NetworkRegistration.GetProperties

It tells the:
 * LocationAreaCode
 * CellId
 * technology
 * MobileCountryCode
 * MobileNetworkCode
 * Name (carrier)
 * Strength

Technology and Strength are arguably harmless, the others are an information leak for apps.

Revision history for this message
Tony Espy (awe) wrote :

I think I followed this up on the mailing list, and may be delinquent a response.

First, the NetworkRegistration interface only really tells you that the device registered to a network for voice. Whether or not an active mobile data connection is available is a different question. You can tell by looking at the current data context.

On the mailing list however I mentioned that it was probably preferable for applications to ask NM about connections instead of going directly to ofono's DBus interface. Also it should be noted that qtsystems-opensource-src was written prior to our integration of ofono and NetworkManager.

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

NetworkManager suffers from similar problems-- it doesn't have a simple interface for determining connectivity, but instead reveals much about the system. It seems like the bug is more in the fact that on mako, searching /proc and /sys doesn't give what's needed.

Changed in qtsystems-opensource-src (Ubuntu Saucy):
status: Confirmed → Won't Fix
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Marking as "Won't Fix" for qtsystems-opensource-src since there is now a connectivity-api that apps can use.

Changed in qtsystems-opensource-src (Ubuntu Trusty):
status: Confirmed → Won't Fix
Changed in qtsystems-opensource-src (Ubuntu):
status: Confirmed → Won't Fix
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

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