@@ -336,12 +336,9 @@ static struct dentry *sel_make_dir(struct dentry *dir, const char *name,
336
336
unsigned long * ino );
337
337
338
338
/* declaration for sel_make_policy_nodes */
339
- static struct dentry * sel_make_disconnected_dir (struct super_block * sb ,
339
+ static struct dentry * sel_make_swapover_dir (struct super_block * sb ,
340
340
unsigned long * ino );
341
341
342
- /* declaration for sel_make_policy_nodes */
343
- static void sel_remove_entries (struct dentry * de );
344
-
345
342
static ssize_t sel_read_mls (struct file * filp , char __user * buf ,
346
343
size_t count , loff_t * ppos )
347
344
{
@@ -508,13 +505,13 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
508
505
struct selinux_policy * newpolicy )
509
506
{
510
507
int ret = 0 ;
511
- struct dentry * tmp_parent , * tmp_bool_dir , * tmp_class_dir , * old_dentry ;
512
- unsigned int tmp_bool_num , old_bool_num ;
513
- char * * tmp_bool_names , * * old_bool_names ;
514
- int * tmp_bool_values , * old_bool_values ;
508
+ struct dentry * tmp_parent , * tmp_bool_dir , * tmp_class_dir ;
509
+ unsigned int bool_num = 0 ;
510
+ char * * bool_names = NULL ;
511
+ int * bool_values = NULL ;
515
512
unsigned long tmp_ino = fsi -> last_ino ; /* Don't increment last_ino in this function */
516
513
517
- tmp_parent = sel_make_disconnected_dir (fsi -> sb , & tmp_ino );
514
+ tmp_parent = sel_make_swapover_dir (fsi -> sb , & tmp_ino );
518
515
if (IS_ERR (tmp_parent ))
519
516
return PTR_ERR (tmp_parent );
520
517
@@ -532,8 +529,8 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
532
529
goto out ;
533
530
}
534
531
535
- ret = sel_make_bools (newpolicy , tmp_bool_dir , & tmp_bool_num ,
536
- & tmp_bool_names , & tmp_bool_values );
532
+ ret = sel_make_bools (newpolicy , tmp_bool_dir , & bool_num ,
533
+ & bool_names , & bool_values );
537
534
if (ret )
538
535
goto out ;
539
536
@@ -542,38 +539,30 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
542
539
if (ret )
543
540
goto out ;
544
541
542
+ lock_rename (tmp_parent , fsi -> sb -> s_root );
543
+
545
544
/* booleans */
546
- old_dentry = fsi -> bool_dir ;
547
- lock_rename (tmp_bool_dir , old_dentry );
548
545
d_exchange (tmp_bool_dir , fsi -> bool_dir );
549
546
550
- old_bool_num = fsi -> bool_num ;
551
- old_bool_names = fsi -> bool_pending_names ;
552
- old_bool_values = fsi -> bool_pending_values ;
553
-
554
- fsi -> bool_num = tmp_bool_num ;
555
- fsi -> bool_pending_names = tmp_bool_names ;
556
- fsi -> bool_pending_values = tmp_bool_values ;
557
-
558
- sel_remove_old_bool_data (old_bool_num , old_bool_names , old_bool_values );
547
+ swap (fsi -> bool_num , bool_num );
548
+ swap (fsi -> bool_pending_names , bool_names );
549
+ swap (fsi -> bool_pending_values , bool_values );
559
550
560
551
fsi -> bool_dir = tmp_bool_dir ;
561
- unlock_rename (tmp_bool_dir , old_dentry );
562
552
563
553
/* classes */
564
- old_dentry = fsi -> class_dir ;
565
- lock_rename (tmp_class_dir , old_dentry );
566
554
d_exchange (tmp_class_dir , fsi -> class_dir );
567
555
fsi -> class_dir = tmp_class_dir ;
568
- unlock_rename (tmp_class_dir , old_dentry );
556
+
557
+ unlock_rename (tmp_parent , fsi -> sb -> s_root );
569
558
570
559
out :
560
+ sel_remove_old_bool_data (bool_num , bool_names , bool_values );
571
561
/* Since the other temporary dirs are children of tmp_parent
572
562
* this will handle all the cleanup in the case of a failure before
573
563
* the swapover
574
564
*/
575
- sel_remove_entries (tmp_parent );
576
- dput (tmp_parent ); /* d_genocide() only handles the children */
565
+ simple_recursive_removal (tmp_parent , NULL );
577
566
578
567
return ret ;
579
568
}
@@ -1351,54 +1340,48 @@ static const struct file_operations sel_commit_bools_ops = {
1351
1340
.llseek = generic_file_llseek ,
1352
1341
};
1353
1342
1354
- static void sel_remove_entries (struct dentry * de )
1355
- {
1356
- d_genocide (de );
1357
- shrink_dcache_parent (de );
1358
- }
1359
-
1360
1343
static int sel_make_bools (struct selinux_policy * newpolicy , struct dentry * bool_dir ,
1361
1344
unsigned int * bool_num , char * * * bool_pending_names ,
1362
1345
int * * bool_pending_values )
1363
1346
{
1364
1347
int ret ;
1365
- ssize_t len ;
1366
- struct dentry * dentry = NULL ;
1367
- struct inode * inode = NULL ;
1368
- struct inode_security_struct * isec ;
1369
- char * * names = NULL , * page ;
1348
+ char * * names , * page ;
1370
1349
u32 i , num ;
1371
- int * values = NULL ;
1372
- u32 sid ;
1373
1350
1374
- ret = - ENOMEM ;
1375
1351
page = (char * )get_zeroed_page (GFP_KERNEL );
1376
1352
if (!page )
1377
- goto out ;
1353
+ return - ENOMEM ;
1378
1354
1379
- ret = security_get_bools (newpolicy , & num , & names , & values );
1355
+ ret = security_get_bools (newpolicy , & num , & names , bool_pending_values );
1380
1356
if (ret )
1381
1357
goto out ;
1382
1358
1359
+ * bool_num = num ;
1360
+ * bool_pending_names = names ;
1361
+
1383
1362
for (i = 0 ; i < num ; i ++ ) {
1384
- ret = - ENOMEM ;
1363
+ struct dentry * dentry ;
1364
+ struct inode * inode ;
1365
+ struct inode_security_struct * isec ;
1366
+ ssize_t len ;
1367
+ u32 sid ;
1368
+
1369
+ len = snprintf (page , PAGE_SIZE , "/%s/%s" , BOOL_DIR_NAME , names [i ]);
1370
+ if (len >= PAGE_SIZE ) {
1371
+ ret = - ENAMETOOLONG ;
1372
+ break ;
1373
+ }
1385
1374
dentry = d_alloc_name (bool_dir , names [i ]);
1386
- if (!dentry )
1387
- goto out ;
1375
+ if (!dentry ) {
1376
+ ret = - ENOMEM ;
1377
+ break ;
1378
+ }
1388
1379
1389
- ret = - ENOMEM ;
1390
1380
inode = sel_make_inode (bool_dir -> d_sb , S_IFREG | S_IRUGO | S_IWUSR );
1391
1381
if (!inode ) {
1392
1382
dput (dentry );
1393
- goto out ;
1394
- }
1395
-
1396
- ret = - ENAMETOOLONG ;
1397
- len = snprintf (page , PAGE_SIZE , "/%s/%s" , BOOL_DIR_NAME , names [i ]);
1398
- if (len >= PAGE_SIZE ) {
1399
- dput (dentry );
1400
- iput (inode );
1401
- goto out ;
1383
+ ret = - ENOMEM ;
1384
+ break ;
1402
1385
}
1403
1386
1404
1387
isec = selinux_inode (inode );
@@ -1416,23 +1399,8 @@ static int sel_make_bools(struct selinux_policy *newpolicy, struct dentry *bool_
1416
1399
inode -> i_ino = i |SEL_BOOL_INO_OFFSET ;
1417
1400
d_add (dentry , inode );
1418
1401
}
1419
- * bool_num = num ;
1420
- * bool_pending_names = names ;
1421
- * bool_pending_values = values ;
1422
-
1423
- free_page ((unsigned long )page );
1424
- return 0 ;
1425
1402
out :
1426
1403
free_page ((unsigned long )page );
1427
-
1428
- if (names ) {
1429
- for (i = 0 ; i < num ; i ++ )
1430
- kfree (names [i ]);
1431
- kfree (names );
1432
- }
1433
- kfree (values );
1434
- sel_remove_entries (bool_dir );
1435
-
1436
1404
return ret ;
1437
1405
}
1438
1406
@@ -1961,20 +1929,40 @@ static struct dentry *sel_make_dir(struct dentry *dir, const char *name,
1961
1929
return dentry ;
1962
1930
}
1963
1931
1964
- static struct dentry * sel_make_disconnected_dir (struct super_block * sb ,
1932
+ static int reject_all (struct mnt_idmap * idmap , struct inode * inode , int mask )
1933
+ {
1934
+ return - EPERM ; // no access for anyone, root or no root.
1935
+ }
1936
+
1937
+ static const struct inode_operations swapover_dir_inode_operations = {
1938
+ .lookup = simple_lookup ,
1939
+ .permission = reject_all ,
1940
+ };
1941
+
1942
+ static struct dentry * sel_make_swapover_dir (struct super_block * sb ,
1965
1943
unsigned long * ino )
1966
1944
{
1967
- struct inode * inode = sel_make_inode (sb , S_IFDIR | S_IRUGO | S_IXUGO );
1945
+ struct dentry * dentry = d_alloc_name (sb -> s_root , ".swapover" );
1946
+ struct inode * inode ;
1968
1947
1969
- if (!inode )
1948
+ if (!dentry )
1970
1949
return ERR_PTR (- ENOMEM );
1971
1950
1972
- inode -> i_op = & simple_dir_inode_operations ;
1973
- inode -> i_fop = & simple_dir_operations ;
1951
+ inode = sel_make_inode (sb , S_IFDIR );
1952
+ if (!inode ) {
1953
+ dput (dentry );
1954
+ return ERR_PTR (- ENOMEM );
1955
+ }
1956
+
1957
+ inode -> i_op = & swapover_dir_inode_operations ;
1974
1958
inode -> i_ino = ++ (* ino );
1975
1959
/* directory inodes start off with i_nlink == 2 (for "." entry) */
1976
1960
inc_nlink (inode );
1977
- return d_obtain_alias (inode );
1961
+ inode_lock (sb -> s_root -> d_inode );
1962
+ d_add (dentry , inode );
1963
+ inc_nlink (sb -> s_root -> d_inode );
1964
+ inode_unlock (sb -> s_root -> d_inode );
1965
+ return dentry ;
1978
1966
}
1979
1967
1980
1968
#define NULL_FILE_NAME "null"
0 commit comments