Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Arch Linux
Packaging
Upstream
linux-rt
Commits
ca7f85be
Commit
ca7f85be
authored
Oct 08, 2016
by
Richard Weinberger
Browse files
ubifs: Add support for encrypted symlinks
Signed-off-by:
Richard Weinberger
<
richard@nod.at
>
parent
f4f61d2c
Changes
3
Hide whitespace changes
Inline
Side-by-side
fs/ubifs/dir.c
View file @
ca7f85be
...
...
@@ -629,7 +629,7 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
fstr
.
len
=
fstr_real_len
;
err
=
fscrypt_fname_disk_to_usr
(
dir
,
key_hash_flash
(
c
,
&
dent
->
key
),
0
,
&
nm
.
disk_name
,
&
fstr
);
if
(
err
<
0
)
if
(
err
)
goto
out
;
}
else
{
fstr
.
len
=
fname_len
(
&
nm
);
...
...
@@ -1164,10 +1164,27 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
struct
ubifs_inode
*
dir_ui
=
ubifs_inode
(
dir
);
struct
ubifs_info
*
c
=
dir
->
i_sb
->
s_fs_info
;
int
err
,
len
=
strlen
(
symname
);
int
sz_change
=
CALC_DENT_SIZE
(
dentry
->
d_name
.
len
);
int
sz_change
=
CALC_DENT_SIZE
(
len
);
struct
fscrypt_str
disk_link
=
FSTR_INIT
((
char
*
)
symname
,
len
+
1
);
struct
fscrypt_symlink_data
*
sd
=
NULL
;
struct
ubifs_budget_req
req
=
{
.
new_ino
=
1
,
.
new_dent
=
1
,
.
new_ino_d
=
ALIGN
(
len
,
8
),
.
dirtied_ino
=
1
};
struct
fscrypt_name
nm
;
if
(
ubifs_crypt_is_encrypted
(
dir
))
{
err
=
fscrypt_get_encryption_info
(
dir
);
if
(
err
)
goto
out_budg
;
if
(
!
fscrypt_has_encryption_key
(
dir
))
{
err
=
-
EPERM
;
goto
out_budg
;
}
disk_link
.
len
=
(
fscrypt_fname_encrypted_size
(
dir
,
len
)
+
sizeof
(
struct
fscrypt_symlink_data
));
}
/*
* Budget request settings: new inode, new direntry and changing parent
...
...
@@ -1177,36 +1194,77 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
dbg_gen
(
"dent '%pd', target '%s' in dir ino %lu"
,
dentry
,
symname
,
dir
->
i_ino
);
if
(
len
>
UBIFS_MAX_INO_DATA
)
if
(
disk_link
.
len
>
UBIFS_MAX_INO_DATA
)
return
-
ENAMETOOLONG
;
err
=
ubifs_budget_space
(
c
,
&
req
);
if
(
err
)
return
err
;
err
=
fscrypt_setup_filename
(
dir
,
&
dentry
->
d_name
,
0
,
&
nm
);
if
(
err
)
goto
out_budg
;
inode
=
ubifs_new_inode
(
c
,
dir
,
S_IFLNK
|
S_IRWXUGO
);
if
(
IS_ERR
(
inode
))
{
err
=
PTR_ERR
(
inode
);
goto
out_
budg
;
goto
out_
fname
;
}
ui
=
ubifs_inode
(
inode
);
ui
->
data
=
kmalloc
(
len
+
1
,
GFP_NOFS
);
ui
->
data
=
kmalloc
(
disk_link
.
len
,
GFP_NOFS
);
if
(
!
ui
->
data
)
{
err
=
-
ENOMEM
;
goto
out_inode
;
}
memcpy
(
ui
->
data
,
symname
,
len
);
((
char
*
)
ui
->
data
)[
len
]
=
'\0'
;
inode
->
i_link
=
ui
->
data
;
if
(
ubifs_crypt_is_encrypted
(
dir
))
{
struct
qstr
istr
=
QSTR_INIT
(
symname
,
len
);
struct
fscrypt_str
ostr
;
sd
=
kzalloc
(
disk_link
.
len
,
GFP_NOFS
);
if
(
!
sd
)
{
err
=
-
ENOMEM
;
goto
out_inode
;
}
err
=
fscrypt_get_encryption_info
(
inode
);
if
(
err
)
{
kfree
(
sd
);
goto
out_inode
;
}
if
(
!
fscrypt_has_encryption_key
(
inode
))
{
kfree
(
sd
);
err
=
-
EPERM
;
goto
out_inode
;
}
ostr
.
name
=
sd
->
encrypted_path
;
ostr
.
len
=
disk_link
.
len
;
err
=
fscrypt_fname_usr_to_disk
(
inode
,
&
istr
,
&
ostr
);
if
(
err
)
{
kfree
(
sd
);
goto
out_inode
;
}
sd
->
len
=
cpu_to_le16
(
ostr
.
len
);
disk_link
.
name
=
(
char
*
)
sd
;
}
else
{
inode
->
i_link
=
ui
->
data
;
}
memcpy
(
ui
->
data
,
disk_link
.
name
,
disk_link
.
len
);
((
char
*
)
ui
->
data
)[
disk_link
.
len
-
1
]
=
'\0'
;
/*
* The terminating zero byte is not written to the flash media and it
* is put just to make later in-memory string processing simpler. Thus,
* data length is @len, not @len + %1.
*/
ui
->
data_len
=
len
;
inode
->
i_size
=
ubifs_inode
(
inode
)
->
ui_size
=
len
;
ui
->
data_len
=
disk_link
.
len
-
1
;
inode
->
i_size
=
ubifs_inode
(
inode
)
->
ui_size
=
disk_link
.
len
-
1
;
err
=
ubifs_init_security
(
dir
,
inode
,
&
dentry
->
d_name
);
if
(
err
)
...
...
@@ -1216,7 +1274,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
dir
->
i_size
+=
sz_change
;
dir_ui
->
ui_size
=
dir
->
i_size
;
dir
->
i_mtime
=
dir
->
i_ctime
=
inode
->
i_ctime
;
err
=
ubifs_jnl_update
(
c
,
dir
,
&
dentry
->
d_name
,
inode
,
0
,
0
);
err
=
ubifs_jnl_update
(
c
,
dir
,
&
nm
,
inode
,
0
,
0
);
if
(
err
)
goto
out_cancel
;
mutex_unlock
(
&
dir_ui
->
ui_mutex
);
...
...
@@ -1224,6 +1282,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
ubifs_release_budget
(
c
,
&
req
);
insert_inode_hash
(
inode
);
d_instantiate
(
dentry
,
inode
);
fscrypt_free_filename
(
&
nm
);
return
0
;
out_cancel:
...
...
@@ -1233,6 +1292,8 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
out_inode:
make_bad_inode
(
inode
);
iput
(
inode
);
out_fname:
fscrypt_free_filename
(
&
nm
);
out_budg:
ubifs_release_budget
(
c
,
&
req
);
return
err
;
...
...
fs/ubifs/file.c
View file @
ca7f85be
...
...
@@ -1657,6 +1657,59 @@ static int ubifs_file_open(struct inode *inode, struct file *filp)
return
0
;
}
static
const
char
*
ubifs_get_link
(
struct
dentry
*
dentry
,
struct
inode
*
inode
,
struct
delayed_call
*
done
)
{
int
err
;
struct
fscrypt_symlink_data
*
sd
;
struct
ubifs_inode
*
ui
=
ubifs_inode
(
inode
);
struct
fscrypt_str
cstr
;
struct
fscrypt_str
pstr
;
if
(
!
ubifs_crypt_is_encrypted
(
inode
))
return
ui
->
data
;
if
(
!
dentry
)
return
ERR_PTR
(
-
ECHILD
);
err
=
fscrypt_get_encryption_info
(
inode
);
if
(
err
)
return
ERR_PTR
(
err
);
sd
=
(
struct
fscrypt_symlink_data
*
)
ui
->
data
;
cstr
.
name
=
sd
->
encrypted_path
;
cstr
.
len
=
le16_to_cpu
(
sd
->
len
);
if
(
cstr
.
len
==
0
)
return
ERR_PTR
(
-
ENOENT
);
if
((
cstr
.
len
+
sizeof
(
struct
fscrypt_symlink_data
)
-
1
)
>
ui
->
data_len
)
return
ERR_PTR
(
-
EIO
);
err
=
fscrypt_fname_alloc_buffer
(
inode
,
cstr
.
len
,
&
pstr
);
if
(
err
)
return
ERR_PTR
(
err
);
err
=
fscrypt_fname_disk_to_usr
(
inode
,
0
,
0
,
&
cstr
,
&
pstr
);
if
(
err
)
{
fscrypt_fname_free_buffer
(
&
pstr
);
return
ERR_PTR
(
err
);
}
pstr
.
name
[
pstr
.
len
]
=
'\0'
;
// XXX this probably won't happen anymore...
if
(
pstr
.
name
[
0
]
==
'\0'
)
{
fscrypt_fname_free_buffer
(
&
pstr
);
return
ERR_PTR
(
-
ENOENT
);
}
set_delayed_call
(
done
,
kfree_link
,
pstr
.
name
);
return
pstr
.
name
;
}
const
struct
address_space_operations
ubifs_file_address_operations
=
{
.
readpage
=
ubifs_readpage
,
.
writepage
=
ubifs_writepage
,
...
...
@@ -1681,7 +1734,7 @@ const struct inode_operations ubifs_file_inode_operations = {
const
struct
inode_operations
ubifs_symlink_inode_operations
=
{
.
readlink
=
generic_readlink
,
.
get_link
=
simple
_get_link
,
.
get_link
=
ubifs
_get_link
,
.
setattr
=
ubifs_setattr
,
.
getattr
=
ubifs_getattr
,
.
listxattr
=
ubifs_listxattr
,
...
...
fs/ubifs/super.c
View file @
ca7f85be
...
...
@@ -198,7 +198,6 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum)
}
memcpy
(
ui
->
data
,
ino
->
data
,
ui
->
data_len
);
((
char
*
)
ui
->
data
)[
ui
->
data_len
]
=
'\0'
;
inode
->
i_link
=
ui
->
data
;
break
;
case
S_IFBLK
:
case
S_IFCHR
:
...
...
David Runge
🐿
@dvzrv
mentioned in commit
8a5c56c2
·
Sep 07, 2021
mentioned in commit
8a5c56c2
mentioned in commit 8a5c56c2bdbcc856ab38b494a3ab58cc16d07e9b
Toggle commit list
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment