@@ -629,7 +629,7 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
629
629
fstr .len = fstr_real_len ;
630
630
631
631
err = fscrypt_fname_disk_to_usr (dir , key_hash_flash (c , & dent -> key ), 0 , & nm .disk_name , & fstr );
632
- if (err < 0 )
632
+ if (err )
633
633
goto out ;
634
634
} else {
635
635
fstr .len = fname_len (& nm );
@@ -1164,10 +1164,27 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
1164
1164
struct ubifs_inode * dir_ui = ubifs_inode (dir );
1165
1165
struct ubifs_info * c = dir -> i_sb -> s_fs_info ;
1166
1166
int err , len = strlen (symname );
1167
- int sz_change = CALC_DENT_SIZE (dentry -> d_name .len );
1167
+ int sz_change = CALC_DENT_SIZE (len );
1168
+ struct fscrypt_str disk_link = FSTR_INIT ((char * )symname , len + 1 );
1169
+ struct fscrypt_symlink_data * sd = NULL ;
1168
1170
struct ubifs_budget_req req = { .new_ino = 1 , .new_dent = 1 ,
1169
1171
.new_ino_d = ALIGN (len , 8 ),
1170
1172
.dirtied_ino = 1 };
1173
+ struct fscrypt_name nm ;
1174
+
1175
+ if (ubifs_crypt_is_encrypted (dir )) {
1176
+ err = fscrypt_get_encryption_info (dir );
1177
+ if (err )
1178
+ goto out_budg ;
1179
+
1180
+ if (!fscrypt_has_encryption_key (dir )) {
1181
+ err = - EPERM ;
1182
+ goto out_budg ;
1183
+ }
1184
+
1185
+ disk_link .len = (fscrypt_fname_encrypted_size (dir , len ) +
1186
+ sizeof (struct fscrypt_symlink_data ));
1187
+ }
1171
1188
1172
1189
/*
1173
1190
* Budget request settings: new inode, new direntry and changing parent
@@ -1177,36 +1194,77 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
1177
1194
dbg_gen ("dent '%pd', target '%s' in dir ino %lu" , dentry ,
1178
1195
symname , dir -> i_ino );
1179
1196
1180
- if (len > UBIFS_MAX_INO_DATA )
1197
+ if (disk_link . len > UBIFS_MAX_INO_DATA )
1181
1198
return - ENAMETOOLONG ;
1182
1199
1183
1200
err = ubifs_budget_space (c , & req );
1184
1201
if (err )
1185
1202
return err ;
1186
1203
1204
+ err = fscrypt_setup_filename (dir , & dentry -> d_name , 0 , & nm );
1205
+ if (err )
1206
+ goto out_budg ;
1207
+
1187
1208
inode = ubifs_new_inode (c , dir , S_IFLNK | S_IRWXUGO );
1188
1209
if (IS_ERR (inode )) {
1189
1210
err = PTR_ERR (inode );
1190
- goto out_budg ;
1211
+ goto out_fname ;
1191
1212
}
1192
1213
1193
1214
ui = ubifs_inode (inode );
1194
- ui -> data = kmalloc (len + 1 , GFP_NOFS );
1215
+ ui -> data = kmalloc (disk_link . len , GFP_NOFS );
1195
1216
if (!ui -> data ) {
1196
1217
err = - ENOMEM ;
1197
1218
goto out_inode ;
1198
1219
}
1199
1220
1200
- memcpy (ui -> data , symname , len );
1201
- ((char * )ui -> data )[len ] = '\0' ;
1202
- inode -> i_link = ui -> data ;
1221
+ if (ubifs_crypt_is_encrypted (dir )) {
1222
+ struct qstr istr = QSTR_INIT (symname , len );
1223
+ struct fscrypt_str ostr ;
1224
+
1225
+ sd = kzalloc (disk_link .len , GFP_NOFS );
1226
+ if (!sd ) {
1227
+ err = - ENOMEM ;
1228
+ goto out_inode ;
1229
+ }
1230
+
1231
+ err = fscrypt_get_encryption_info (inode );
1232
+ if (err ) {
1233
+ kfree (sd );
1234
+ goto out_inode ;
1235
+ }
1236
+
1237
+ if (!fscrypt_has_encryption_key (inode )) {
1238
+ kfree (sd );
1239
+ err = - EPERM ;
1240
+ goto out_inode ;
1241
+ }
1242
+
1243
+ ostr .name = sd -> encrypted_path ;
1244
+ ostr .len = disk_link .len ;
1245
+
1246
+ err = fscrypt_fname_usr_to_disk (inode , & istr , & ostr );
1247
+ if (err ) {
1248
+ kfree (sd );
1249
+ goto out_inode ;
1250
+ }
1251
+
1252
+ sd -> len = cpu_to_le16 (ostr .len );
1253
+ disk_link .name = (char * )sd ;
1254
+ } else {
1255
+ inode -> i_link = ui -> data ;
1256
+ }
1257
+
1258
+ memcpy (ui -> data , disk_link .name , disk_link .len );
1259
+ ((char * )ui -> data )[disk_link .len - 1 ] = '\0' ;
1260
+
1203
1261
/*
1204
1262
* The terminating zero byte is not written to the flash media and it
1205
1263
* is put just to make later in-memory string processing simpler. Thus,
1206
1264
* data length is @len, not @len + %1.
1207
1265
*/
1208
- ui -> data_len = len ;
1209
- inode -> i_size = ubifs_inode (inode )-> ui_size = len ;
1266
+ ui -> data_len = disk_link . len - 1 ;
1267
+ inode -> i_size = ubifs_inode (inode )-> ui_size = disk_link . len - 1 ;
1210
1268
1211
1269
err = ubifs_init_security (dir , inode , & dentry -> d_name );
1212
1270
if (err )
@@ -1216,14 +1274,15 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
1216
1274
dir -> i_size += sz_change ;
1217
1275
dir_ui -> ui_size = dir -> i_size ;
1218
1276
dir -> i_mtime = dir -> i_ctime = inode -> i_ctime ;
1219
- err = ubifs_jnl_update (c , dir , & dentry -> d_name , inode , 0 , 0 );
1277
+ err = ubifs_jnl_update (c , dir , & nm , inode , 0 , 0 );
1220
1278
if (err )
1221
1279
goto out_cancel ;
1222
1280
mutex_unlock (& dir_ui -> ui_mutex );
1223
1281
1224
1282
ubifs_release_budget (c , & req );
1225
1283
insert_inode_hash (inode );
1226
1284
d_instantiate (dentry , inode );
1285
+ fscrypt_free_filename (& nm );
1227
1286
return 0 ;
1228
1287
1229
1288
out_cancel :
@@ -1233,6 +1292,8 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
1233
1292
out_inode :
1234
1293
make_bad_inode (inode );
1235
1294
iput (inode );
1295
+ out_fname :
1296
+ fscrypt_free_filename (& nm );
1236
1297
out_budg :
1237
1298
ubifs_release_budget (c , & req );
1238
1299
return err ;
0 commit comments