Skip to content

Commit 5c248a6

Browse files
committed
Support 32-bit compatibility mode on 64-bit kernels.
1 parent 97ec7db commit 5c248a6

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

fs/compat.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <linux/slab.h>
4949
#include <linux/pagemap.h>
5050
#include <linux/aio.h>
51+
#include <linux/gobohide.h>
5152

5253
#include <asm/uaccess.h>
5354
#include <asm/mmu_context.h>
@@ -844,6 +845,7 @@ struct compat_readdir_callback {
844845
struct dir_context ctx;
845846
struct compat_old_linux_dirent __user *dirent;
846847
int result;
848+
struct dentry *dentry;
847849
};
848850

849851
static int compat_fillonedir(struct dir_context *ctx, const char *name,
@@ -893,6 +895,7 @@ COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
893895
if (!f.file)
894896
return -EBADF;
895897

898+
buf.dentry = f.file->f_path.dentry;
896899
error = iterate_dir(f.file, &buf.ctx);
897900
if (buf.result)
898901
error = buf.result;
@@ -914,6 +917,7 @@ struct compat_getdents_callback {
914917
struct compat_linux_dirent __user *previous;
915918
int count;
916919
int error;
920+
struct dentry *dentry;
917921
};
918922

919923
static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
@@ -923,6 +927,7 @@ static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
923927
struct compat_getdents_callback *buf =
924928
container_of(ctx, struct compat_getdents_callback, ctx);
925929
compat_ulong_t d_ino;
930+
struct hide *hidden;
926931
int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) +
927932
namlen + 2, sizeof(compat_long_t));
928933

@@ -936,10 +941,20 @@ static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
936941
}
937942
dirent = buf->previous;
938943
if (dirent) {
944+
hidden = gobohide_get(d_ino, name, namlen, buf->dentry);
945+
if (hidden) {
946+
gobohide_put(hidden);
947+
return 0;
948+
}
939949
if (__put_user(offset, &dirent->d_off))
940950
goto efault;
941951
}
942952
dirent = buf->current_dir;
953+
hidden = gobohide_get(d_ino, name, namlen, buf->dentry);
954+
if (hidden) {
955+
gobohide_put(hidden);
956+
return 0;
957+
}
943958
if (__put_user(d_ino, &dirent->d_ino))
944959
goto efault;
945960
if (__put_user(reclen, &dirent->d_reclen))
@@ -979,6 +994,7 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
979994
if (!f.file)
980995
return -EBADF;
981996

997+
buf.dentry = f.file->f_path.dentry;
982998
error = iterate_dir(f.file, &buf.ctx);
983999
if (error >= 0)
9841000
error = buf.error;
@@ -1001,13 +1017,15 @@ struct compat_getdents_callback64 {
10011017
struct linux_dirent64 __user *previous;
10021018
int count;
10031019
int error;
1020+
struct dentry *dentry;
10041021
};
10051022

10061023
static int compat_filldir64(struct dir_context *ctx, const char *name,
10071024
int namlen, loff_t offset, u64 ino,
10081025
unsigned int d_type)
10091026
{
10101027
struct linux_dirent64 __user *dirent;
1028+
struct hide *hidden;
10111029
struct compat_getdents_callback64 *buf =
10121030
container_of(ctx, struct compat_getdents_callback64, ctx);
10131031
int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1,
@@ -1020,10 +1038,20 @@ static int compat_filldir64(struct dir_context *ctx, const char *name,
10201038
dirent = buf->previous;
10211039

10221040
if (dirent) {
1041+
hidden = gobohide_get(ino, name, namlen, buf->dentry);
1042+
if (hidden) {
1043+
gobohide_put(hidden);
1044+
return 0;
1045+
}
10231046
if (__put_user_unaligned(offset, &dirent->d_off))
10241047
goto efault;
10251048
}
10261049
dirent = buf->current_dir;
1050+
hidden = gobohide_get(ino, name, namlen, buf->dentry);
1051+
if (hidden) {
1052+
gobohide_put(hidden);
1053+
return 0;
1054+
}
10271055
if (__put_user_unaligned(ino, &dirent->d_ino))
10281056
goto efault;
10291057
off = 0;
@@ -1066,6 +1094,7 @@ COMPAT_SYSCALL_DEFINE3(getdents64, unsigned int, fd,
10661094
if (!f.file)
10671095
return -EBADF;
10681096

1097+
buf.dentry = f.file->f_path.dentry;
10691098
error = iterate_dir(f.file, &buf.ctx);
10701099
if (error >= 0)
10711100
error = buf.error;

fs/compat_ioctl.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include <linux/i2c-dev.h>
5858
#include <linux/atalk.h>
5959
#include <linux/gfp.h>
60+
#include <linux/gobohide.h>
6061

6162
#include "internal.h"
6263

@@ -910,6 +911,7 @@ COMPATIBLE_IOCTL(FIONCLEX)
910911
COMPATIBLE_IOCTL(FIOASYNC)
911912
COMPATIBLE_IOCTL(FIONBIO)
912913
COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */
914+
COMPATIBLE_IOCTL(FIGOBOHIDE)
913915
COMPATIBLE_IOCTL(FS_IOC_FIEMAP)
914916
/* 0x00 */
915917
COMPATIBLE_IOCTL(FIBMAP)
@@ -1557,6 +1559,7 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
15571559
case FIONBIO:
15581560
case FIOASYNC:
15591561
case FIOQSIZE:
1562+
case FIGOBOHIDE:
15601563
break;
15611564

15621565
#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)

0 commit comments

Comments
 (0)