Skip to content

Commit 81c64b0

Browse files
committed
Merge tag 'ovl-fixes-5.5-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs fixes from Miklos Szeredi: "Fix some bugs and documentation" * tag 'ovl-fixes-5.5-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: docs: filesystems: overlayfs: Fix restview warnings docs: filesystems: overlayfs: Rename overlayfs.txt to .rst ovl: relax WARN_ON() on rename to self ovl: fix corner case of non-unique st_dev;st_ino ovl: don't use a temp buf for encoding real fh ovl: make sure that real fid is 32bit aligned in memory ovl: fix lookup failure on multi lower squashfs
2 parents e31736d + 35c6cb4 commit 81c64b0

File tree

10 files changed

+166
-101
lines changed

10 files changed

+166
-101
lines changed

Documentation/filesystems/overlayfs.txt renamed to Documentation/filesystems/overlayfs.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
13
Written by: Neil Brown
24
Please see MAINTAINERS file for where to send questions.
35

@@ -181,7 +183,7 @@ Kernel config options:
181183
worried about backward compatibility with kernels that have the redirect_dir
182184
feature and follow redirects even if turned off.
183185

184-
Module options (can also be changed through /sys/module/overlay/parameters/*):
186+
Module options (can also be changed through /sys/module/overlay/parameters/):
185187

186188
- "redirect_dir=BOOL":
187189
See OVERLAY_FS_REDIRECT_DIR kernel config option above.
@@ -263,7 +265,7 @@ top, lower2 the middle and lower3 the bottom layer.
263265

264266

265267
Metadata only copy up
266-
--------------------
268+
---------------------
267269

268270
When metadata only copy up feature is enabled, overlayfs will only copy
269271
up metadata (as opposed to whole file), when a metadata specific operation
@@ -286,10 +288,10 @@ pointed by REDIRECT. This should not be possible on local system as setting
286288
"trusted." xattrs will require CAP_SYS_ADMIN. But it should be possible
287289
for untrusted layers like from a pen drive.
288290

289-
Note: redirect_dir={off|nofollow|follow(*)} conflicts with metacopy=on, and
291+
Note: redirect_dir={off|nofollow|follow[*]} conflicts with metacopy=on, and
290292
results in an error.
291293

292-
(*) redirect_dir=follow only conflicts with metacopy=on if upperdir=... is
294+
[*] redirect_dir=follow only conflicts with metacopy=on if upperdir=... is
293295
given.
294296

295297
Sharing and copying layers

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12394,7 +12394,7 @@ L: [email protected]
1239412394
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git
1239512395
S: Supported
1239612396
F: fs/overlayfs/
12397-
F: Documentation/filesystems/overlayfs.txt
12397+
F: Documentation/filesystems/overlayfs.rst
1239812398

1239912399
P54 WIRELESS DRIVER
1240012400
M: Christian Lamparter <[email protected]>

fs/overlayfs/copy_up.c

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -227,13 +227,17 @@ int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat)
227227
struct ovl_fh *ovl_encode_real_fh(struct dentry *real, bool is_upper)
228228
{
229229
struct ovl_fh *fh;
230-
int fh_type, fh_len, dwords;
231-
void *buf;
230+
int fh_type, dwords;
232231
int buflen = MAX_HANDLE_SZ;
233232
uuid_t *uuid = &real->d_sb->s_uuid;
233+
int err;
234234

235-
buf = kmalloc(buflen, GFP_KERNEL);
236-
if (!buf)
235+
/* Make sure the real fid stays 32bit aligned */
236+
BUILD_BUG_ON(OVL_FH_FID_OFFSET % 4);
237+
BUILD_BUG_ON(MAX_HANDLE_SZ + OVL_FH_FID_OFFSET > 255);
238+
239+
fh = kzalloc(buflen + OVL_FH_FID_OFFSET, GFP_KERNEL);
240+
if (!fh)
237241
return ERR_PTR(-ENOMEM);
238242

239243
/*
@@ -242,42 +246,35 @@ struct ovl_fh *ovl_encode_real_fh(struct dentry *real, bool is_upper)
242246
* the price or reconnecting the dentry.
243247
*/
244248
dwords = buflen >> 2;
245-
fh_type = exportfs_encode_fh(real, buf, &dwords, 0);
249+
fh_type = exportfs_encode_fh(real, (void *)fh->fb.fid, &dwords, 0);
246250
buflen = (dwords << 2);
247251

248-
fh = ERR_PTR(-EIO);
252+
err = -EIO;
249253
if (WARN_ON(fh_type < 0) ||
250254
WARN_ON(buflen > MAX_HANDLE_SZ) ||
251255
WARN_ON(fh_type == FILEID_INVALID))
252-
goto out;
256+
goto out_err;
253257

254-
BUILD_BUG_ON(MAX_HANDLE_SZ + offsetof(struct ovl_fh, fid) > 255);
255-
fh_len = offsetof(struct ovl_fh, fid) + buflen;
256-
fh = kmalloc(fh_len, GFP_KERNEL);
257-
if (!fh) {
258-
fh = ERR_PTR(-ENOMEM);
259-
goto out;
260-
}
261-
262-
fh->version = OVL_FH_VERSION;
263-
fh->magic = OVL_FH_MAGIC;
264-
fh->type = fh_type;
265-
fh->flags = OVL_FH_FLAG_CPU_ENDIAN;
258+
fh->fb.version = OVL_FH_VERSION;
259+
fh->fb.magic = OVL_FH_MAGIC;
260+
fh->fb.type = fh_type;
261+
fh->fb.flags = OVL_FH_FLAG_CPU_ENDIAN;
266262
/*
267263
* When we will want to decode an overlay dentry from this handle
268264
* and all layers are on the same fs, if we get a disconncted real
269265
* dentry when we decode fid, the only way to tell if we should assign
270266
* it to upperdentry or to lowerstack is by checking this flag.
271267
*/
272268
if (is_upper)
273-
fh->flags |= OVL_FH_FLAG_PATH_UPPER;
274-
fh->len = fh_len;
275-
fh->uuid = *uuid;
276-
memcpy(fh->fid, buf, buflen);
269+
fh->fb.flags |= OVL_FH_FLAG_PATH_UPPER;
270+
fh->fb.len = sizeof(fh->fb) + buflen;
271+
fh->fb.uuid = *uuid;
277272

278-
out:
279-
kfree(buf);
280273
return fh;
274+
275+
out_err:
276+
kfree(fh);
277+
return ERR_PTR(err);
281278
}
282279

283280
int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
@@ -300,8 +297,8 @@ int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
300297
/*
301298
* Do not fail when upper doesn't support xattrs.
302299
*/
303-
err = ovl_check_setxattr(dentry, upper, OVL_XATTR_ORIGIN, fh,
304-
fh ? fh->len : 0, 0);
300+
err = ovl_check_setxattr(dentry, upper, OVL_XATTR_ORIGIN, fh->buf,
301+
fh ? fh->fb.len : 0, 0);
305302
kfree(fh);
306303

307304
return err;
@@ -317,7 +314,7 @@ static int ovl_set_upper_fh(struct dentry *upper, struct dentry *index)
317314
if (IS_ERR(fh))
318315
return PTR_ERR(fh);
319316

320-
err = ovl_do_setxattr(index, OVL_XATTR_UPPER, fh, fh->len, 0);
317+
err = ovl_do_setxattr(index, OVL_XATTR_UPPER, fh->buf, fh->fb.len, 0);
321318

322319
kfree(fh);
323320
return err;

fs/overlayfs/dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
11701170
if (newdentry == trap)
11711171
goto out_dput;
11721172

1173-
if (WARN_ON(olddentry->d_inode == newdentry->d_inode))
1173+
if (olddentry->d_inode == newdentry->d_inode)
11741174
goto out_dput;
11751175

11761176
err = 0;

fs/overlayfs/export.c

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,11 @@ static int ovl_check_encode_origin(struct dentry *dentry)
211211
return 1;
212212
}
213213

214-
static int ovl_d_to_fh(struct dentry *dentry, char *buf, int buflen)
214+
static int ovl_dentry_to_fid(struct dentry *dentry, u32 *fid, int buflen)
215215
{
216216
struct ovl_fh *fh = NULL;
217217
int err, enc_lower;
218+
int len;
218219

219220
/*
220221
* Check if we should encode a lower or upper file handle and maybe
@@ -231,43 +232,29 @@ static int ovl_d_to_fh(struct dentry *dentry, char *buf, int buflen)
231232
return PTR_ERR(fh);
232233

233234
err = -EOVERFLOW;
234-
if (fh->len > buflen)
235+
len = OVL_FH_LEN(fh);
236+
if (len > buflen)
235237
goto fail;
236238

237-
memcpy(buf, (char *)fh, fh->len);
238-
err = fh->len;
239+
memcpy(fid, fh, len);
240+
err = len;
239241

240242
out:
241243
kfree(fh);
242244
return err;
243245

244246
fail:
245247
pr_warn_ratelimited("overlayfs: failed to encode file handle (%pd2, err=%i, buflen=%d, len=%d, type=%d)\n",
246-
dentry, err, buflen, fh ? (int)fh->len : 0,
247-
fh ? fh->type : 0);
248+
dentry, err, buflen, fh ? (int)fh->fb.len : 0,
249+
fh ? fh->fb.type : 0);
248250
goto out;
249251
}
250252

251-
static int ovl_dentry_to_fh(struct dentry *dentry, u32 *fid, int *max_len)
252-
{
253-
int res, len = *max_len << 2;
254-
255-
res = ovl_d_to_fh(dentry, (char *)fid, len);
256-
if (res <= 0)
257-
return FILEID_INVALID;
258-
259-
len = res;
260-
261-
/* Round up to dwords */
262-
*max_len = (len + 3) >> 2;
263-
return OVL_FILEID;
264-
}
265-
266253
static int ovl_encode_fh(struct inode *inode, u32 *fid, int *max_len,
267254
struct inode *parent)
268255
{
269256
struct dentry *dentry;
270-
int type;
257+
int bytes = *max_len << 2;
271258

272259
/* TODO: encode connectable file handles */
273260
if (parent)
@@ -277,10 +264,14 @@ static int ovl_encode_fh(struct inode *inode, u32 *fid, int *max_len,
277264
if (WARN_ON(!dentry))
278265
return FILEID_INVALID;
279266

280-
type = ovl_dentry_to_fh(dentry, fid, max_len);
281-
267+
bytes = ovl_dentry_to_fid(dentry, fid, bytes);
282268
dput(dentry);
283-
return type;
269+
if (bytes <= 0)
270+
return FILEID_INVALID;
271+
272+
*max_len = bytes >> 2;
273+
274+
return OVL_FILEID_V1;
284275
}
285276

286277
/*
@@ -777,37 +768,64 @@ static struct dentry *ovl_lower_fh_to_d(struct super_block *sb,
777768
goto out;
778769
}
779770

771+
static struct ovl_fh *ovl_fid_to_fh(struct fid *fid, int buflen, int fh_type)
772+
{
773+
struct ovl_fh *fh;
774+
775+
/* If on-wire inner fid is aligned - nothing to do */
776+
if (fh_type == OVL_FILEID_V1)
777+
return (struct ovl_fh *)fid;
778+
779+
if (fh_type != OVL_FILEID_V0)
780+
return ERR_PTR(-EINVAL);
781+
782+
fh = kzalloc(buflen, GFP_KERNEL);
783+
if (!fh)
784+
return ERR_PTR(-ENOMEM);
785+
786+
/* Copy unaligned inner fh into aligned buffer */
787+
memcpy(&fh->fb, fid, buflen - OVL_FH_WIRE_OFFSET);
788+
return fh;
789+
}
790+
780791
static struct dentry *ovl_fh_to_dentry(struct super_block *sb, struct fid *fid,
781792
int fh_len, int fh_type)
782793
{
783794
struct dentry *dentry = NULL;
784-
struct ovl_fh *fh = (struct ovl_fh *) fid;
795+
struct ovl_fh *fh = NULL;
785796
int len = fh_len << 2;
786797
unsigned int flags = 0;
787798
int err;
788799

789-
err = -EINVAL;
790-
if (fh_type != OVL_FILEID)
800+
fh = ovl_fid_to_fh(fid, len, fh_type);
801+
err = PTR_ERR(fh);
802+
if (IS_ERR(fh))
791803
goto out_err;
792804

793805
err = ovl_check_fh_len(fh, len);
794806
if (err)
795807
goto out_err;
796808

797-
flags = fh->flags;
809+
flags = fh->fb.flags;
798810
dentry = (flags & OVL_FH_FLAG_PATH_UPPER) ?
799811
ovl_upper_fh_to_d(sb, fh) :
800812
ovl_lower_fh_to_d(sb, fh);
801813
err = PTR_ERR(dentry);
802814
if (IS_ERR(dentry) && err != -ESTALE)
803815
goto out_err;
804816

817+
out:
818+
/* We may have needed to re-align OVL_FILEID_V0 */
819+
if (!IS_ERR_OR_NULL(fh) && fh != (void *)fid)
820+
kfree(fh);
821+
805822
return dentry;
806823

807824
out_err:
808825
pr_warn_ratelimited("overlayfs: failed to decode file handle (len=%d, type=%d, flags=%x, err=%i)\n",
809-
len, fh_type, flags, err);
810-
return ERR_PTR(err);
826+
fh_len, fh_type, flags, err);
827+
dentry = ERR_PTR(err);
828+
goto out;
811829
}
812830

813831
static struct dentry *ovl_fh_to_parent(struct super_block *sb, struct fid *fid,

fs/overlayfs/inode.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,14 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
200200
if (ovl_test_flag(OVL_INDEX, d_inode(dentry)) ||
201201
(!ovl_verify_lower(dentry->d_sb) &&
202202
(is_dir || lowerstat.nlink == 1))) {
203-
stat->ino = lowerstat.ino;
204203
lower_layer = ovl_layer_lower(dentry);
204+
/*
205+
* Cannot use origin st_dev;st_ino because
206+
* origin inode content may differ from overlay
207+
* inode content.
208+
*/
209+
if (samefs || lower_layer->fsid)
210+
stat->ino = lowerstat.ino;
205211
}
206212

207213
/*

0 commit comments

Comments
 (0)