3.5.5: please review nasty API change in wireless extensions

Stefan Winter swinter at kde.org
Thu Sep 28 15:55:05 BST 2006


Hi folks,

I received a mail by Jean Tourillhes about an upcoming API change in the 
wireless extensions which removes NULL termination on SSIDs. Nasty thing, I 
hope the minimal patch (inline, at the end) gets it right. It should get into 
3.5.x soon, because probably the next kernel 2.6.19 will use the new API and 
might break stuff.
Here's the (long) mail describing the API change, afterwards comes my patch. 
Please review, I'd like to commit it before the 3.5.5 deadline passes.

++++++++++++++ Fwd from Jean Tourillhes ++++++++++++++++

You are the maintainer of an user-space application using
Wireless Extensions. I'm planning some incompatible changes to the
Wireless Extensions in version 21 that might affect your application,
and wanted to let you know so that you have the time to prepare your
application for this change.

        The main change affect the ESSID length.

        The original API for ESSID was designed this way :
---------------------------------------------------
                wrq.u.essid.pointer = myessid;
                wrq.u.essid.length = strlen(myessid) + 1;
---------------------------------------------------
        This is valid up to WE-20.

        Starting with WE-21, the API will be :
---------------------------------------------------
                wrq.u.essid.pointer = myessid;
                wrq.u.essid.length = strlen(myessid);
---------------------------------------------------

        The way to design an application working with both version of
Wireless Extensions looks like this :
---------------------------------------------------
                wrq.u.essid.pointer = myessid;
                wrq.u.essid.length = strlen(myessid);
                if(iwrange.we_version_compiled < 21)
                        wrq.u.essid.length++;
---------------------------------------------------

        This also means that when reading an ESSID, the string will no
longer be NULL terminated, and you will have to terminate it yourself.
        Something like this works with all versions of the API :
---------------------------------------------------
                memset(myessid, '\0', IW_ESSID_MAX_SIZE+1);
                memcpy(myessid, wrq.u.essid.pointer, wrq.u.essid.length);
---------------------------------------------------

        The Wireless Tools 28-pre15 and later are fully compliant with
those changes, you can look at them for inspiration.

        Rationale...
        The initial API was designed with safety in mind, the extra
NULL character make sure the string is always NULL terminated. The
downside is that this was less logical, people expect the lenght field
to reflect the true lenght of the data.
        Over the years, I had to fix many drivers for that. However,
today the number of drivers has increased, and I don't always have to
time to audit each driver and convince the author to accept my
patch. The current situation is that some drivers work one way, some
other driver work another way, and there is no longer any consistency.
        After discussion with some driver authors, they convinced me
that the more logical way was preferable. Vox populi...

        I know that such a change is painful for all you guys (I share
the pain). However, the drivers are already in an inconsistent state,
doing different things, which is even more painful in the long run.
        This change is probably a few months away. However, if you
take into account the time it takes for distro to package stuff, you
may want to be ready before that time.

        Good luck...

        Jean

++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Patch:

Index: interface_wireless_wirelessextensions.cpp
===================================================================
--- interface_wireless_wirelessextensions.cpp   (revision 589644)
+++ interface_wireless_wirelessextensions.cpp   (working copy)
@@ -139,7 +139,8 @@
     }

   /* Get ESSID */
-  wrq.u.essid.pointer = (caddr_t) WIFI_CONFIG(info,essid);
+  /* prepare NULL-terminated buffer in case the string returned by 
SIOCGIWESSID is NOT NULL-terminated */
+  memset(wrq.u.essid.pointer, '\0', IW_ESSID_MAX_SIZE + 1);
   wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
   wrq.u.essid.flags = 0;
   if (iw_get_ext (skfd, ifname, SIOCGIWESSID, &wrq) >= 0)

Greetings,

Stefan Winter (now in the i18n BoF)




More information about the kde-core-devel mailing list