Extracted from Cyanogen wiki.
In Android, each app runs as its own UID (user ID) just like multiple people would have their own UID on a big UNIX system. The reasoning is the same, to prevent apps (people) from messing with each other’s data. The data for each app has to be ‘owned’ by the UID the app runs as, and additionally the app itself (.apk file) has to be that same UID. Unlike big UNIX systems, these IDs are stored in the packages.xml file in /data/system. This file, in addition to storing UIDs, stores the android permissions of each program as described in its manifest (permissions like writing to the sdcard, monitoring phone state, turning wifi on and off, accessing bluetooth, etc). If the file is damaged, deleted, or otherwise unreadable, it is regenerated. The app UIDs are assigned initially in the order you install them (10001, 10002, etc.). When the packages.xml regenerates, it grabs the Android permissions from the .apks but doesn’t know what the old UIDs were. That’s where fix_permissions comes in.
Whether run from recovery or a booted system, fix_permissions reads through the packages.xml file and performs a chown/chmod command (which changes owner/change read-write-execute permissions) on each .apk and the data directory for it. It doesn’t fix Android permissions (e.g. if phone.apk lost the ability to make calls, fix_permissions wouldn’t help — see below). While CM updates the version of fix_permissions in the ROM on a semi-regular basis, the version in any given recovery is probably older (and recoveries aren’t upgraded on phones as often, either). So if fix_permissions in recovery doesn’t work, the one in the booted rom might (or vice versa).
Run the following commands in terminal :
su
fix_permissions