abstract 3d futuristic network technology on black backgrounds

A race condition occurs when two or more threads can access shared data and try to change it at the same time. Because the thread scheduling algorithm can switch between threads at any time, it does not know the order in which the threads will try to access the shared data. Therefore, the result of the change in the data depends on the thread scheduling algorithm, that is, both threads compete for access to change the data.

For example, let’s imagine a program belonging to root that stores information in a file owned by the user who is executing the program; surely the code will contain lines similar to the following:

if (access (file, W_OK) == 0) {open (); write ();}

In normal execution, if the user does not have sufficient privileges to write to the file, the call to access () will return -1 and writing will not be allowed. If this call does not fail, open () will not fail either, since the effective UID under which the program is running is that of root; this way we are making sure that the program writes to the file if and only if the user who executes it can do it – without additional privileges due to the setuid -. But,> what happens if the file changes between the call to access () and the following ones? The program will be writing to a file on which the necessary checks have not been carried out to guarantee security. For example, let’s imagine that after the call to access (), and just before open () is executed, the user deletes the referenced file and links / etc / passwd with the same name: the program will be writing information to the file of passwords.

This type of situation, in which a program checks a property of an object and then executes a certain action assuming that the property is maintained, when it really is not, is called TOCTTOU (Time of check to time of use). > What can be done to avoid it? The operating system itself gives us the different solutions to the problem ([BD96]). For example, we can use file descriptors instead of names: in our case, we should use a variant of the access () call that works with descriptors instead of file names (it doesn’t really exist, it would be necessary to modify the kernel of the operation to achieve it); With this we achieve that even if the name of the file is modified, the object that we access is the same during all the time.

However, there are calls that use file names and do not have an equivalent that uses descriptors; In order not to have to reprogram the entire Unix kernel, there is a second solution that also covers these calls: associate a descriptor and a file name without restricting the access mode. For this, a special opening mode would be used, O_ACCESS – which would need to be implemented – instead of the classic O_RDONLY, O_WRONLY or O_RDWR; This new mode would guarantee that if the object exists, a regular open () would be made on it but without the right to write or read (it would be necessary to make a second call to the function, with the appropriate parameters), and if it does not exist a name is reserved and an inode of type `reserved ‘, a type of transition that would later be necessary to convert into a common file type in Unix (directory, socket, link …) with the corresponding calls.

See also:
IDE – Visual Programming environment
Rust – A programming language loved by its community


Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *