There is at least one scenario by which this could be fixed by software, even a standard patch applied to all phones.
Apps (even Apples Compass app) do not make direct calls to the hardware, they get their data via the OS (e.g. the CMAttitude Class in the CoreMotion framework returns various numbers relating to the phones attitude). There are several reasons for this, but one is that the hardware itself in this instance needs calibration i.e. fine-tuning so that we know that a particular hardware reading equates to e.g. a perfectly horizontal phone. These calibration data are probably held in some non-volatile memory, and are set as the phones come through the production line, with each phone getting its own specific calibration data written into the NVRAM. The OS is then supposed to take the raw hardware reading, apply the calibration data from the NVRAM, and then give the calibrated reading to the app.
The problem we are seeing could be due to an iOS7 bug such that it either fails to apply the calibration data or it reads the wrong bit of the NVRAM so it applies an incorrect or zero calibration. If such a bug was fixed to make the OS apply the calibration data correctly, the results returned to the app would then be correctly calibrated again.
So all our phones may have the correct calibration data sitting on them but an iOS7 bug means these data are ignored and the OS is giving uncalibrated data. Because different phones have different calibration values, different phones show different incorrect values as a result of the bug. Occasionally, the raw values need only a very small or no correction, so these phones show the correct value.