[pso] [T2 Linux] Race conditions in exemplul de char device din enuntul temei
Stefan Bucur
stefan.bucur at gmail.com
Wed Aug 20 21:11:22 EEST 2008
Salut!
Poate nu am luat in considerare toate aspectele, insa am impresia ca
exemplul de char device de conversie upper-case dat ca punct de
pornire este gresit pentru ca permite situatii de race (nu neaparat
pt. sisteme SMP). Structura:
struct case_dev {
struct cdev cdev;
char buffer[BUFFER_SIZE];
unsigned put, get;
atomic_t fill;
wait_queue_head_t wq_reads, wq_writes;
} devs[CASE_MAX_MINORS];
este sincronizata doar la nivelul campului fill, incat codul urmator
poate genera o situatie de race:
static int case_read(struct file *file, char *user_buffer,
size_t size, loff_t *offset)
{
int i=0;
struct case_dev *dev=(struct case_dev*)file->private_data;
if (file->f_mode&O_NONBLOCK) {
if (atomic_read(&dev->fill) == 0)
return -EAGAIN;
} else {
if (wait_event_interruptible(dev->wq_reads, atomic_read(&dev->fill) > 0))
return -ERESTARTSYS;
}
while ((atomic_read(&dev->fill)>0) && size) {
if (put_user(dev->buffer[dev->get], &user_buffer[i]))
return -EFAULT;
dev->get++; dev->get%=BUFFER_SIZE;
i++; size--; atomic_dec(&dev->fill);
}
if (atomic_read(&dev->fill) < BUFFER_SIZE)
wake_up(&dev->wq_writes);
return i;
}
Aici, presupunem ca sunt 2 procese care citesc simultan din device si
dev->fill = 1. Primul proces reuseste sa intre in bucla while, apoi
pp. ca kernel-ul este preemptat, si al doilea proces intra in while
(faptul ca dev->fill este atomica nu ne ajuta cu nimic aici), si
rezultatul net este ca se va citi de 2 ori din buffer si
atomic_dec(&dev->fill) va fi executat de doua ori, starea device-ului
devenind una invalida.
Acesta e doar un exemplu de race - si dev->get++ poate genera un race
daca preemptarea are loc in mijlocul incrementarii.
Solutia evidenta mi se pare folosirea unui spinlock care sa protejeze
buffer-ul si variabilele de stare asociate, insa as dori sa stiu daca
exista ceva ce-mi scapa mie si rationamentul de mai sus e gresit.
Multumesc,
Stefan Bucur
More information about the pso
mailing list