@@ -1199,14 +1199,34 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
11991199 return PTR_ERR (ctx .result ) == - EAGAIN ? 0 : PTR_ERR (ctx .result );
12001200}
12011201
1202+ /*
1203+ * Lock keyring for link.
1204+ */
1205+ int __key_link_lock (struct key * keyring ,
1206+ const struct keyring_index_key * index_key )
1207+ __acquires (& keyring - > sem )
1208+ __acquires (& keyring_serialise_link_lock )
1209+ {
1210+ if (keyring -> type != & key_type_keyring )
1211+ return - ENOTDIR ;
1212+
1213+ down_write (& keyring -> sem );
1214+
1215+ /* Serialise link/link calls to prevent parallel calls causing a cycle
1216+ * when linking two keyring in opposite orders.
1217+ */
1218+ if (index_key -> type == & key_type_keyring )
1219+ mutex_lock (& keyring_serialise_link_lock );
1220+
1221+ return 0 ;
1222+ }
1223+
12021224/*
12031225 * Preallocate memory so that a key can be linked into to a keyring.
12041226 */
12051227int __key_link_begin (struct key * keyring ,
12061228 const struct keyring_index_key * index_key ,
12071229 struct assoc_array_edit * * _edit )
1208- __acquires (& keyring - > sem )
1209- __acquires (& keyring_serialise_link_lock )
12101230{
12111231 struct assoc_array_edit * edit ;
12121232 int ret ;
@@ -1215,20 +1235,13 @@ int __key_link_begin(struct key *keyring,
12151235 keyring -> serial , index_key -> type -> name , index_key -> description );
12161236
12171237 BUG_ON (index_key -> desc_len == 0 );
1238+ BUG_ON (* _edit != NULL );
12181239
1219- if (keyring -> type != & key_type_keyring )
1220- return - ENOTDIR ;
1221-
1222- down_write (& keyring -> sem );
1240+ * _edit = NULL ;
12231241
12241242 ret = - EKEYREVOKED ;
12251243 if (test_bit (KEY_FLAG_REVOKED , & keyring -> flags ))
1226- goto error_krsem ;
1227-
1228- /* serialise link/link calls to prevent parallel calls causing a cycle
1229- * when linking two keyring in opposite orders */
1230- if (index_key -> type == & key_type_keyring )
1231- mutex_lock (& keyring_serialise_link_lock );
1244+ goto error ;
12321245
12331246 /* Create an edit script that will insert/replace the key in the
12341247 * keyring tree.
@@ -1239,7 +1252,7 @@ int __key_link_begin(struct key *keyring,
12391252 NULL );
12401253 if (IS_ERR (edit )) {
12411254 ret = PTR_ERR (edit );
1242- goto error_sem ;
1255+ goto error ;
12431256 }
12441257
12451258 /* If we're not replacing a link in-place then we're going to need some
@@ -1258,11 +1271,7 @@ int __key_link_begin(struct key *keyring,
12581271
12591272error_cancel :
12601273 assoc_array_cancel_edit (edit );
1261- error_sem :
1262- if (index_key -> type == & key_type_keyring )
1263- mutex_unlock (& keyring_serialise_link_lock );
1264- error_krsem :
1265- up_write (& keyring -> sem );
1274+ error :
12661275 kleave (" = %d" , ret );
12671276 return ret ;
12681277}
@@ -1312,9 +1321,6 @@ void __key_link_end(struct key *keyring,
13121321 BUG_ON (index_key -> type == NULL );
13131322 kenter ("%d,%s," , keyring -> serial , index_key -> type -> name );
13141323
1315- if (index_key -> type == & key_type_keyring )
1316- mutex_unlock (& keyring_serialise_link_lock );
1317-
13181324 if (edit ) {
13191325 if (!edit -> dead_leaf ) {
13201326 key_payload_reserve (keyring ,
@@ -1323,6 +1329,9 @@ void __key_link_end(struct key *keyring,
13231329 assoc_array_cancel_edit (edit );
13241330 }
13251331 up_write (& keyring -> sem );
1332+
1333+ if (index_key -> type == & key_type_keyring )
1334+ mutex_unlock (& keyring_serialise_link_lock );
13261335}
13271336
13281337/*
@@ -1358,25 +1367,32 @@ static int __key_link_check_restriction(struct key *keyring, struct key *key)
13581367 */
13591368int key_link (struct key * keyring , struct key * key )
13601369{
1361- struct assoc_array_edit * edit ;
1370+ struct assoc_array_edit * edit = NULL ;
13621371 int ret ;
13631372
13641373 kenter ("{%d,%d}" , keyring -> serial , refcount_read (& keyring -> usage ));
13651374
13661375 key_check (keyring );
13671376 key_check (key );
13681377
1378+ ret = __key_link_lock (keyring , & key -> index_key );
1379+ if (ret < 0 )
1380+ goto error ;
1381+
13691382 ret = __key_link_begin (keyring , & key -> index_key , & edit );
1370- if (ret == 0 ) {
1371- kdebug ( "begun {%d,%d}" , keyring -> serial , refcount_read ( & keyring -> usage )) ;
1372- ret = __key_link_check_restriction ( keyring , key );
1373- if ( ret == 0 )
1374- ret = __key_link_check_live_key (keyring , key );
1375- if (ret == 0 )
1376- __key_link ( key , & edit );
1377- __key_link_end ( keyring , & key -> index_key , edit );
1378- }
1383+ if (ret < 0 )
1384+ goto error_end ;
1385+
1386+ kdebug ( "begun {%d,%d}" , keyring -> serial , refcount_read ( & keyring -> usage ));
1387+ ret = __key_link_check_restriction (keyring , key );
1388+ if (ret == 0 )
1389+ ret = __key_link_check_live_key ( keyring , key );
1390+ if ( ret == 0 )
1391+ __key_link ( key , & edit );
13791392
1393+ error_end :
1394+ __key_link_end (keyring , & key -> index_key , edit );
1395+ error :
13801396 kleave (" = %d {%d,%d}" , ret , keyring -> serial , refcount_read (& keyring -> usage ));
13811397 return ret ;
13821398}
0 commit comments