For code called in user context, it's very common to defy C convention, and return 0 for success, and a negative error number (eg. -EFAULT) for failure. This can be unintuitive at first, but it's fairly widespread in the kernel.
encode a negative error number into a pointer, and
to get it back out again: avoids a separate pointer parameter for
the error number. Icky, but in a good way.