Hi,
regarding 1.)
2FF synchronizer are ok.
Because, if you go from fast to slow clock. You will not get every pointer value on the slow side. But due to the gray coding you will always have a stable value. With this the remaining logic is ok and stable.
Regarding 2.) You are right. The full or early detection may be to late or early. But it is always on the save side. E.g. looking at full. This is detected on the write side. You get a synchronized read pointer. This is either the correct pointer, or it shows the status of some cycles before. So you may detect a full scenario, but your fifo isn't full anymore. But you will never write into a full fifo. You will only stop your pipeline, when it isn't needed.
regards