Wednesday, 16 November 2011

Google's _nomap SSID madness

Now, I try to write positive comments on my blog, but now and again things really irk me and I need to comment about them.  

Google is using wireless access point SSIDs to construct a database to enable devices to determine their location using wireless and hence not relying on GPS.   If you want to opt out of this database, Google is suggesting that one should simply append _nomap to the SSID.   Google also hopes that this will become a standard SSID opt-out for any location service database.

This basically means that if you want your desired SSID you get opted into Google's database (so much for privacy), otherwise you have to put up with some utterly stupid name that Google mandates.  Thanks for the choice Google.  And there is nothing to stop other location service providers either suggesting a different naming scheme to make it impossible to opt out of one or more schemes.

Now, if the UK government mandated that all SSIDs needed to be named in a specific way to opt out of their special database, there would be uproar.  However, Google just ploughs ahead with more of their data gathering and nobody seems to complain.

Monday, 7 November 2011

Does your UEFI firmware have CSM support or not?

UEFI  Compatibility Support Module (CSM) provides compatibility support for traditional legacy BIOS.  This allows allows the booting an operating system that requires a traditional option ROM support, such as BIOS Int 10h video calls.

While looking at boot and runtime misbehaviour on UEFI systems I would like to know if CSM is enabled or not, but the question is how does one detect CSM support?   Well, making the assumption that CSM is generally enabled to support Int 10h video calls, we look for any video option ROMs and see if the real mode Int 10h vector is set to jump to a handler in one of the ROMs.

Option ROMs are found in the region 0xc0000 to 0xe0000 and normally the video option ROM is found at 0xc0000.  Option ROMs are found on 512 byte boundaries with a header bytes containing 0x55, 0xaa and ROM length (divided by 512) so we just mmap in 0xc0000..xe0000 and then scan the memory for headers to locate option ROM images.

My assumption for CSM being enabled is that Int 10h vectors into one of these option ROMs, and we can assume it is a video option ROM if it contains the string "VGA" somewhere in the ROM image.  Yes, it is a hack, but it seems to work on the range of UEFI enabled systems I've so far used.

For reference, I've put the code in my debug-code git repository and available for anyone to use.

I've also added a CSM test to the Firmware Test Suite (fwts).  One can install fwts and run the test on Ubuntu by using:

 sudo apt-get install fwts  
 sudo fwts csm -  

Friday, 28 October 2011

UEFI Secure Boot and Linux

There has been a lot of (heated) discussion in the past weeks concerning UEFI Secure Boot and how this can impact on the ability of a user to install their operating system of choice.

To address this, today has seen no less than two papers published to address this hot topic.  Canonical along with Red Hat have published a white paper that describes how UEFI Secure Boot will impact users and manufactures.   The paper also provides recommendations on the implementation of UEFI Secure Boot in way that allows users to be in control of their own PC hardware.

Meanwhile the Linux Foundation has also published a paper giving technical guidance on how to implement UEFI Secure Boot to allow operating systems other than Windows 8 to operate on new Windows 8 PCs.

So lots to read and good technical guidance all round.  Let's  hope that these constructive set of papers will push the argument into a positive outcome.

Sunday, 23 October 2011

Determining the number of arguments in a C vararg macro

C vararg macros are very useful and I've generally used them a lot for wrapping C vararg functions.  However, at times it would be very useful to be able to determine the number of arguments being passed into the the vararg macro and this is not as straight forward as it first seems.

Anyhow, this problem has been asked many times on the usenet and internet, and I stumbled on a very creative solution by Laurent Deniau posted on comp.std.c back in 2006.

 #define PP_NARG(...) \  
      PP_NARG_(__VA_ARGS__,PP_RSEQ_N())  
 #define PP_NARG_(...) \  
      PP_ARG_N(__VA_ARGS__)  
 #define PP_ARG_N( \  
      _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \  
      _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \  
      _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \  
      _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \  
      _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \  
      _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \  
      _61,_62,_63,N,...) N  
 #define PP_RSEQ_N() \  
      63,62,61,60,          \  
      59,58,57,56,55,54,53,52,51,50, \  
      49,48,47,46,45,44,43,42,41,40, \  
      39,38,37,36,35,34,33,32,31,30, \  
      29,28,27,26,25,24,23,22,21,20, \  
      19,18,17,16,15,14,13,12,11,10, \  
      9,8,7,6,5,4,3,2,1,0  
   
 /* Some test cases */  
 PP_NARG(A) -> 1  
 PP_NARG(A,B) -> 2  
 PP_NARG(A,B,C) -> 3  
 PP_NARG(A,B,C,D) -> 4  
 PP_NARG(A,B,C,D,E) -> 5   

However, passing no arguments to this macro yields 1, which is not as we expect. So last night I tweaked the macro to fix this problem by checking the length of the stringified macro arguments and adjusting the return value for a empty __VA_ARGS__  - as follows:

 #define PP_NARG(...)  (PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) - \  
     (sizeof(#__VA_ARGS__) == 1))  
 #define PP_NARG_(...)  PP_ARG_N(__VA_ARGS__)  
   
 #define PP_ARG_N( \  
    _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \  
   _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \  
   _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \  
   _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \  
   _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \  
   _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \  
   _61,_62,_63, N, ...) N  
   
 #define PP_RSEQ_N() \  
     63,62,61,60,          \  
     59,58,57,56,55,54,53,52,51,50, \  
     49,48,47,46,45,44,43,42,41,40, \  
     39,38,37,36,35,34,33,32,31,30, \  
     29,28,27,26,25,24,23,22,21,20, \  
     19,18,17,16,15,14,13,12,11,10, \  
     9,8,7,6,5,4,3,2,1,0  

The purists may point out that PP_NARG() only handles 64 arguments.  For just integer arguments, a better solution for any number of arguments has been proposed by user qrdl on stackoverflow:

 #define NUMARGS(...) (int)(sizeof((int[]){0, ##__VA_ARGS__})/sizeof(int)-1)

..which is appealing as it is more immediately understandable than the PP_NARG() macro, however it is less generic since it only works for ints.

Anyhow, it's great to find such novel solutions even if they may be at first a little bit non-intuitive.