The difference between effective/permitted capabilities is similar to the difference between real/effective UIDs in setuid programs. The idea isn't to stop a rogue app from escalating privs (you wouldn't grant them privs in the first place, same as you wouldn't setuid them) but to allow a program to run with minimal privileges and only escalate where necessary. This helps minimize the impact of bugs
A very contrived example: I want to have a program that will let me send a SIGHUP to processes owned by the user or to allow a God user to send SIGHUP to
This program has the CAP_KILL capability set on the file.
The pseudo code might look something like:
if process_id==1 and user_is_God:
The obvious bug, here, is that I don't check that the user is allowed to send the signal in the first place. Because I've dropped the effective CAP_KILL permission I won't be allowing the user to kill processes other than their own.
Very contrived, for sure! But the idea is to run as far as possible with "least privileges" and only enable privileges when necessary.
Now this won't necessarily protect against buffer overflow attacks because the injected code could enable permitted privileges, so capability aware code should also drop permitted privileges once they are no longer needed; eg a webserver might drop CAP_NET_BIND_SERVICE after it has bound to port 80. You can't enable something not in your permitted set!