Встретил занятный код в ядре линукса, возможно будет интересно.
http://lxr.linux.no/#linux+v3.8/fs/select.c#L816
Код:
816 int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
817 struct timespec *end_time)
818 {
819 struct poll_wqueues table;
820 int err = -EFAULT, fdcount, len, size;
821 /* Allocate small arguments on the stack to save memory and be
822 faster - use long to make sure the buffer is aligned properly
823 on 64 bit archs to avoid unaligned access */
824 long stack_pps[POLL_STACK_ALLOC/sizeof(long)];
825 struct poll_list *const head = (struct poll_list *)stack_pps;
826 struct poll_list *walk = head;
827 unsigned long todo = nfds;
828
829 if (nfds > rlimit(RLIMIT_NOFILE))
830 return -EINVAL;
831
832 len = min_t(unsigned int, nfds, N_STACK_PPS);
833 for (;;) {
834 walk->next = NULL;
835 walk->len = len;
836 if (!len)
837 break;
838
839 if (copy_from_user(walk->entries, ufds + nfds-todo,
840 sizeof(struct pollfd) * walk->len))
841 goto out_fds;
842
843 todo -= walk->len;
844 if (!todo)
845 break;
846
847 len = min(todo, POLLFD_PER_PAGE);
848 size = sizeof(struct poll_list) + sizeof(struct pollfd) * len;
849 walk = walk->next = kmalloc(size, GFP_KERNEL);
850 if (!walk) {
851 err = -ENOMEM;
852 goto out_fds;
853 }
854 }
855
856 poll_initwait(&table);
857 fdcount = do_poll(nfds, head, &table, end_time);
858 poll_freewait(&table);
859
860 for (walk = head; walk; walk = walk->next) {
861 struct pollfd *fds = walk->entries;
862 int j;
863
864 for (j = 0; j < walk->len; j++, ufds++)
865 if (__put_user(fds[j].revents, &ufds->revents))
866 goto out_fds;
867 }
Вызвав сисколл
poll с параметрами
ufds (указатель) и
nfds (unsigned int), попадаем в функцию do_sys_poll() с этими же параметрами.
Здесь могла бы быть неплохая, пусть и не из легких, бага, если бы строка 835 располагась всего двумя строчками ниже

Тогда при передаче nfds = 0, из цикла сразу бы происходил выход, не вызывая copy_from_user(), которая проверяет "правильность" переданного указателя
ufds, и ниже происходил вызов __put_user(), которая такой проверки не делает.
Получили бы запись неопределённых данных (из stack_pps[]) по любому желаемому адресу в ядре.
С неопределённостью можно бороться, например, предварительным массажем стека.