[LinuxFocus-icon]
�����  |  �����  |  ������  |  �����

������� | ������ | ������ | ��� LF
��� ������� �������� ��: English  Castellano  Deutsch  Francais  Nederlands  Portugues  Russian  Turkce  

[image of the authors]
����� Fr�d�ric Raynal, Christophe Blaess, Christophe Grenier
<pappy(_at_)users.sourceforge.net, ccb(_at_)club-internet.fr, grenier(_at_)nef.esiea.fr>

�� ������:

Christophe Blaess - ����������� ������� �� �����������. �� ���������� Linux � ������ ������� ����� ����� ������ �� ���� �������. �������� ������������ ��������� man �������, ����������� Linux Documentation Project.

Christophe Grenier - ������� 5 ����� � ESIEA, ��� �� ����� �������� ����������. �������� ���������� ������������ �������������.

Fr�d�ric Raynal ����� ��� ���������� Linux, ������ ��� �� �� ���������� ���������� �����, �� ���������� �� �������, �� MSG, �� �������� ���� �� �������� ... ������ ������� ���� � ��������.



������� �� �������:
Kolobynin Alexey <alexey_ak0(_at_)mail.ru>

����������:

 

��� �������� ��� � ������������ ��� ���������� ���������� - ����� 5: ������� ��������� (race conditions)

[article illustration]

������:

����� ������ �� ����� ����� ��������� ��������� ������������, ��������� � ����������������. ������� ��������� ��������� � ������, ����� ��������� �������� ���������� ���� � ��� �� ������ (����, ����������, ������) � ���� � �� �� �����, � ������ �� ��� "��������", ��� ����� ����������� ������. ��� �������� � ��������� ����������� ������, � ����� � ��������� ��� � ������������, ������� ����� ��������� ����� ������ �������.

_________________ _________________ _________________

 

��������

�������� �������, ������������ ������� ���������, ���������: ������� ������ �������� ����������� ������ � ���������� �������. �� ���������, ��� ������ ��� �� ������������ ������ ���������, � ����� ���������� ��� �� ������ ����������. ������� ��������� ���������, ����� ������ ������� �������� ������������ ��� �� ������ � ���������� ������� ����� ��������� ������ ��������� ����� ������� � ����������� ��� ��������������. �������� �������, ����������� ��� ����, ����� ���� ����������. ������������ �������� � ������ �� - ���������� ����� ���������. ���� ��� �������� � ���� � ��������� ��� ���� � ���� � ������������, ����� ���� ������� ��������� ���������� ������������ �������.

��� ���, ��� �� ����� ������� ��������, ����� ��������������� ������. ����� ����� �������� ��������� �������������� � ������������ � ����� ���� Linux ��� ������������ ������ � ������. �� ����� ����� ������������� ��������� ���������� � ��� ��������� ����� �������� ���� �������� �������. ��� ��������� �� ������ � ������� ������, �� � � ������� ������� � ����������� ��� ������ ����������� ����� ����� �� ���������� /dev/.

���� �����, �����, ������������ �� ��������� ������������ �������, ������������ ������ Set-UID ����������, ��� ��� ��������� ����� ��������������� ������������ ��������� ������������ �����. ������, � ������� �� ������������ ����� ��� � ������������ (������������ ������, ������ �������, ...), ������� ��������� ������ �� ��������� ���������� "�������" ����. ��� ������ ������ ���� ���� �������� ������������ ������� ���������, ���� ��� �����������. ���� ��� ����� ����� ����� ���� ��������� � �� "����������" ��������� (�� Set-UID), �������� ��� �� ����� � ������ �� ������� ������������, ������� ������� �� root, � ����, ����� �� �������� ������ ����������, ����� �������� ������ � ��� ��������. ���, ��������, ������ � ����� (� ������� ~/.rhost, ��� ������ "+ +" ����������� ������ ������ � ����� ������ ��� ������) ��� ������ ����������������� ����� (������������� ����������� ������, ������ ����������� ����������, ���� �������, ������ ����, ...)

� ������� �� ��� � ������������, ������������ � ���������� �������, ������ �������� ����� ��������� �� ���� �����������, � �� ������ � Set-UID �������� � ��������� �������� ��� �������.

 

������ ������

���������� ��������� Set-UID ���������, ������� ����� ��������� ������ � �����, ������������� ������������. �� ����� ��, ��������, ����������� ������ �������� ������������ ���������, ����� ��� sendmail. �����������, ��� ������������ ����� ������ ��� ��� �����, ��� � ��������� ��� ������ � ����, ��� ���������� ������������� ��� ��������� ���������������. � ���� ������ ���������� ������ ���������, ����������� �� ���� ����, ������������ ���������. ��� ����� ��������, ��� ���� �� �������� ������������� ������� �� ��������� ����. �� ����� ��������, ��� ���� ��������� Set-UID root, � �� ��������� �������� ����� ���� �� ������. �������������� ��� ������� ��������� ����� �� ����� �������� UID. ������� ������� ���-������ �����:

1     /* ex_01.c */
2     #include <stdio.h>
3     #include <stdlib.h>
4     #include <unistd.h>
5     #include <sys/stat.h>
6     #include <sys/types.h>
7
8     int
9     main (int argc, char * argv [])
10    {
11        struct stat st;
12        FILE * fp;
13
14        if (argc != 3) {
15            fprintf (stderr, "������������� : %s ���� ���������\n", argv [0]);
16            exit(EXIT_FAILURE);
17        }
18        if (stat (argv [1], & st) < 0) {
19            fprintf (stderr, "�� ������ %s\n", argv [1]);
20            exit(EXIT_FAILURE);
21        }
22        if (st . st_uid != getuid ()) {
23            fprintf (stderr, "�� �������� %s \n", argv [1]);
24            exit(EXIT_FAILURE);
25        }
26        if (! S_ISREG (st . st_mode)) {
27            fprintf (stderr, "%s �� �������� ������� ������\n", argv[1]);
28            exit(EXIT_FAILURE);
29        }
30
31        if ((fp = fopen (argv [1], "w")) == NULL) {
32            fprintf (stderr, "���������� �������\n");
33            exit(EXIT_FAILURE);
34        }
35        fprintf (fp, "%s\n", argv [2]);
36        fclose (fp);
37        fprintf (stderr, "������ �������\n");
38        exit(EXIT_SUCCESS);
39    }

��� �� ��������� � ����� ������ ������, ���� �� ����� ��� Set-UID ���������� �������� �������� ���� ���������� � ������� ����, ��������� UID ������������, ������������ ���. ����������, ������������� �������� ������������� ������, ���������������� ������ ������� ������������. ������ ���������� ��� ID root-�, �� ������ �� ������ ��������, ��������� UID ������ ������������ ��������� UID. � ��� ��, �� ������� ���� ��� ��� � ����, ���� ���� ��� �� ��� �� � �������������, ��� ������� ��� ������ ��������, ����� ���������������� ����� � ������������.

��� �� ����� ������, ��������� �������� ����������, ���������� ��� ����������� ��������, �� ����: ���� ����������, ����������� ������������ � ��� ������� ����. ����� ��� ��������� ���� � ���������� ���������. ��� ��� ��������� ����! ���, ����� �����, ��� � ���������� ������� ����� ������� ��������� ����� ��� ������ stat() � ��� ��������� ��� ������ fopen(). ���� ���������� ����� ������������ ���, ������ ��������� ����� �������������� �� � �������� ��������� �����. ����� ������� ���� ����� �������, ������� ������, ������� �������� ������� ����� ����� ����� ����������, ����� ������� �� ������� �����, ����� ������� ������ �������. �������� ������ 30 (����� ������) � �������:

30        sleep (20);

������ ������� �������� ���������. ������� ������� �� Set-UID root. �������, ��� ����� �����, ��������� ����� ������ ����� ������� /etc/shadow:

$ cc ex_01.c -Wall -o ex_01
$ su
Password:
# cp /etc/shadow /etc/shadow.bak
# chown root.root ex_01
# chmod +s ex_01
# exit
$ ls -l ex_01
-rwsrwsr-x 1 root  root    15454 Jan 30 14:14 ex_01
$

��� ������ ��� �����. �� � ����������, ������������� ���. �� ����� Set-UID root ������� (����� ex_01), ���������� ���� � ������������, � ������ �������� ������, ��������������� root �� ����� ������� /etc/shadow �� ������, ���������� ������ ������.

������� �� ������� ���� fic, ������������� ���:

$ rm -f fic
$ touch fic

�����, �� ��������� ���� ���������� � ������� ������. �� ������ ��� �������� ������ � ���� ����. ���������� ��������� ��� ������� � "��������" �� ��������� ����� ����� ��������� �������� � �����.

$ ./ex_01 fic "root::1:99999:::::" &
[1] 4426

���������� ������ root ����� �� man �������� shadow(5), ����� ������ - �� ��� ������ ���� ����� (��� ������). ���� ������� ����, � ��� ���� ����� 20 ������, ����� ������� ���� fic � �������� ��� ������� (������������� ��� ������� - ��� ���������) �� ���� /etc/shadow. ��������, ��� ����� ������������ ����� ��������� ������ �� ���� � ������������ ��� ����������, ���� ���� �� �� ����� ��������� ��� ���������� (��� � /tmp, ��� �� ������ ���� �������). ������ ���������� ������� ����� ������ �����, ��� ��� ��� ������� ��� ������� ���������.

$ rm -f fic
$ ln -s /etc/shadow ./fic

����� �� �������� �������� ������� ������� ex_01 � ������������ ����� ��� ������ ������� fg � �������� ���� �� ����������:

$ fg
./ex_01 fic "root::1:99999:::::"
Write Ok
$

�����! ������. ���� /etc/shadow �������� ������ ���� ������, ������� �������, ��� root �� ����� ������. �� �� ������?

$ su
# whoami
root
# cat /etc/shadow
root::1:99999:::::
#

�������� ��� �����������, ������ ������ ���� �������:

# cp /etc/shadow.bak /etc/shadow
cp: replace `/etc/shadow'? y
#
 

����� ������������

�� ������������ ������� ��������� � Set-UID root �������. �������, ����� �������, ��� ��������� ��������� 20 ������, ����� �� ������ ����� �� ��� �������� ����. � ��������� ���������� ������� ��������� �������� ��� ������������� ������ �� ����� �������� �����. ��� �� �� ������������� ��?

������ �������� ���������� �� ����� "������ �����", �������� ������� �����, ������ ��� ������� ����� ���, ��������� �������, ����� ���������������� �������. �������� �������� ����� "�������" � ���� � ������������ ��� ������ ��������� ����������, ������������ �� ���������� ���������� ������� ����� ����� ����������, �������, ��� ����������� �������� ���������, ���������� ���. ���� ������� � ���������� ��������, ����� ���� ����� ������������ �������� ����� ������������ �����. ���� ������ ������� ��� �������:

�����, ����������� ��� ��������������� ����� � ������������, ���������� �� ������� ���������, ���������� ������� � ������, ������ �� ��������! ��������� ����� �������� ����������� ������� ��������.

 

��������� ������������������

��������, ������� ����������� ����, �������� �� ����������� �������� �������������� ������� � ���������� ������� ����� ����� ����������, �� ������ ����������. � ���������� �������� ��������� �� �������� ������ �����. ����� ������, �������� ������������, ���� �� ���������� ������ �������� ��� ���� ��������� ���� /etc/shadow. ����������, ��������� �������� ����� ����� ������������ �������� ������� � ������ ���� � ����� ������, ��� ���������� ���������. ��������, ��� ����������� ��������� ������ (rm, mv, ln � �.�.) ������������ �� ��� �����, � �� �� ��� ����������. ���� ���� �� �������� ���� (��������� rm � ��������� ����� unlink()), ��-���������� ���������� ��� ���������, ����� ��������� ���������� ����� - ��������� ������� ������ - ����� �������.

������, ������� ���� ������� � ���������� ���������, ���������� ��-�� ����, ��� �� ��������, ��� ���������� ����� ������ ����� � ��� ���������� ���������, ���, ��� �������, ��������� � ���������� ������� ����� ���������� stat() � fopen(). ������� ������� ������ ����������, ����� ��������������, ��� ��� ������������ ������ �� ���������. �������� ������, ��������� ����� ��� ������. � ����������, ������� ����������� ���, �� ������� ����� ������ �� ��������� ����. �����������, �������� � ����� ������� � ����� �����������. ����� -f ������� ln ���������� ������� ������ ���� ���� ��� ��� ����������:

$ ln -f /etc/fstab ./myfile
$ ls -il /etc/fstab myfile
8570 -rw-r--r--   2 root  root  716 Jan 25 19:07 /etc/fstab
8570 -rw-r--r--   2 root  root  716 Jan 25 19:07 myfile
$ cat myfile
/dev/hda5   /                 ext2    defaults,mand   1 1
/dev/hda6   swap              swap    defaults        0 0
/dev/fd0    /mnt/floppy       vfat    noauto,user     0 0
/dev/hdc    /mnt/cdrom        iso9660 noauto,ro,user  0 0
/dev/hda1   /mnt/dos          vfat    noauto,user     0 0
/dev/hda7   /mnt/audio        vfat    noauto,user     0 0
/dev/hda8   /home/ccb/annexe  ext2    noauto,user     0 0
none        /dev/pts          devpts  gid=5,mode=620  0 0
none        /proc             proc    defaults        0 0
$ ln -f /etc/host.conf ./myfile
$ ls -il /etc/host.conf myfile 
8198 -rw-r--r--   2 root  root   26 Mar 11  2000 /etc/host.conf
8198 -rw-r--r--   2 root  root   26 Mar 11  2000 myfile
$ cat myfile
order hosts,bind
multi on
$

����� -i ������� /bin/ls ������� ����� ���������� ����������� � ������ ������. �� �����, ��� ���� ��� ��������� �� ��������� ���������� ��������� �����������.

����������, ��� �������� ��, ����� �������, ������� ������ �������� � ������������ ������ � �����, ������ ���������� � ����� � ��� �� ����������, � � ����� � ��� �� ��������� ������������. � ��� ��������! ���� ���� ������������� ��������� ���� �������������, ����� ������������� ��� �������� ����������. ����� �� ��������� ���� ��� ������, ��������� ����� open() ���������� ����� �����, ������� �������� ������������, ������������� � ���������� ������ �� ���������� �������. ��� �������� ������, ������� �� ����� ����� �����������, ����� ���������� � ����������� ����� �����, �� ��������, ��� ���������� � ������, ������� ���� ������������ ��� �������� ��������.

������� ������� ���� ������: ���� ���� ��� ������, ����� �������� ��� ������ �����, ������� ��� ��������, �� ����� ������ �� ���������� �����. ���� ���� ��� �������, ���������� � ������������ �����, ���������� ����� �� ��������� � �����, ���� ���� ��� ��� �������� �� ����������, ��� ��� ����������. ���� ������������ ���������� � ���������� ����� ����� ��������� ������� open(), ������� ������������� �������� ����������, � ������������� ����� ����������� ��� ������ close() ��� ����������� ��������.

���� �� ����� ���� �������! �� ����� ������� ����, � ����� ��������� ����� �������, ������ �������������� �����������, � �� ������-�� ����� �����. ��� ����� ������� ��������� ��������� ����� fstat() (�������� ��� �� ��� � stat()), ������� ��������� �������� ����������, � �� ������� ���. ����� �������� ������ � ����������� �����, ��������� ����������, �� ����� ������������ ������� fdopen() (������� �������� ��� �� ��� � fopen()), ��� ��� ��� ���������� ����������, � �� ��� �����. ��� ����� ���������� ���������:

1    /* ex_02.c */
2    #include <fcntl.h>
3    #include <stdio.h>
4    #include <stdlib.h>
5    #include <unistd.h>
6    #include <sys/stat.h>
7    #include <sys/types.h>
8
9     int
10    main (int argc, char * argv [])
11    {
12        struct stat st;
13        int fd;
14        FILE * fp;
15
16        if (argc != 3) {
17            fprintf (stderr, "������������� : %s ���� ���������\n", argv [0]);
18            exit(EXIT_FAILURE);
19        }
20        if ((fd = open (argv [1], O_WRONLY, 0)) < 0) {
21            fprintf (stderr, "���������� ������� %s\n", argv [1]);
22            exit(EXIT_FAILURE);
23        }
24        fstat (fd, & st);
25        if (st . st_uid != getuid ()) {
26            fprintf (stderr, "%s �� �������� !\n", argv [1]);
27            exit(EXIT_FAILURE);
28        }
29        if (! S_ISREG (st . st_mode)) {
30            fprintf (stderr, "%s �� �������� ������� ������\n", argv[1]);
31            exit(EXIT_FAILURE);
32        }
33        if ((fp = fdopen (fd, "w")) == NULL) {
34            fprintf (stderr, "���������� �������\n");
35            exit(EXIT_FAILURE);
36        }
37        fprintf (fp, "%s", argv [2]);
38        fclose (fp);
39        fprintf (stderr, "������ �������\n");
40        exit(EXIT_SUCCESS);
41    }

������, ����� ������ 20, ������� ��������� ����� ����� (��������, ��������������, �������� ������) �� ������ ������� �� ��������� ����� ���������; ���������� ��������� ����������� ����� ����� ����������.

 

�������� ��������

��� ������ � ������, ����� ���������� ����������� ������������ ����� ���������� �������������� � �������� ���������� �����. �� �������� �������� ������������ ������������� ��������� ��������� ������� ��� ������ � ����������� ������� ����� �������� �����������, � �� �� ������������, ������������ ���� � �����:

��������� ����� �������������
fchdir (int fd) ��������� � ����������, �������������� fd.
fchmod (int fd, mode_t mode) �������� ����� ������� � �����.
fchown (int fd, uid_t uid, gid_t gif) �������� ��������� �����.
fstat (int fd, struct stat * st) ���������� �� �����������, ������������ � ��������� ����������� ����������� �����.
ftruncate (int fd, off_t length) �������� ������������ ����.
fdopen (int fd, char * mode) �������������� ����-����� �� ��� ��������� �����������. ��� ��������� ���������� stdio, � �� ��������� �����.

��� �����, �����������, �� ������ ������� ���� � ������ ������, ������ open() (�� ������� ��� ������ �������� ��� �������� ������ �����). ��������� � ������ open() ��������� �����, ����� ����� ��������� �������� � ���������� �������.

�� ���������� �� ������������� ��������� ������������ ��� ��������� �������. ��������, �������� (���� ���� ��� �� ����� ������ ������ � ��������� ���������) �� ��������, ������������ � ������ ����������� /bin/login, ��� ������������ ��������� ���� ������. ������ ���������� ������������� ������������� ������ � ������� root, ���� �� �������� ���� /etc/passwd. ����� ��������� ����� ���������� ����������, ���� ���� �������� �������������� ������������ �������� �������. ������, ��������, ��� ���������� ������� ����, ������ �������� �� ������������� �����, ��������� ����� ���������. ����� /bin/login ����� �������� ����������� ���������� ���������� ������������, �������� �������� ������ ������������ ������ � ������� root... �������� � ���� ������������, ������� ����������, ��������� ����� ��������� �� ������ ������� ��� ��� ������ ��������� �����, �� � ��� ������, ����� ��� ��� ������������� �����-���� ��������, ��������� � ������������� �������.

 

������� ��������� � ���������� �����

���������, ������������ ��������� �������������, �� ������ ��������� �� ����������� ������ � ����������� �����. ����� �����, ����� ������� ������� ��������� ���� ������������� ������� ��������� ��� ������ � ����� ������. �������� ��������� ������� �� ������������, ������������ ������������ ��������� ����� Set-UID root ���������� ��� ������������ ���������������� ��������� ���������� � ����� �������, ������� ������� ������� ���������, �� ����� �������� ���������� ���������� ����� ����� ���� �������������� ������������� �������.

����� ��������� �� ���� ������������ � ������ ���� ���������, ���������� ������ �������� ������������ ������� � ����� ������. ��� �� �� ��������, ������� ��������� � ����� ������, ����� ��������� ������������� ��������� ������������ ������ ������ � �������� ���������� �����. ������� ���������� ����� ������ ��� ��������.

����� ������� ������ ���������� ������ � ����, �� ������� � ���� ������������� ���� ���� ��� ����� ���. ���� ������� ������ ����������, �� ���� ������ ������� �� ����� ��������� ���������� ����� ����� ���, ��� �������, ��� �� ����� �����. �������� �������, ������� ������� ���������� ����� ������� ����������� �����, ����� ���� ���������, ��� ������� ��������� �� ����� �������, ���� �� ������ ����������.

�� ����� ����, ������� �����, ��� �� �������: ���� ��������� ����������, ��������� ��� ������ � ��� ������. ��������� �������� ����� ������������ ������� ���������� ��� ������, ��� ��� �� ���� �� ��� �� ���������� �������� ���������� �����. ������, � ������ ���������� ������� ������ ���� ������� ����� ������� ���������� ��� ������, � � ��� ����� �� ����� ���� ������������� ������� ������ ����������, ���� �� ������.

���������� ��� ���� ���������� (�� ������� ����� ���� � ������ �� �����������). ������, �� BSD, ������� �� ��������� ������ flock(). ������ �������� ������ - ���������� �����, � �������� �� ������� �������� ����������� ������, ������ - ���������� ���������, �������� ��������, ������� ����� �������������. ��� ����� ��������� ��������� ��������: LOCK_SH (���������� ��� ������), LOCK_EX (��� ������), LOCK_UN (������ ����������). ������� ��������� ������� �� �����, ���� ����������� �������� ����������. ������, �� ������ ���������� �������� ��� | ������� ��������� � ���������� LOCK_NB, ����� ������� �������� ����������� ������ ����, ����� ������������������.

������ ��� ����������, �� System V, ������� �� ��������� ������ fcntl(), ������� �������. ���������� ������������ ������� lockf() ������� � ���������� ������, �� �� �� �����. ������ �������� fcntl() - ���������� ����� ��� ����������. ������ - ������������ ����������� ��������: F_SETLK � F_SETLKW ��������� ������������, ������ ������� ���������������� ������� ���� �������� �� ���������� ���������, � �� ����� ��� ������ ����� �� ���������� ���������� ��� ��������� �������. F_GETLK ��������� ��������� ���������� ����� (��� ���������� ��� ��������������� ����������). ������ �������� - ��������� �� ���������� ���� struct flock, ������� ��������� ����������. ������ ���� ��������� flock ���������:

��� ��� ��������
l_type int ��������� ��������: F_RDLCK (���������� ��� ������), F_WRLCK (��� ������) and F_UNLCK (��� ������ ����������).
l_whence int ��� �������� ���� l_start (������ SEEK_SET).
l_start off_t ������� ������ ���������� (������ 0).
l_len off_t ����� ����������, 0 ��� ���������� ����� �����.

�� ����� ������, ��� fcntl() �������� ����������� ������������ ����� �����, ��� ����� ������ ����� ���� �� ��������� � flock(). ������� �������� �� ���������, ������� ����������� ���������� ��� ������ ��� ������, ����� ������� ������� ��� ���������, � ������� ���� ������������ ������ ���� ����� ������� (� ������� ����������).

1    /* ex_03.c */
2    #include <fcntl.h>
3    #include <stdio.h>
4    #include <stdlib.h>
5    #include <sys/stat.h>
6    #include <sys/types.h>
7    #include <unistd.h>
8
9    int
10   main (int argc, char * argv [])
11   {
12     int i;
13     int fd;
14     char buffer [2];
15     struct flock lock;
16
17     for (i = 1; i < argc; i ++) {
18       fd = open (argv [i], O_RDWR | O_CREAT, 0644);
19       if (fd < 0) {
20         fprintf (stderr, "���������� ������� %s\n", argv [i]);
21         exit(EXIT_FAILURE);
22       }
23       lock . l_type = F_WRLCK;
24       lock . l_whence = SEEK_SET;
25       lock . l_start = 0;
26       lock . l_len = 0;
27       if (fcntl (fd, F_SETLK, & lock) < 0) {
28         fprintf (stderr, "���������� ������������� %s\n", argv [i]);
29         exit(EXIT_FAILURE);
30       }
31     }
32     fprintf (stdout, "������� ���� ��� ������ ����������(��)\n");
33     fgets (buffer, 2, stdin);
34     exit(EXIT_SUCCESS);
35   }

������� �� ��������� ��� ��������� � ������ �������, ��� ��� ����� �������:

$ cc -Wall ex_03.c -o ex_03
$ ./ex_03 myfile
������� ���� ��� ������ ����������(��)
>� ������� ���������...
    $ ./ex_03 myfile
    ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ������������� myfile
    $
������� ���� �� ������ �������, �� ������� ����������.

��� ������ ��������� ����������, �� ������ �������� ��������� ������� ��������� � ����������� � �������� ������, ��� ����� lpd, ������� ���������� flock() ��� ���������� ����� /var/lock/subsys/lpd, ����� ������� �������� ������ ���� ��������� ��� ����������. �� ����� ������ ��������� ��������� �������� � ��������� ������, ����� ��� � ���������� pam ���� /etc/passwd ����������� ��� ������ fcntl(), ��� ��������� ������ ������������.

������, ����� �������� ������� ��� ������ �� ������������� ��������� ���������� ����������, �� ���� ����������, ������� ����������� � ���� ���������� �� ��������� ������, ����� ������� ��� ������� � ������ ��������� ����. �� ���� �� ������� � ���������� ������������ - ����� ���������� ������������ ��������� � ������ � ������. � ���������, ����� ��������� ��������� ����� �������� ���������� �����, ���� ���� ������ �������, � ���������� ����������, ������������ ��� ��� ������. ��� ������. �� ���������� ��������� ���� � ���� � ��������� ���, ��������� ���������� ���������:

$ echo "FIRST" > myfile
$ ./ex_03 myfile
������� ���� ��� ������ ����������(��)
> � ������ ������� �� �������� ����:
    $ echo "SECOND" > myfile
    $
����������� �� ������ �������, �� ��������� "�����������":
(����)
$ cat myfile
SECOND
$

����� ������ ��� ��������, ���� Linux ������������� ���������� �������������� �������� ������������ �� System V. ������� �� ������ ������������ ���� �������� ������ ��� ������ fcntl(), �� �� flock(). ������������� ����� ������� ����, ��� ���������� fcntl() �������, ������������ ����������� ���������� ���� �������. �����, ���� ������� ��������� ���� ��� ������, ������ ������� �� ������ �������� ���� ���� (���� root). ����������� ���������� ����, ������� ������������, - ��� ������������� ��� Set-GID ��� ������ ���� ���������� ��� ������. ����� ����� �������� ��������:

$ chmod g+s-x myfile
$
������ ����� �� ����������. ����� ������������� ������������ �������� ����������� ������������ ��� ��������� � �����, ������ ���� ���������� ������� mandatory ��� �������, ��� ��������� ���� ����. ������, ��� ���� �������� ���� /etc/fstab � �������� ���� ����� mand � 4-�� ������� ��� ������ �������:
# mount
/dev/hda5 on / type ext2 (rw)
[...]
# mount / -o remount,mand
# mount
/dev/hda5 on / type ext2 (rw,mand)
[...]
#
������ �� ����� ���������, ��� ��������� � ������ ������� ����������:
$ ./ex_03 myfile
������� ���� ��� ������ ����������(��)
>� ������� ���������:
    $ echo "THIRD" > myfile
    bash: myfile: Resource temporarily not available
    $
� ����������� �� ������ �������:
(����)
$ cat myfile
SECOND
$

��������������-�� ������������ ������� ������� ������� �� ������������� ������� ���������� ������ (�������� /etc/passwd ��� /etc/shadow). ������������ ���������� ������������� ������� ������� � ������, ��� ��������� ��� ���������� ��� ������ ���������� ������ � �������, � ��� ������ ��� �� ������� ����� ������ ���������, ���� ����� ��������� ��������� ��������� ��� ����������.

 

��������� �����

����� ����� ��������� ���������� �������� ��������� ������ �� ������� �����. �������� ������ - ������� ������ � �������� ��������������� �������������� �����, ��� ������������ �������� ����� ��������� ����� �� ��������� ����� ��� ���������� ����� ����������. �����, ��������� ����� unlink() ������� �������� ���� � rename() ��������� ��������� ���� �� ����� ���������.

�������� ���������� �����, ���� ��� �� ������� ������� �������, ����� ���������� ��������� ������� �������� ������� ��������� ��� �������������� ������������. ���� � ������������, ���������� �� ��������� ������, ���� ������� ���������� � ����� ����������� ��� Apache, Linuxconf, getty_ps, wu-ftpd, rdist, gpm, inn � �.�. �������� ��������� ���������, ������� �������� �������� ������ ���� �������.

��� �������, �������� ���������� ����� ���������� � ���������� /tmp. ��� ��������� ���������� �������������� �����, ��� �������� ������, ����������� �� �������� ���������� �������. ����� ��� ��������� ����������� ������������� ������ �������� ������ (��������� cron), � ����� ������������ ��� ���� ������ ��������� ������, ������������� ��� �������� � �.�. ������ ������������� ���������� �������������� ��� ��������� ������ � ������ <paths.h> � <stdio.h> � ����������� ����������� �������� _PATH_TMP � P_tmpdir. �� ����� ����, ������������� ���������� �� ���������, �������� �� /tmp, �� ����� ������, ��� ��� ��� ��������� �������������� ���� ����������, ������� ���������� C. ������, ��������, ��� ��������� ������������ �� GlibC �� ��������� � ���������� � ���������� ������� ����� ���� �������� ��������� ���������� ��������� TMPDIR. ������� ������������ ����� ������� ���, ����� ��������� ����� ����������� � ����������, ������������� ���, � �� � /tmp. ��� ������ ����������, ��������, ����� ������, ���������� ��� /tmp, ������� ���, ����� ��������� ���������� ��������� ����� ����� ��� �������� ��������� ������.

��������� ���������� /tmp ���� ������������� ��-�� ���� �������:

 $ ls -ld /tmp
drwxrwxrwt 7 root  root    31744 Feb 14 09:47 /tmp
$

Sticky-Bit, �������������� ������ t � ����� ��� ������������ �������� 01000, ��� ���������� � ���������� ����� ����������� ����������: ������ �������� ���������� (root) � �������� �����, ������������ � ���� ����������, ����� ������� ���� ����. ���������� ����� ������ ����� ��� ������, ����� ������������ ����� ���������� ��� ���� �����, ������ ���������, ��� ��� �������� - ��� ������� �� ��������� ������, ���������� ����������.

��� �� �����, ������������� ���������� ��� ���������� �������� ������ ����� ������� ��������� ��������. ������ � ������������ ������ Set-UID root ����������, ������������������ � �������������. ������, ��������� �������� �����. ���� ���� ������� ������� ������, ���������, ��� ���������� ���������� ��������� ������, ��������, SIGTERM ��� SIGQUIT ��� �������� �������, �� ���������� ������ ��������� �����, ��� ����������, �� �� ������������. � ������ ������� ��� �������� � /tmp/dead.letter. �������, ������������ ����� ���� ���� ���� ������� (��� ��� �� ����� ������ � /tmp) ��� �������� ��������� (������������� � ����������� UID-�� root-�) ������� ������ �� /etc/passwd � ������ dead.letter, ����� �������� � ���� ���� ���������� �������������� ������ (�������� ����������� ������ "root::1:99999:::::").

������ �������� ����� ������ ��������� - ��������������� ����� �����. �� ������ ���� ��� ����������� �� ���������� � �������, ��� ��� ����� ������������ ��� ����� /tmp/dead.letter. ������� ������ ��� - ������������ ��� �����, ���������� ��� ������� ���������� ���������. ���������� ��������� ������������ �������, ������� ����� ������������ ��� �������������� ��� ���������� �����.

�����������, � ��� ���� �������� �������, ������� ���� ��� ���������� ��� ��� ������ ���������� �����. �������� ����������� ����������� �������� ������ � �������� ����� (�� �� ����� � ��� ���������� C), � �������, ��� ����� ������������, ���� ��� ������� ������� �������. ��������� ����� ������� ������������� ������ � ������, ��������������� ����������� C. ���� ������ ������� - ���������, ���������� �� ���� ����� ��� ���������. ������ �� ������� ���-������ �����:

  if ((fd = open (filename, O_RDWR)) != -1) {
    fprintf (stderr, "%s ��� ����������\n", filename);
    exit(EXIT_FAILURE);
  }
  fd = open (filename, O_RDWR | O_CREAT, 0644);
  ...

��������, ��� �������� �������� ������� ���������, ��� ���� � ������������ ��������� ������� ��� �������� ������������, ������������ � �������� ������ �� /etc/passwd � ���������� ����� ������ � ������ open(). ��� ��� �������� ������ ���� ������� ������, ����� ���������� ���� ���������� �������� ����� ����. ��� ��������, ���� ������������ ����������� ����� ���������� ������ open(). ��� ���������� O_EXCL � ������������ ������ � O_CREAT. � ���� ������, open() �������� �����������, ���� ���� ��� ����������, ������ �������� �� ������������� ����� � ���������.

����� ������, ���������� Gnu 'x' ��� ������� �������� � ������� fopen() ������� ������������� ��������, ������� �������� �����������, ���� ���� ��� ����������:

  FILE * fp;

  if ((fp = fopen (filename, "r+x")) == NULL) {
    perror ("���������� ������� ����.");
    exit (EXIT_FAILURE);
  }

����� ������� � ��������� ������ ����� ������ ������ ����. ���� �� �������� ������ ���������� � ���� � ������� 644 (������/������ ��� ���������, ������ ��� ���������), ����� �������� ������������. �������

	#include <sys/types.h>
	#include <sys/stat.h>

        mode_t umask(mode_t mask);
��������� ���������� ����� ������� � ����� � ������ ��������. �������, ����� ������ umask(077), ���� ����� ������ � ������� 600 (������/������ ��� ���������, ������� ���� ������).

������ �������� ���������� ����� ���������� � ��� �����:

  1. �������� ����������� ����� (����������) ;
  2. �������� �����, ��������� O_CREAT | O_EXCL � ������ ������������� ������� �������;
  3. �������� ���������� �������� ����� � ����������� ��������������� �������� (������ ��� �����).

��� ������� ��������� ����? �������

      #include <stdio.h>

      char *tmpnam(char *s);
      char *tempnam(const char *dir, const char *prefix);

���������� ��������� �� �������� ��������� �����.

������ ������� ��������� �������� NULL, � ���� ������ ��� ���������� ����� ������������ ������. ��� ���������� ����� �������� ��� ��������� ������ tmpnam(NULL). ���� �������� - ������, ��� ������� �������� ������, ��� ���������� � ���, ��� �������, ����� ������ �������� ������� �� L-tmpnam ����. ����� ��������� � ������������� ������! �������� man ������������� � ���������, ����� ������� ������������ � ���������� NULL � ���������� _POSIX_THREADS ��� _POSIX_THREAD_SAFE_FUNCTIONS.

������� tempnam() ���������� ��������� �� ������. ���������� dir ������ ���� "����������" (�������� man �������� ���������� �������� ����� "���������� (suitable)"). ��� ������� ���������, ��� ���� �� ����������, ����� ��������� ��� �����. ������, �����, �������� man �� ����������� ������������ dir, ��� ��� ��� "����������" ����������� ����� ��������������� ������ � ����������� �� ���������� �������. ��������, ��� Gnome �������� ������������ ������� ��������� �������:

  char *filename;
  int fd;

  do {
    filename = tempnam (NULL, "foo");
    fd = open (filename, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, 0600);
    free (filename);
  } while (fd == -1);
����, �������������� �����, ��������� ���������, �� ������� ��� ����. ��� ��������, ���� ������, ��� �� ����� ������� ��������� ���� ��������, ��� ������� ��� ������� ����������� ���������� ���������� ������...

�������

       #include <stdio.h>

       FILE *tmpfile (void);
������� ���������� ��� ����� � ��������� ���. ���� ���� ������������� ��������� ��� ��������.

� GlibC-2.1.3 ��� ������� ���������� ������� ������� ��� � � tmpnam() ��� �������� ����� �����, � ����� ��������� ��������������� ����������. ����� ����� ���� ���������, ������ Linux ������� ������� ���, ���� �� ������ �� ������������ ������� ��������, �� ���� ��� ������������ ����������� ��� ������ ���������� ������ close().

   FILE * fp_tmp;

   if ((fp_tmp = tmpfile()) == NULL) {
    fprintf (stderr, "���������� ������� ��������� ����\n");
    exit (EXIT_FAILURE);
  }

  /* ... ������������� ���������� ����� ... */
  fclose (fp_tmp);  /* �������� �������� �� ������� */

� ���������� ������� ��� �� ����� �������� ��� ����� ��� ���������� ��� ������� ��������, ������ ������� � ��� ������ � ������������ �� �� ��������� �������. ������� ��� �� ����� ����� ��� ���������� �����, � ������ ���������� ����� ������ � �����������. ������� tmpfile() ������ ��� � ������.

�������� man ����� �� ������������ ��, ������ Secure-Programs-HOWTO �� ����������� �� �������������. �� ������ ������, ������������ �� ����������� �������� �����, � �� �� ����� ��������� ������ ����������. �������� �� ��� ���������, ��� ������� �������� ����������.

� ���������, �������

       #include <stdlib.h>

       char *mktemp(char *template);
       int mkstemp(char *template);
������� ���������� ��� �� �������, ������� ������������� "XXXXXX". ��� ���� ����������, ��� ����� �������� ���������� ��� �����.

� ����������� �� ������, mktemp() �������� ������ ���� 'X' �� ������������� �������� (PID)... ��� ��������� ����� ������� ��� ���: ������ ��������� ���� ���������. ��������� ������ ��������� ������������� ����� ����� �����.

mkstemp() - �������������� ������� � Secure-Programs-HOWTO. ��� ����� �������������:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>

 void failure(msg) {
  fprintf(stderr, "%s\n", msg);
  exit(1);
 }

/*
 * ������� ��������� ���� � ���������� ���.
 * ��� ��������� ������� ��� ����� �� �������� �������, �������
 * ��� �� ����� ��� ��������� ����������.
 */
FILE *create_tempfile(char *temp_filename_pattern)
{
  int temp_fd;
  mode_t old_mode;
  FILE *temp_file;

  /* �������� ����� � ������������� ������� ������� */
  old_mode = umask(077);
  temp_fd = mkstemp(temp_filename_pattern);
  (void) umask(old_mode);
  if (temp_fd == -1) {
    failure("���������� ������� ��������� ����");
  }
  if (!(temp_file = fdopen(temp_fd, "w+b"))) {
    failure("���������� ������� ���������� ���������� �����");
  }
  if (unlink(temp_filename_pattern) == -1) {
    failure("���������� ������� ��������� ����");
  }
  return temp_file;
}

��� ��� ������� ���������� ��������, ��������� � ����������� � ��������������. �� ����, �� ������� ���������� ���������� ��������� �������������� ��������� ����� ������������ (����������)... ������ ������ �� ���������� �������� � ����������� �� ������� (�������������). ��������, ������� tmpfile() ��������� ��������� ���� �� ������� (� ��������� ������� �� ������������ O_EXCL), ��� mkstemp() ������������ ��������� ���������� ����� � ����������� �� ����������.  

�����

�� ����������� ����� ��� �������� ������������, ���������� ������� ��������� �� ��������� � ������ ������ ��������. ��������, ��� �� �� ������ ������� ������������, ��� ��� ���������������� �������� ������ ��������������� ����������� �����������, ���� ������ ����� ���������� �� ��������� ����. ��� ��� ������� ��������� ������� ���� � ������������, �� �� ������ ������������ � ������, ����������� �� �������������� ������ ��������, ����� ��� ���������� ��� ���������� ������� ���������� ��� �������� ������, ����������� � �������������� shmget(). ������ ������������� ��������� �������������� ������� (��������, ��������), ����� �������� ���������� ��� ����������� ������.

 

������


 

�������� �������

� ������ ������� ���� �������� �������. �� ���� �������� �� ������ �������� ���� ����������� ��� ����������� ����������� ������ ��������� :
 talkback page 

Webpages maintained by the LinuxFocus Editor team
© Fr�d�ric Raynal, Christophe Blaess, Christophe Grenier, FDL
LinuxFocus.org

Click here to report a fault or send a comment to LinuxFocus
Translation information:
fr --> -- : Fr�d�ric Raynal, Christophe Blaess, Christophe Grenier <pappy(_at_)users.sourceforge.net, ccb(_at_)club-internet.fr, grenier(_at_)nef.esiea.fr>
fr --> en: Georges Tarbouriech <georges.t(_at_)linuxfocus.org>
en --> en: Lorne Bailey <sherm_pbody(_at_)yahoo.com>
en --> ru: Kolobynin Alexey <alexey_ak0(_at_)mail.ru>

2002-09-20, generated by lfparser version 2.30