Bug 5924

Summary: {add,del}{user,group}: missing locking support on /etc/ databases
Product: Busybox Reporter: Kyeong <kyeongyoo>
Component: OtherAssignee: unassigned
Status: NEW ---    
Severity: normal CC: busybox-cvs
Priority: P5    
Version: 1.18.x   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Host: Target:
Build:
Attachments: Possible fix for the adduser issue

Description Kyeong 2013-02-12 02:10:11 UTC
Created attachment 4742 [details]
Possible fix for the adduser issue

If multiple "adduser" command is executed in parallel, /etc/passwd and /etc/shadow files are corrupted and easily causes the device not bootable due to missing user names like "root".

For example, the following script will add 30 users in parallel and the resulting /etc/passwd file is normally truncated.

N=${1:-30}
I=1
while [ $I -le $N ]; do
  USER=$(printf "user-%02d" $I)
  echo ==== $USER
  adduser -H -h /flash -D -s /sbin/startshell -g group -G wheel $USER &
  I=$((I+1))
done


I've attached a possible fix for this which resolves:
1. Previously if "passwd+" file is not cleaned up (say due to "adduser" being killed), then second "adduser" cannot modify "passwd" file forever.
2. Added flock() to detect unoccupied "passwd+" file (so the second process can delete it).
3. Make sure to open "passwd" file after getting proper permission to use "passwd+". Otherwise the old "passwd" may be used instead.

I've also checked the code is same in 1.21.0.
Comment 1 Mike Frysinger 2016-02-18 06:48:08 UTC
we'll want to implement the same algorithm that shadow does.  namely, create an /etc/xxx.lock file and unlink it when we're done.  that way we're also in sync with other tools in case people are running them.