diff options
author | Manuel Bentele | 2020-11-09 07:48:36 +0100 |
---|---|---|
committer | Manuel Bentele | 2020-11-09 07:48:36 +0100 |
commit | 07684ba72271a1307124eb71904f5c5aa1aebe43 (patch) | |
tree | 52a84fdb774e0145b41f872338f44bc4ad2f10e2 | |
parent | [KERNEL] protect access to server list if alt server is added/removed (diff) | |
download | dnbd3-07684ba72271a1307124eb71904f5c5aa1aebe43.tar.gz dnbd3-07684ba72271a1307124eb71904f5c5aa1aebe43.tar.xz dnbd3-07684ba72271a1307124eb71904f5c5aa1aebe43.zip |
[KERNEL] protect read-only access to server list
This patch completes the changes from the last commit [1] and protects
in addition the read-only access to the alternative list of new servers.
Otherwise a race condition between ioctl ADD_SRV/REM_SRV (process
context) and dnbd3 discover thread would be possible since the
'new_servers_num' field is changed in both contexts.
[1] - DNBD3 commit db5a93a43fea2aa3c3bbaf8c48d238e60d834676
-rw-r--r-- | src/kernel/blk.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/kernel/blk.c b/src/kernel/blk.c index 7e043c0..c6b4598 100644 --- a/src/kernel/blk.c +++ b/src/kernel/blk.c @@ -184,23 +184,26 @@ static int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int { result = -ENOENT; } - else if (dev->new_servers_num >= NUMBER_SERVERS) - { - result = -EAGAIN; - } else if (msg == NULL) { result = -EINVAL; } + + /* protect access to 'new_servers_num' and 'new_servers' */ + spin_lock_irqsave(&dev->blk_lock, irqflags); + if (dev->new_servers_num >= NUMBER_SERVERS) + { + result = -EAGAIN; + } else { - spin_lock_irqsave(&dev->blk_lock, irqflags); + /* add or remove specified server */ memcpy(&dev->new_servers[dev->new_servers_num].host, &msg->hosts[0], sizeof(msg->hosts[0])); dev->new_servers[dev->new_servers_num].failures = (cmd == IOCTL_ADD_SRV ? 0 : 1); // 0 = ADD, 1 = REM ++dev->new_servers_num; - spin_unlock_irqrestore(&dev->blk_lock, irqflags); result = 0; } + spin_unlock_irqrestore(&dev->blk_lock, irqflags); break; case BLKFLSBUF: |