main.c edited to fix random corruption of configuration file
There’s a flaw in the NVRAM encryption process which, by 20% of the chance, will cause the saved configuration file become corrupted. This commit is to fix this problem. Here’s the detail. Whenever NVRAM variables contain any control characters which ASCII values are less than 32(0x20), data corruption may occur when saving configuration file, either by using tomato GUI menu Administration/Backup Configuration or command line: nvram save filename.cfg. This problem will cause restoration failure either in GUI menu Restore Configuration or command line: nvram restore filename.cfg, WITHOUT showing any error messages. When this error occurs, only the NVRAM variables before the corrupted data are restored while any data after it is lost. The most common scenario that control characters are used in nvram is Line Feed(0x0A) and Carriage Return(0x0D), usually appears in custom scripts in firewall, init, etc. The root cause lies in nvram_arm/main.c in the following code: Line 68: rand = get_rand() % 30; Line 88: if (buf[i] == 0x0) buf[i] = 0xfd + get_rand() % 3; else buf[i] = 0xff - buf[i] + rand; Line 68 generate a random value from 0 to 29 and store it in “rand”. Starting from line 88, it uses this value to convert the original NVRAM value to the encrypted one. When it meets 0, which is a separator for NVRAM variables, random value of 0xfd, 0xfe, 0xff are used to represent it in the encrypted format. However, when NVRAM contains control characters such as 0x0A, and the random value happens to be 0, 1, or 2 less, in this case, “rand” = 0x08, 0x09 or 0x0A, the encrypted value will be 0xfd, 0xfe, 0xff, which is the same as “0” in the encrypted format. This results in decryption failure because the encrypted value of 0xfd, 0xfe, 0xff not only means 0, it also can be 0x0A, 0x0D, etc. The original values are lost and the data corruption occurs. While the perfect solution could be a complete makeover of this algorithm, the less perfect one is to walk around it. So far, only control characters of 0x0A and 0x0D are found to be used in NVRAM variables. By excluding the random value(in “rand”) from 8 to 13, value 0x0A and 0x0D will never to encrypted to 0xfd, 0xfe and 0xff, thus avoid the problem. The updated code contains a do…while loop to check if “rand” is between 8 to 13, if true, get the random number again until it’s not. This fix only works when the NVRAM contains no other control characters. If it does, corruption still occurs. However, this is quite uncommon. The up side of this fix is: it doesn’t interfere with the decryption algorithm by only use less number of random values in the encryption process. No change has to be made in the restore process for things to work. It’s totally compatible with any existing good configuration file. The fix has been tested in my ARM router and so far so good.arm-ng
parent
24bad8d1ba
commit
32fdfa7f61
Loading…
Reference in New Issue