-
Stephen C. Tweedie authored
I've been chasing a weird SELinux bug which shows up mostly when doing installs of a dev-* rpm (ie. creating and overwriting lots of block device inodes), but which I've also seen when doing mkinitrd. It turned out not to be an SELinux problem at all, but a core VFS S_ISBLK bug. It seems that SELinux simply widens the race window. The code at fault is fs/fs-writeback.c:__mark_inode_dirty(): /* * Only add valid (hashed) inodes to the superblock's * dirty list. Add blockdev inodes as well. */ if (!S_ISBLK(inode->i_mode)) { if (hlist_unhashed(&inode->i_hash)) goto out; if (inode->i_state & (I_FREEING|I_CLEAR)) goto out; } The "I_FREEING|I_CLEAR" condition was added after the ISBLK/unhashed tests were already in the source, but I can't see any reason why we'd want the I_FREEING test not to apply to block devices. And indeed, this results in all sorts of inode list corruptions. Simply moving the I_FREEING|I_CLEAR test out of the protection of the S_ISBLK() condition fixes things entirely. The existing 2.6 kernel will reliably fail on me in about 2 seconds once "rpm -Uvh --force dev*.rpm" starts its actual installation of the new inodes. With the patch below I can't reproduce it at all.
2cecfc0f