Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa445f97 authored by Eric Biggers's avatar Eric Biggers Committed by Greg Kroah-Hartman
Browse files

ANDROID: fscrypt: prevent fscrypt_operations from affecting KMI



'struct fscrypt_operations' is only used by fs/crypto/ (which is always
built-in) and by three filesystems (which are either built-in to GKI, in
the case of ext4 and f2fs, or aren't supported by Android, in the case
of ubifs).  The only way a loadable module could use fscrypt_operations
is if the module were a filesystem that used fs/crypto/, which isn't
possible since KMI symbol list doesn't include anything in fs/crypto/.

However, any change to struct fscrypt_operations changes the symbol CRC
of most of the KMI functions exported by any files fs/*.c that include
<linux/fscrypt.h>.  This is because the definition of fscrypt_operations
is visible to them, and in principle it's possible to get to
fscrypt_operations from most VFS structs (e.g. inode->i_sb->s_cop), even
though there's no reason to do so outside the crypto code.

Work around this by putting the definition of struct fscrypt_operations
behind #ifdef FSCRYPT_NEED_OPS, and only defining this in the files that
actually need the definition.  (It could be moved into a separate header
instead, but this way keeps the diff from upstream smaller.)

This will cause a one-time CRC change of all the affected KMI functions,
but afterwards any changes to fscrypt_operations won't "break the KMI".

Bug: 170265596
Test: re-generated the ABI, changed struct fscrypt_operations (and
      struct fscrypt_info as well, just in case), re-generated the ABI
      again, and verified it didn't change.
Change-Id: Ib5dd49550aec81a64b3d6077a0aeb5747be908ff
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent d2a52d0e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#ifndef _FSCRYPT_PRIVATE_H
#define _FSCRYPT_PRIVATE_H

#define FSCRYPT_NEED_OPS
#include <linux/fscrypt.h>
#include <linux/siphash.h>
#include <crypto/hash.h>
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include <linux/compat.h>
#endif

#define FSCRYPT_NEED_OPS
#include <linux/fscrypt.h>
#include <linux/fsverity.h>

+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/quotaops.h>
#include <crypto/hash.h>

#define FSCRYPT_NEED_OPS
#include <linux/fscrypt.h>
#include <linux/fsverity.h>

+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <crypto/hash.h>
#include <crypto/algapi.h>

#define FSCRYPT_NEED_OPS
#include <linux/fscrypt.h>

#include "ubifs-media.h"
+6 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ struct fscrypt_name {
 */
#define FS_CFLG_OWN_PAGES (1U << 1)

#ifdef FSCRYPT_NEED_OPS
/*
 * crypto operations for filesystems
 */
@@ -74,6 +75,7 @@ struct fscrypt_operations {
	void (*get_devices)(struct super_block *sb,
			    struct request_queue **devs);
};
#endif

static inline bool fscrypt_has_encryption_key(const struct inode *inode)
{
@@ -97,6 +99,7 @@ static inline bool fscrypt_needs_contents_encryption(const struct inode *inode)
	return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
}

#ifdef FSCRYPT_NEED_OPS
static inline const union fscrypt_context *
fscrypt_get_dummy_context(struct super_block *sb)
{
@@ -104,6 +107,7 @@ fscrypt_get_dummy_context(struct super_block *sb)
		return NULL;
	return sb->s_cop->get_dummy_context(sb);
}
#endif

/*
 * When d_splice_alias() moves a directory's encrypted alias to its decrypted
@@ -801,6 +805,7 @@ static inline int fscrypt_prepare_setattr(struct dentry *dentry,
 * -ENOKEY if the encryption key is missing, or another -errno code if a problem
 * occurred while setting up the encryption key.
 */
#ifdef FSCRYPT_NEED_OPS
static inline int fscrypt_prepare_symlink(struct inode *dir,
					  const char *target,
					  unsigned int len,
@@ -816,6 +821,7 @@ static inline int fscrypt_prepare_symlink(struct inode *dir,
		return -ENAMETOOLONG;
	return 0;
}
#endif

/**
 * fscrypt_encrypt_symlink() - encrypt the symlink target if needed