The preferred way of securing tftpd is to use the tftp SELinux targeted policy module. This post is now of historic interest only, I have SELinux enabled, using the targeted policy in enforcing mode. That is the right way of doing things.
On RHEL systems, tftpd is started from xinetd as a root user. The configuration is stored in /etc/xinetd.d/tftp. You may wish to run it as a different user for security purposes. Let's assume that the tftpd user has been created, with login directory set accordingly to /tftpboot.
There are two ways you could try to set tftpd to run as non-root, and only one of them works. You may try to change the user entry in the xinetd configuration file. This will fail when in.tftpd tries to set its supplementary group to nobody, thus -- if you strace -- the following call fails:
[pid 16429] setgroups32(1, ) = -1 EPERM (Operation not permitted)
Instead, you should add the -u parameter to the tftpd's command line in its xinetd config file.
server_args = -s /tftpboot -u tftpd -v
where tftpd should be replaced with whatever username you chose for tftpd. That way in.tftpd changes its effective user upon startup.
If you don't want the files served by tftpd to be visible by unprivileged users from the local host (say, if tftpd serves to devices on an isolated, secure network), you should make the /tftpboot directory not world-readable (# chmod o-rwx /tftpboot). Do not change permissions on the files in that directory, though: in.tftpd insists that they be world-readable. This makes sense, since -- in a way -- they do become world-readable via in.tftpd, and the latter doesn't know what other restrictions there may be in place due to network architecture. The files should also be owned by root, that way you can control write access by granting it to others: in this case only the tftpd user will be able to access them anyway, do to permissions on the /tftpboot directory. Remember: tftpd offers no protections from unauthorized access. It is up to your firewall and network architecture to limit access as appropriate.
You can strace a running xinetd process and all its children like so:
# strace -p $(ps -o pid= -C xinetd) -fF