lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 16 Feb 2009 12:15:24 +0900
From:	Paul Mundt <lethal@...ux-sh.org>
To:	Adrian McMenamin <adrian@...golddream.dyndns.info>
Cc:	viro@...iv.linux.org.uk, linux-fsdevel@...r.kernel.org,
	LKML <linux-kernel@...r.kernel.org>, linux-sh@...r.kernel.org
Subject: Re: [RFC][PATCH] filesystem: VMUFAT filesystem

On Sat, Feb 14, 2009 at 09:16:59PM +0000, Adrian McMenamin wrote:
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/fs.h>
> +#include <linux/slab.h>
> +#include <linux/blkdev.h>
> +#include <linux/buffer_head.h>
> +#include <linux/mtd/mtd.h>
> +#include "vmufat.h"
> +
Why do you have an mtd include?

> +struct dentry *vmufat_inode_lookup(struct inode *in, struct dentry *dent,
> +	struct nameidata *nd)
> +{
[snip]
> +	sb = in->i_sb;
> +	vmudetails = (struct memcard *)sb->s_fs_info;

All of your sb->s_fs_info casts are superfluous. Do not cast void
pointers.

> +			if (!ino || IS_ERR(ino)) {
> +				error = -EACCES;
> +				goto release_bh;
> +			}
In the IS_ERR case, you can use PTR_ERR for setting the error value.
Throughout most of this code you completely ignore the error value that
is handed down and invent your own instead, making debugging far more
painful than it needs to be.

> +		/* do we need to move to the next block in the directory? */
> +		if ((fno / 0x10) > (vmudetails->dir_bnum - blck_read)) {
> +			brelse(bh);
> +			blck_read--;

Was the extra vowel really that much more work to write out?

> +	/* BCD timestamp it */
> +	unix_date = CURRENT_TIME.tv_sec;
> +	day = unix_date / 86400 - 3652;
> +	year = day / 365;
> +
> +	if ((year + 3) / 4 + 365 * year > day)
> +		year--;
> +
> +	day -= (year + 3) / 4 + 365 * year;
> +	if (day == 59 && !(year & 3)) {
> +		nl_day = day;
> +		month = 2;
> +	} else {
> +		nl_day = (year & 3) || day <= 59 ? day : day - 1;
> +		for (month = 0; month < 12; month++)
> +			if (day_n[month] > nl_day)
> +				break;
> +	}
> +
> +	century = 19;
> +	if (year > 19)
> +		century = 20;
> +
> +	bh->b_data[z + 0x10] = bcd_from_u8(century);
> +	u8year = year + 80;
> +	if (u8year > 99)
> +		u8year = u8year - 100;
> +
> +	bh->b_data[z + 0x11] = bcd_from_u8(u8year);
> +	bh->b_data[z + 0x12] = bcd_from_u8((__u8) month);
> +	bh->b_data[z + 0x13] =
> +	    bcd_from_u8((__u8) day - day_n[month - 1] + 1);
> +	bh->b_data[z + 0x14] =
> +	    bcd_from_u8((__u8) ((unix_date / 3600) % 24));
> +	bh->b_data[z + 0x15] = bcd_from_u8((__u8) ((unix_date / 60) % 60));
> +	bh->b_data[z + 0x16] = bcd_from_u8((__u8) (unix_date % 60));
> +
This should be abstracted out in to a separate function, and you can get
rid of most of this hand-rolled time mangling by using the rtc lib
routines.

Additionally, all of the bcd conversion code is superfluous, since you
can include linux/bcd.h and use bin2bcd and bcd2bin directly.

> +static int vmufat_inode_rename(struct inode *in_source,
> +			      struct dentry *de_source,
> +			      struct inode *in_target,
> +			      struct dentry *de_target)
> +{
> +	return -EPERM;
> +}
> +
Just get rid of this if you aren't going to support it.

> +	saved_file =
> +	    kmalloc(sizeof(struct vmufat_file_info), GFP_KERNEL);
> +
Error handling?

> +	}
> +	/* Now every other block */
> +	else {

Please refrain from adopting magical coding styles.

> +			}
> +
> +		}
> +
> +
> +	}
> +
> +
Lots of superfluous whitespace.

> +	readbuf = kzalloc(count, GFP_KERNEL);
> +	/* Traverse through FAT to read the blocks in */
> +	x = 0;
Again, no error handling.

> +static int vmufat_file_open(struct inode *in, struct file *f)
> +{
> +	return 0;
> +}
> +
You should be able to kill this off, also.

> +__u8 bcd_from_u8(__u8 num)
> +{
> +	__u8 topnib = num / 10;
> +	__u8 botnib = num % 10;
> +	return topnib << 4 | botnib;
> +}
> +
> +inline int int_from_bcd(__u8 bcd)
> +{
> +	int topnib = (bcd >> 4) & 0x000f;
> +	int botnib = bcd & 0x000f;
> +
> +	return (topnib * 10) + botnib;
> +}
> +
As already mentioned, these are already in linux/bcd.h.

> +static void vmufat_put_super(struct super_block *sb)
> +{
> +	struct memcard *vmudetails;
> +	sb->s_dev = 0;
> +	vmudetails = (struct memcard *) (sb->s_fs_info);
> +	kfree(vmudetails);

vmudetails is completely unused here, just kfree sb->s_fs_info.

> +	/* BCD timestamp it */
> +	unix_date = CURRENT_TIME.tv_sec;
> +	day = unix_date / 86400 - 3652;
> +	year = day / 365;
> +	if ((year + 3) / 4 + 365 * year > day)
> +		year--;
> +	day -= (year + 3) / 4 + 365 * year;
> +	if (day == 59 && !(year & 3)) {
> +		nl_day = day;
> +		month = 2;
> +	} else {
> +		nl_day = (year & 3) || day <= 59 ? day : day - 1;
> +		for (month = 0; month < 12; month++)
> +			if (day_n[month] > nl_day)
> +				break;
> +	}
> +
> +	century = 19;
> +	if (year > 19)
> +		century = 20;
> +	bh->b_data[z + 0x10] = bcd_from_u8(century);
> +	u8year = year + 80;
> +	if (u8year > 99)
> +		u8year = u8year - 100;
> +	bh->b_data[z + 0x11] = bcd_from_u8(u8year);
> +	bh->b_data[z + 0x12] = bcd_from_u8((__u8) month);
> +	bh->b_data[z + 0x13] =
> +	    bcd_from_u8((__u8) day - day_n[month - 1] + 1);
> +	bh->b_data[z + 0x14] =
> +	    bcd_from_u8((__u8) ((unix_date / 3600) % 24));
> +	bh->b_data[z + 0x15] = bcd_from_u8((__u8) ((unix_date / 60) % 60));
> +	bh->b_data[z + 0x16] = bcd_from_u8((__u8) (unix_date % 60));
> +
> +	((__u16 *) bh->b_data)[z / 2 + 0x0C] = cpu_to_le16(in->i_blocks);
> +	if (inode_num != 0)
> +		((__u16 *) bh->b_data)[z / 2 + 0x0D] = 0;
> +	else /* game */
> +		((__u16 *) bh->b_data)[z / 2 + 0x0D] = cpu_to_le16(1);
> +	in->i_mtime.tv_sec = unix_date;

Again, all of this can be simplified using rtc lib and bcd routines.

> +static int check_sb_format(struct buffer_head *bh)
> +{
> +	__u32 s_magic = 0x55555555;
> +
This magic value is used in lots of places, you should have a define for
it, and add it to linux/magic.h.

> +	if (!((((__u32 *) bh->b_data)[0] == s_magic)
> +	      && (((__u32 *) bh->b_data)[1] == s_magic)
> +	      && (((__u32 *) bh->b_data)[2] == s_magic)
> +	      && (s_magic == ((__u32 *) bh->b_data)[3])))
> +		return 0;

&&'s at the end of the line. You can also switch the if to a return and
kill off the else.

> +	vmudata = kmalloc(sizeof(struct memcard), GFP_KERNEL);
> +
> +	/* user blocks */
No error handling again. You will want to verify all of your kmallocs,
since you seem to have this issue a lot.

> +	while ((erasesize /= 2) != 0)
> +		log_2++;	/* thanks to MR Brown */
> +
> +	sb->s_blocksize_bits = log_2;

ilog2()?

I've tried to skip over the bits already noted by Evgeniy, but you may
have already fixed up some of the issues noted above anyways.

Also, in the next iteration of this patch, please do not break the Cc
list and send multiple times to different lists, it makes it very
difficult to follow what is going on, especially if the threads of
conversation diverge.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ