summaryrefslogtreecommitdiffstats
path: root/fs/udf/udfdecl.h
diff options
context:
space:
mode:
authorSteve Magnani <steve.magnani@digidescorp.com>2017-10-12 09:48:40 -0400
committerJan Kara <jack@suse.cz>2017-10-17 05:56:45 -0400
commitb490bdd630cc43a5725e76c7c23f8a7e55551145 (patch)
tree9ee95e0af7d247b2a8b282b2b5ed1a783465e9da /fs/udf/udfdecl.h
parent503c3117d05c184b431e403cd05c463ac41370f0 (diff)
udf: Fix 64-bit sign extension issues affecting blocks > 0x7FFFFFFF
Large (> 1 TiB) UDF filesystems appear subject to several problems when mounted on 64-bit systems: * readdir() can fail on a directory containing File Identifiers residing above 0x7FFFFFFF. This manifests as a 'ls' command failing with EIO. * FIBMAP on a file block located above 0x7FFFFFFF can return a negative value. The low 32 bits are correct, but applications that don't mask the high 32 bits of the result can perform incorrectly. Per suggestion by Jan Kara, introduce a udf_pblk_t type for representation of UDF block addresses. Ultimately, all driver functions that manipulate UDF block addresses should use this type; for now, deployment is limited to functions with actual or potential sign extension issues. Changes to udf_readdir() and udf_block_map() address the issues noted above; other changes address potential similar issues uncovered during audit of the driver code. Signed-off-by: Steven J. Magnani <steve@digidescorp.com> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf/udfdecl.h')
-rw-r--r--fs/udf/udfdecl.h21
1 files changed, 13 insertions, 8 deletions
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 63b034984378..8e51704fd75d 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -73,6 +73,8 @@ static inline size_t udf_ext0_offset(struct inode *inode)
73/* computes tag checksum */ 73/* computes tag checksum */
74u8 udf_tag_checksum(const struct tag *t); 74u8 udf_tag_checksum(const struct tag *t);
75 75
76typedef uint32_t udf_pblk_t;
77
76struct dentry; 78struct dentry;
77struct inode; 79struct inode;
78struct task_struct; 80struct task_struct;
@@ -144,15 +146,17 @@ static inline struct inode *udf_iget(struct super_block *sb,
144 return __udf_iget(sb, ino, false); 146 return __udf_iget(sb, ino, false);
145} 147}
146extern int udf_expand_file_adinicb(struct inode *); 148extern int udf_expand_file_adinicb(struct inode *);
147extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *); 149extern struct buffer_head *udf_expand_dir_adinicb(struct inode *inode,
148extern struct buffer_head *udf_bread(struct inode *, int, int, int *); 150 udf_pblk_t *block, int *err);
151extern struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block,
152 int create, int *err);
149extern int udf_setsize(struct inode *, loff_t); 153extern int udf_setsize(struct inode *, loff_t);
150extern void udf_evict_inode(struct inode *); 154extern void udf_evict_inode(struct inode *);
151extern int udf_write_inode(struct inode *, struct writeback_control *wbc); 155extern int udf_write_inode(struct inode *, struct writeback_control *wbc);
152extern long udf_block_map(struct inode *, sector_t); 156extern udf_pblk_t udf_block_map(struct inode *inode, sector_t block);
153extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, 157extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *,
154 struct kernel_lb_addr *, uint32_t *, sector_t *); 158 struct kernel_lb_addr *, uint32_t *, sector_t *);
155extern int udf_setup_indirect_aext(struct inode *inode, int block, 159extern int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block,
156 struct extent_position *epos); 160 struct extent_position *epos);
157extern int __udf_add_aext(struct inode *inode, struct extent_position *epos, 161extern int __udf_add_aext(struct inode *inode, struct extent_position *epos,
158 struct kernel_lb_addr *eloc, uint32_t elen, int inc); 162 struct kernel_lb_addr *eloc, uint32_t elen, int inc);
@@ -168,8 +172,9 @@ extern int8_t udf_current_aext(struct inode *, struct extent_position *,
168 struct kernel_lb_addr *, uint32_t *, int); 172 struct kernel_lb_addr *, uint32_t *, int);
169 173
170/* misc.c */ 174/* misc.c */
171extern struct buffer_head *udf_tgetblk(struct super_block *, int); 175extern struct buffer_head *udf_tgetblk(struct super_block *sb,
172extern struct buffer_head *udf_tread(struct super_block *, int); 176 udf_pblk_t block);
177extern struct buffer_head *udf_tread(struct super_block *sb, udf_pblk_t block);
173extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t, 178extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t,
174 uint32_t, uint8_t); 179 uint32_t, uint8_t);
175extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, 180extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t,
@@ -228,8 +233,8 @@ extern void udf_free_blocks(struct super_block *, struct inode *,
228 struct kernel_lb_addr *, uint32_t, uint32_t); 233 struct kernel_lb_addr *, uint32_t, uint32_t);
229extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t, 234extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t,
230 uint32_t, uint32_t); 235 uint32_t, uint32_t);
231extern int udf_new_block(struct super_block *, struct inode *, uint16_t, 236extern udf_pblk_t udf_new_block(struct super_block *sb, struct inode *inode,
232 uint32_t, int *); 237 uint16_t partition, uint32_t goal, int *err);
233 238
234/* directory.c */ 239/* directory.c */
235extern struct fileIdentDesc *udf_fileident_read(struct inode *, loff_t *, 240extern struct fileIdentDesc *udf_fileident_read(struct inode *, loff_t *,