@@ -4024,6 +4024,7 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
struct path path;
int error;
unsigned int lookup_flags = 0;
+ umode_t mode_stripped;
error = may_mknod(mode);
if (error)
@@ -4034,8 +4035,9 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
if (IS_ERR(dentry))
goto out1;
- error = security_path_mknod(&path, dentry,
- mode_strip_umask(path.dentry->d_inode, mode), dev);
+ mode_stripped = mode_strip_umask(path.dentry->d_inode, mode);
+
+ error = security_path_mknod(&path, dentry, mode_stripped, dev);
if (error)
goto out2;
@@ -4045,7 +4047,8 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
error = vfs_create(idmap, path.dentry->d_inode,
dentry, mode, true);
if (!error)
- ima_post_path_mknod(idmap, dentry);
+ ima_post_path_mknod(idmap, &path, dentry,
+ mode_stripped, dev);
break;
case S_IFCHR: case S_IFBLK:
error = vfs_mknod(idmap, path.dentry->d_inode,
@@ -32,7 +32,8 @@ extern int ima_read_file(struct file *file, enum kernel_read_file_id id,
extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
enum kernel_read_file_id id);
extern void ima_post_path_mknod(struct mnt_idmap *idmap,
- struct dentry *dentry);
+ const struct path *dir, struct dentry *dentry,
+ umode_t mode, unsigned int dev);
extern int ima_file_hash(struct file *file, char *buf, size_t buf_size);
extern int ima_inode_hash(struct inode *inode, char *buf, size_t buf_size);
extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size);
@@ -114,7 +115,9 @@ static inline int ima_post_read_file(struct file *file, void *buf, loff_t size,
}
static inline void ima_post_path_mknod(struct mnt_idmap *idmap,
- struct dentry *dentry)
+ const struct path *dir,
+ struct dentry *dentry,
+ umode_t mode, unsigned int dev)
{
return;
}
@@ -696,18 +696,26 @@ void ima_post_create_tmpfile(struct mnt_idmap *idmap,
/**
* ima_post_path_mknod - mark as a new inode
* @idmap: idmap of the mount the inode was found from
+ * @dir: path structure of parent of the new file
* @dentry: newly created dentry
+ * @mode: mode of the new file
+ * @dev: undecoded device number
*
* Mark files created via the mknodat syscall as new, so that the
* file data can be written later.
*/
void ima_post_path_mknod(struct mnt_idmap *idmap,
- struct dentry *dentry)
+ const struct path *dir, struct dentry *dentry,
+ umode_t mode, unsigned int dev)
{
struct integrity_iint_cache *iint;
struct inode *inode = dentry->d_inode;
int must_appraise;
+ /* See do_mknodat(), IMA is executed for case 0: and case S_IFREG: */
+ if ((mode & S_IFMT) != 0 && (mode & S_IFMT) != S_IFREG)
+ return;
+
if (!ima_policy_flag || !S_ISREG(inode->i_mode))
return;