@@ -145,6 +145,7 @@ open_by_handle_at (int mount_fd, struct file_handle *handle, int flags)
145
145
#define PRIVILEGED_OPAQUE_XATTR "trusted.overlay.opaque"
146
146
#define PRIVILEGED_ORIGIN_XATTR "trusted.overlay.origin"
147
147
#define OPAQUE_WHITEOUT ".wh..wh..opq"
148
+ #define WHITEOUT_MAX_LEN (sizeof (".wh.")-1)
148
149
149
150
#if !defined FICLONE && defined __linux__
150
151
# define FICLONE _IOW (0x94, 9, int)
@@ -1365,7 +1366,7 @@ make_ovl_node (struct ovl_data *lo, const char *path, struct ovl_layer *layer, c
1365
1366
int r ;
1366
1367
1367
1368
r = it -> ds -> file_exists (it , whiteout_path );
1368
- if (r < 0 && errno != ENOENT && errno != ENOTDIR )
1369
+ if (r < 0 && errno != ENOENT && errno != ENOTDIR && errno != ENAMETOOLONG )
1369
1370
return NULL ;
1370
1371
1371
1372
if (r == 0 )
@@ -1546,7 +1547,7 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
1546
1547
stop_lookup = true;
1547
1548
1548
1549
ret = it -> ds -> file_exists (it , parent_whiteout_path );
1549
- if (ret < 0 && errno != ENOENT && errno != ENOTDIR )
1550
+ if (ret < 0 && errno != ENOENT && errno != ENOTDIR && errno != ENAMETOOLONG )
1550
1551
return NULL ;
1551
1552
1552
1553
if (ret == 0 )
@@ -1600,7 +1601,7 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
1600
1601
strconcat3 (node_path , PATH_MAX , n -> path , "/" , dent -> d_name );
1601
1602
1602
1603
ret = it -> ds -> file_exists (it , whiteout_path );
1603
- if (ret < 0 && errno != ENOENT && errno != ENOTDIR )
1604
+ if (ret < 0 && errno != ENOENT && errno != ENOTDIR && errno != ENAMETOOLONG )
1604
1605
{
1605
1606
it -> ds -> closedir (dp );
1606
1607
return NULL ;
@@ -1908,7 +1909,7 @@ do_lookup_file (struct ovl_data *lo, fuse_ino_t parent, const char *name)
1908
1909
strconcat3 (whpath , PATH_MAX , pnode -> path , "/.wh." , name );
1909
1910
1910
1911
ret = it -> ds -> file_exists (it , whpath );
1911
- if (ret < 0 && errno != ENOENT && errno != ENOTDIR )
1912
+ if (ret < 0 && errno != ENOENT && errno != ENOTDIR && errno != ENAMETOOLONG )
1912
1913
return NULL ;
1913
1914
if (ret == 0 )
1914
1915
{
@@ -1937,7 +1938,7 @@ do_lookup_file (struct ovl_data *lo, fuse_ino_t parent, const char *name)
1937
1938
1938
1939
strconcat3 (whpath , PATH_MAX , pnode -> path , "/.wh." , name );
1939
1940
ret = it -> ds -> file_exists (it , whpath );
1940
- if (ret < 0 && errno != ENOENT && errno != ENOTDIR )
1941
+ if (ret < 0 && errno != ENOENT && errno != ENOTDIR && errno != ENAMETOOLONG )
1941
1942
return NULL ;
1942
1943
if (ret == 0 )
1943
1944
node = make_whiteout_node (path , name );
@@ -3582,6 +3583,43 @@ do_getattr (fuse_req_t req, struct fuse_entry_param *e, struct ovl_node *node, i
3582
3583
return 0 ;
3583
3584
}
3584
3585
3586
+ static int
3587
+ do_statfs (struct ovl_data * lo , struct statvfs * sfs )
3588
+ {
3589
+ int ret , fd ;
3590
+
3591
+ fd = get_first_layer (lo )-> fd ;
3592
+
3593
+ if (fd >= 0 )
3594
+ ret = fstatvfs (fd , sfs );
3595
+ else
3596
+ ret = statvfs (lo -> mountpoint , sfs );
3597
+ if (ret < 0 )
3598
+ return ret ;
3599
+
3600
+ sfs -> f_namemax -= WHITEOUT_MAX_LEN ;
3601
+ return 0 ;
3602
+ }
3603
+
3604
+ static short
3605
+ get_fs_namemax (struct ovl_data * lo )
3606
+ {
3607
+ static short namemax = 0 ;
3608
+ if (namemax == 0 )
3609
+ {
3610
+ struct statvfs sfs ;
3611
+ int ret ;
3612
+
3613
+ ret = do_statfs (lo , & sfs );
3614
+ /* On errors use a sane default. */
3615
+ if (ret < 0 )
3616
+ namemax = 255 - WHITEOUT_MAX_LEN ;
3617
+ else
3618
+ namemax = sfs .f_namemax ;
3619
+ }
3620
+ return namemax ;
3621
+ }
3622
+
3585
3623
static void
3586
3624
ovl_create (fuse_req_t req , fuse_ino_t parent , const char * name ,
3587
3625
mode_t mode , struct fuse_file_info * fi )
@@ -3590,12 +3628,19 @@ ovl_create (fuse_req_t req, fuse_ino_t parent, const char *name,
3590
3628
cleanup_close int fd = -1 ;
3591
3629
struct fuse_entry_param e ;
3592
3630
struct ovl_node * node = NULL ;
3631
+ struct ovl_data * lo = ovl_data (req );
3593
3632
struct stat st ;
3594
3633
3595
3634
if (UNLIKELY (ovl_debug (req )))
3596
3635
fprintf (stderr , "ovl_create(parent=%" PRIu64 ", name=%s)\n" ,
3597
3636
parent , name );
3598
3637
3638
+ if (strlen (name ) > get_fs_namemax (lo ))
3639
+ {
3640
+ fuse_reply_err (req , ENAMETOOLONG );
3641
+ return ;
3642
+ }
3643
+
3599
3644
fi -> flags = fi -> flags | O_CREAT ;
3600
3645
3601
3646
fd = ovl_do_open (req , parent , name , fi -> flags , mode , & node , & st );
@@ -3868,6 +3913,12 @@ ovl_link (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent, const char *newn
3868
3913
if (UNLIKELY (ovl_debug (req )))
3869
3914
fprintf (stderr , "ovl_link(ino=%" PRIu64 "s, newparent=%" PRIu64 "s, newname=%s)\n" , ino , newparent , newname );
3870
3915
3916
+ if (strlen (newname ) > get_fs_namemax (lo ))
3917
+ {
3918
+ fuse_reply_err (req , ENAMETOOLONG );
3919
+ return ;
3920
+ }
3921
+
3871
3922
node = do_lookup_file (lo , ino , NULL );
3872
3923
if (node == NULL || node -> whiteout )
3873
3924
{
@@ -4007,6 +4058,12 @@ ovl_symlink (fuse_req_t req, const char *link, fuse_ino_t parent, const char *na
4007
4058
if (UNLIKELY (ovl_debug (req )))
4008
4059
fprintf (stderr , "ovl_symlink(link=%s, ino=%" PRIu64 "s, name=%s)\n" , link , parent , name );
4009
4060
4061
+ if (strlen (name ) > get_fs_namemax (lo ))
4062
+ {
4063
+ fuse_reply_err (req , ENAMETOOLONG );
4064
+ return ;
4065
+ }
4066
+
4010
4067
pnode = do_lookup_file (lo , parent , NULL );
4011
4068
if (pnode == NULL || pnode -> whiteout )
4012
4069
{
@@ -4410,9 +4467,17 @@ ovl_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
4410
4467
unsigned int flags )
4411
4468
{
4412
4469
cleanup_lock int l = enter_big_lock ();
4470
+ struct ovl_data * lo = ovl_data (req );
4471
+
4413
4472
if (UNLIKELY (ovl_debug (req )))
4414
4473
fprintf (stderr , "ovl_rename(ino=%" PRIu64 "s, name=%s , ino=%" PRIu64 "s, name=%s)\n" , parent , name , newparent , newname );
4415
4474
4475
+ if (strlen (newname ) > get_fs_namemax (lo ))
4476
+ {
4477
+ fuse_reply_err (req , ENAMETOOLONG );
4478
+ return ;
4479
+ }
4480
+
4416
4481
if (flags & RENAME_EXCHANGE )
4417
4482
ovl_rename_exchange (req , parent , name , newparent , newname , flags );
4418
4483
else
@@ -4422,24 +4487,17 @@ ovl_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
4422
4487
static void
4423
4488
ovl_statfs (fuse_req_t req , fuse_ino_t ino )
4424
4489
{
4425
- int ret , fd ;
4490
+ int ret ;
4426
4491
struct statvfs sfs ;
4427
4492
struct ovl_data * lo = ovl_data (req );
4428
4493
4429
- if (UNLIKELY (ovl_debug (req )))
4430
- fprintf (stderr , "ovl_statfs(ino=%" PRIu64 "s)\n" , ino );
4431
-
4432
- fd = get_first_layer (lo )-> fd ;
4433
-
4434
- if (fd >= 0 )
4435
- ret = fstatvfs (fd , & sfs );
4436
- else
4437
- ret = statvfs (lo -> mountpoint , & sfs );
4494
+ ret = do_statfs (lo , & sfs );
4438
4495
if (ret < 0 )
4439
4496
{
4440
4497
fuse_reply_err (req , errno );
4441
4498
return ;
4442
4499
}
4500
+
4443
4501
fuse_reply_statfs (req , & sfs );
4444
4502
}
4445
4503
@@ -4551,6 +4609,12 @@ ovl_mknod (fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode, dev
4551
4609
fprintf (stderr , "ovl_mknod(ino=%" PRIu64 ", name=%s, mode=%d, rdev=%lu)\n" ,
4552
4610
parent , name , mode , rdev );
4553
4611
4612
+ if (strlen (name ) > get_fs_namemax (lo ))
4613
+ {
4614
+ fuse_reply_err (req , ENAMETOOLONG );
4615
+ return ;
4616
+ }
4617
+
4554
4618
mode = mode & ~ctx -> umask ;
4555
4619
4556
4620
node = do_lookup_file (lo , parent , name );
@@ -4661,6 +4725,13 @@ ovl_mkdir (fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode)
4661
4725
fprintf (stderr , "ovl_mkdir(ino=%" PRIu64 ", name=%s, mode=%d)\n" ,
4662
4726
parent , name , mode );
4663
4727
4728
+
4729
+ if (strlen (name ) > get_fs_namemax (lo ))
4730
+ {
4731
+ fuse_reply_err (req , ENAMETOOLONG );
4732
+ return ;
4733
+ }
4734
+
4664
4735
node = do_lookup_file (lo , parent , name );
4665
4736
if (node != NULL && !node -> whiteout )
4666
4737
{
0 commit comments