* [RFC PATCH v7 0/2] Btrfs: get/set label of a mounted file system @ 2012-12-20 8:43 Jeff Liu 2012-12-20 8:43 ` [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the " Jeff Liu 2012-12-20 8:43 ` [RFC PATCH v7 2/2] Btrfs: Add a new ioctl to set/change " Jeff Liu 0 siblings, 2 replies; 12+ messages in thread From: Jeff Liu @ 2012-12-20 8:43 UTC (permalink / raw) To: linux-btrfs; +Cc: anand.jain, miaox, kreijack, dsterba Hello, Per David's comments upon v6, I missed a check up against the return value of btrfs_end_transaction for btrfs_ioctl_fs_setlabel(), it was fixed in this version. v7->v6: - take care of btrfs_end_transaction() in btrfs_ioctl_fs_setlabel() rather than keeping silence. The old versions can be found at: v6: http://www.spinics.net/lists/linux-btrfs/msg20922.html v5: http://www.spinics.net/lists/linux-btrfs/msg20888.html v4: http://permalink.gmane.org/gmane.comp.file-systems.btrfs/21618 v3: https://patchwork.kernel.org/patch/1124642/ v2: http://permalink.gmane.org/gmane.comp.file-systems.btrfs/12877 v1: http://permalink.gmane.org/gmane.comp.file-systems.btrfs/12872 Thanks, -Jeff ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system 2012-12-20 8:43 [RFC PATCH v7 0/2] Btrfs: get/set label of a mounted file system Jeff Liu @ 2012-12-20 8:43 ` Jeff Liu 2012-12-20 20:18 ` Goffredo Baroncelli 2012-12-20 8:43 ` [RFC PATCH v7 2/2] Btrfs: Add a new ioctl to set/change " Jeff Liu 1 sibling, 1 reply; 12+ messages in thread From: Jeff Liu @ 2012-12-20 8:43 UTC (permalink / raw) To: linux-btrfs; +Cc: anand.jain, miaox, kreijack, dsterba With the new ioctl(2) BTRFS_IOC_GET_FSLABEL we can fetch the label of a mounted file system. Signed-off-by: Jie Liu <jeff.liu@oracle.com> Signed-off-by: Anand Jain <anand.jain@oracle.com> Cc: Miao Xie <miaox@cn.fujitsu.com> Cc: Goffredo Baroncelli <kreijack@inwind.it> Cc: David Sterba <dsterba@suse.cz> --- fs/btrfs/ioctl.c | 15 +++++++++++++++ fs/btrfs/ioctl.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 8fcf9a5..6a2488a 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3699,6 +3699,19 @@ out: return ret; } +static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) +{ + struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; + const char *label = root->fs_info->super_copy->label; + int ret; + + mutex_lock(&root->fs_info->volume_mutex); + ret = copy_to_user(arg, label, strlen(label)); + mutex_unlock(&root->fs_info->volume_mutex); + + return ret ? -EFAULT : 0; +} + long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -3797,6 +3810,8 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_qgroup_create(root, argp); case BTRFS_IOC_QGROUP_LIMIT: return btrfs_ioctl_qgroup_limit(root, argp); + case BTRFS_IOC_GET_FSLABEL: + return btrfs_ioctl_get_fslabel(file, argp); } return -ENOTTY; diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 731e287..5b2cbef 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -451,6 +451,8 @@ struct btrfs_ioctl_send_args { struct btrfs_ioctl_qgroup_create_args) #define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \ struct btrfs_ioctl_qgroup_limit_args) +#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ + char[BTRFS_LABEL_SIZE]) #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ struct btrfs_ioctl_get_dev_stats) #endif -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system 2012-12-20 8:43 ` [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the " Jeff Liu @ 2012-12-20 20:18 ` Goffredo Baroncelli 2012-12-21 6:42 ` Jeff Liu 0 siblings, 1 reply; 12+ messages in thread From: Goffredo Baroncelli @ 2012-12-20 20:18 UTC (permalink / raw) To: Jeff Liu; +Cc: linux-btrfs, anand.jain, miaox, dsterba HI Jeff, On 12/20/2012 09:43 AM, Jeff Liu wrote: > With the new ioctl(2) BTRFS_IOC_GET_FSLABEL we can fetch the label of a mounted file system. > > Signed-off-by: Jie Liu <jeff.liu@oracle.com> > Signed-off-by: Anand Jain <anand.jain@oracle.com> > Cc: Miao Xie <miaox@cn.fujitsu.com> > Cc: Goffredo Baroncelli <kreijack@inwind.it> > Cc: David Sterba <dsterba@suse.cz> [...] > +static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) > +{ > + struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; > + const char *label = root->fs_info->super_copy->label; > + int ret; > + > + mutex_lock(&root->fs_info->volume_mutex); > + ret = copy_to_user(arg, label, strlen(label)); Sorry for pointing out my doubt too late, but should we trust super_copy->label ? An user could insert a usb-key with a btrfs filesystem with a label without zero. In this case strlen() could access outside super_copy->label[]. I think that it should be quite easy to alter artificially a filesystem to crash the kernel. So I not consider this as big problem. However *in case* of a further cycle of this patch I suggest to replace strlen() with strnlen(). > + mutex_unlock(&root->fs_info->volume_mutex); > + > + return ret ? -EFAULT : 0; > +} > + > long btrfs_ioctl(struct file *file, unsigned int > cmd, unsigned long arg) > { > @@ -3797,6 +3810,8 @@ long btrfs_ioctl(struct file *file, unsigned int > return btrfs_ioctl_qgroup_create(root, argp); > case BTRFS_IOC_QGROUP_LIMIT: > return btrfs_ioctl_qgroup_limit(root, argp); > + case BTRFS_IOC_GET_FSLABEL: > + return btrfs_ioctl_get_fslabel(file, argp); > } > > return -ENOTTY; > diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h > index 731e287..5b2cbef 100644 > --- a/fs/btrfs/ioctl.h > +++ b/fs/btrfs/ioctl.h > @@ -451,6 +451,8 @@ struct btrfs_ioctl_send_args { > struct btrfs_ioctl_qgroup_create_args) > #define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \ > struct btrfs_ioctl_qgroup_limit_args) > +#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ > + char[BTRFS_LABEL_SIZE]) > #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ > struct btrfs_ioctl_get_dev_stats) > #endif -- gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it> Key fingerprint BBF5 1610 0B64 DAC6 5F7D 17B2 0EDA 9B37 8B82 E0B5 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system 2012-12-20 20:18 ` Goffredo Baroncelli @ 2012-12-21 6:42 ` Jeff Liu 2012-12-21 8:50 ` Stefan Behrens 2012-12-21 17:36 ` Goffredo Baroncelli 0 siblings, 2 replies; 12+ messages in thread From: Jeff Liu @ 2012-12-21 6:42 UTC (permalink / raw) To: kreijack; +Cc: linux-btrfs, anand.jain, miaox, dsterba Hi Goffredo, On 12/21/2012 04:18 AM, Goffredo Baroncelli wrote: > HI Jeff, > > On 12/20/2012 09:43 AM, Jeff Liu wrote: >> With the new ioctl(2) BTRFS_IOC_GET_FSLABEL we can fetch the label of a mounted file system. >> >> Signed-off-by: Jie Liu <jeff.liu@oracle.com> >> Signed-off-by: Anand Jain <anand.jain@oracle.com> >> Cc: Miao Xie <miaox@cn.fujitsu.com> >> Cc: Goffredo Baroncelli <kreijack@inwind.it> >> Cc: David Sterba <dsterba@suse.cz> > [...] >> +static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) >> +{ >> + struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; >> + const char *label = root->fs_info->super_copy->label; >> + int ret; >> + >> + mutex_lock(&root->fs_info->volume_mutex); >> + ret = copy_to_user(arg, label, strlen(label)); > > Sorry for pointing out my doubt too late, but should we trust > super_copy->label ? > An user could insert a usb-key with a btrfs filesystem with a label > without zero. In this case strlen() could access outside > super_copy->label[]. Thank you for letting me be aware of this situation. First of all, if the user set label via btrfs tools, he can not make it length exceeding BTRFS_LABLE_SIZE - 1. If the user does that through codes wrote by himself like: btrfslabel.c->set_label_unmounted(), he can do that. However, it most likely he did that for evil purpose or any other reasons? > > I think that it should be quite easy to alter artificially a filesystem > to crash the kernel. So I not consider this as big problem. However *in > case* of a further cycle of this patch I suggest to replace strlen() > with strnlen(). I don't think we should replace strlen() with strnlen() since it's totally wrong if the length of label is more than BTRFS_LABEL_SIZE -1, we can not just truncating the label and return it in this case. Add BUG_ON(strlen(label) > BTRFS_LABEL_SIZE - 1) is reasonable instead. Thanks, -Jeff > >> + mutex_unlock(&root->fs_info->volume_mutex); >> + >> + return ret ? -EFAULT : 0; >> +} >> + >> long btrfs_ioctl(struct file *file, unsigned int >> cmd, unsigned long arg) >> { >> @@ -3797,6 +3810,8 @@ long btrfs_ioctl(struct file *file, unsigned int >> return btrfs_ioctl_qgroup_create(root, argp); >> case BTRFS_IOC_QGROUP_LIMIT: >> return btrfs_ioctl_qgroup_limit(root, argp); >> + case BTRFS_IOC_GET_FSLABEL: >> + return btrfs_ioctl_get_fslabel(file, argp); >> } >> >> return -ENOTTY; >> diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h >> index 731e287..5b2cbef 100644 >> --- a/fs/btrfs/ioctl.h >> +++ b/fs/btrfs/ioctl.h >> @@ -451,6 +451,8 @@ struct btrfs_ioctl_send_args { >> struct btrfs_ioctl_qgroup_create_args) >> #define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \ >> struct btrfs_ioctl_qgroup_limit_args) >> +#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ >> + char[BTRFS_LABEL_SIZE]) >> #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ >> struct btrfs_ioctl_get_dev_stats) >> #endif > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system 2012-12-21 6:42 ` Jeff Liu @ 2012-12-21 8:50 ` Stefan Behrens 2012-12-21 17:36 ` Goffredo Baroncelli 1 sibling, 0 replies; 12+ messages in thread From: Stefan Behrens @ 2012-12-21 8:50 UTC (permalink / raw) To: Jeff Liu; +Cc: kreijack, linux-btrfs, anand.jain, miaox, dsterba On 12/21/2012 07:42, Jeff Liu wrote: > On 12/21/2012 04:18 AM, Goffredo Baroncelli wrote: >> On 12/20/2012 09:43 AM, Jeff Liu wrote: >>> +static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) >>> +{ >>> + struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; >>> + const char *label = root->fs_info->super_copy->label; >>> + int ret; >>> + >>> + mutex_lock(&root->fs_info->volume_mutex); >>> + ret = copy_to_user(arg, label, strlen(label)); >> >> Sorry for pointing out my doubt too late, but should we trust >> super_copy->label ? >> An user could insert a usb-key with a btrfs filesystem with a label >> without zero. In this case strlen() could access outside >> super_copy->label[]. > Thank you for letting me be aware of this situation. > > First of all, if the user set label via btrfs tools, he can not make it > length exceeding BTRFS_LABLE_SIZE - 1. > > If the user does that through codes wrote by himself like: > btrfslabel.c->set_label_unmounted(), he can do that. > However, it most likely he did that for evil purpose or any other reasons? >> >> I think that it should be quite easy to alter artificially a filesystem >> to crash the kernel. So I not consider this as big problem. However *in >> case* of a further cycle of this patch I suggest to replace strlen() >> with strnlen(). > I don't think we should replace strlen() with strnlen() since it's > totally wrong if the length of label is more than BTRFS_LABEL_SIZE -1, > we can not just truncating the label and return it in this case. > Add BUG_ON(strlen(label) > BTRFS_LABEL_SIZE - 1) is reasonable instead. Don't allow users to attack the kernel! This would add a severe security issue. A BUG_ON() is something that you can use before the code would crash anyway, to prevent any additional damage and to help in debugging. A BUG() is not a method to report or handle user errors. A Linux system is supposed to run until it is shutdown by the administrator, not until somebody inserts an USB stick. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system 2012-12-21 6:42 ` Jeff Liu 2012-12-21 8:50 ` Stefan Behrens @ 2012-12-21 17:36 ` Goffredo Baroncelli 2012-12-24 8:07 ` Jeff Liu 1 sibling, 1 reply; 12+ messages in thread From: Goffredo Baroncelli @ 2012-12-21 17:36 UTC (permalink / raw) To: Jeff Liu Cc: kreijack, linux-btrfs, anand.jain, miaox, dsterba, Stefan Behrens On 12/21/2012 07:42 AM, Jeff Liu wrote: > Hi Goffredo, > > On 12/21/2012 04:18 AM, Goffredo Baroncelli wrote: >> HI Jeff, >> >> On 12/20/2012 09:43 AM, Jeff Liu wrote: >>> With the new ioctl(2) BTRFS_IOC_GET_FSLABEL we can fetch the label of a mounted file system. >>> >>> Signed-off-by: Jie Liu <jeff.liu@oracle.com> >>> Signed-off-by: Anand Jain <anand.jain@oracle.com> >>> Cc: Miao Xie <miaox@cn.fujitsu.com> >>> Cc: Goffredo Baroncelli <kreijack@inwind.it> >>> Cc: David Sterba <dsterba@suse.cz> >> [...] >>> +static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) >>> +{ >>> + struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; >>> + const char *label = root->fs_info->super_copy->label; >>> + int ret; >>> + >>> + mutex_lock(&root->fs_info->volume_mutex); >>> + ret = copy_to_user(arg, label, strlen(label)); >> >> Sorry for pointing out my doubt too late, but should we trust >> super_copy->label ? >> An user could insert a usb-key with a btrfs filesystem with a label >> without zero. In this case strlen() could access outside >> super_copy->label[]. > Thank you for letting me be aware of this situation. > > First of all, if the user set label via btrfs tools, he can not make it > length exceeding BTRFS_LABLE_SIZE - 1. > > If the user does that through codes wrote by himself like: > btrfslabel.c->set_label_unmounted(), he can do that. > However, it most likely he did that for evil purpose or any other reasons? I think the most likely case is the "evil purpose". >> >> I think that it should be quite easy to alter artificially a filesystem >> to crash the kernel. So I not consider this as big problem. However *in >> case* of a further cycle of this patch I suggest to replace strlen() >> with strnlen(). > I don't think we should replace strlen() with strnlen() since it's > totally wrong if the length of label is more than BTRFS_LABEL_SIZE -1, > we can not just truncating the label and return it in this case. This for me is sufficient, or we could copy all the label buffer, without further check: copy_to_user(arg, label, BTRFS_LABEL_SIZE) > Add BUG_ON(strlen(label) > BTRFS_LABEL_SIZE - 1) is reasonable instead. I agree with Stefan, this is not a correct use of BUG_ON; a warning is sufficient (there is un-correct data read from disk). > > Thanks, > -Jeff >> >>> + mutex_unlock(&root->fs_info->volume_mutex); >>> + >>> + return ret ? -EFAULT : 0; >>> +} >>> + >>> long btrfs_ioctl(struct file *file, unsigned int >>> cmd, unsigned long arg) >>> { >>> @@ -3797,6 +3810,8 @@ long btrfs_ioctl(struct file *file, unsigned int >>> return btrfs_ioctl_qgroup_create(root, argp); >>> case BTRFS_IOC_QGROUP_LIMIT: >>> return btrfs_ioctl_qgroup_limit(root, argp); >>> + case BTRFS_IOC_GET_FSLABEL: >>> + return btrfs_ioctl_get_fslabel(file, argp); >>> } >>> >>> return -ENOTTY; >>> diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h >>> index 731e287..5b2cbef 100644 >>> --- a/fs/btrfs/ioctl.h >>> +++ b/fs/btrfs/ioctl.h >>> @@ -451,6 +451,8 @@ struct btrfs_ioctl_send_args { >>> struct btrfs_ioctl_qgroup_create_args) >>> #define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \ >>> struct btrfs_ioctl_qgroup_limit_args) >>> +#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ >>> + char[BTRFS_LABEL_SIZE]) >>> #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ >>> struct btrfs_ioctl_get_dev_stats) >>> #endif >> >> > > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it> Key fingerprint BBF5 1610 0B64 DAC6 5F7D 17B2 0EDA 9B37 8B82 E0B5 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system 2012-12-21 17:36 ` Goffredo Baroncelli @ 2012-12-24 8:07 ` Jeff Liu 2012-12-24 13:46 ` Goffredo Baroncelli 0 siblings, 1 reply; 12+ messages in thread From: Jeff Liu @ 2012-12-24 8:07 UTC (permalink / raw) To: kreijack Cc: Goffredo Baroncelli, linux-btrfs, anand.jain, miaox, dsterba, Stefan Behrens On 12/22/2012 01:36 AM, Goffredo Baroncelli wrote: > On 12/21/2012 07:42 AM, Jeff Liu wrote: >> Hi Goffredo, >> >> On 12/21/2012 04:18 AM, Goffredo Baroncelli wrote: >>> HI Jeff, >>> >>> On 12/20/2012 09:43 AM, Jeff Liu wrote: >>>> With the new ioctl(2) BTRFS_IOC_GET_FSLABEL we can fetch the label of a mounted file system. >>>> >>>> Signed-off-by: Jie Liu <jeff.liu@oracle.com> >>>> Signed-off-by: Anand Jain <anand.jain@oracle.com> >>>> Cc: Miao Xie <miaox@cn.fujitsu.com> >>>> Cc: Goffredo Baroncelli <kreijack@inwind.it> >>>> Cc: David Sterba <dsterba@suse.cz> >>> [...] >>>> +static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) >>>> +{ >>>> + struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; >>>> + const char *label = root->fs_info->super_copy->label; >>>> + int ret; >>>> + >>>> + mutex_lock(&root->fs_info->volume_mutex); >>>> + ret = copy_to_user(arg, label, strlen(label)); >>> >>> Sorry for pointing out my doubt too late, but should we trust >>> super_copy->label ? >>> An user could insert a usb-key with a btrfs filesystem with a label >>> without zero. In this case strlen() could access outside >>> super_copy->label[]. >> Thank you for letting me be aware of this situation. >> >> First of all, if the user set label via btrfs tools, he can not make it >> length exceeding BTRFS_LABLE_SIZE - 1. >> >> If the user does that through codes wrote by himself like: >> btrfslabel.c->set_label_unmounted(), he can do that. >> However, it most likely he did that for evil purpose or any other reasons? > > I think the most likely case is the "evil purpose". > >>> >>> I think that it should be quite easy to alter artificially a filesystem >>> to crash the kernel. So I not consider this as big problem. However *in >>> case* of a further cycle of this patch I suggest to replace strlen() >>> with strnlen(). >> I don't think we should replace strlen() with strnlen() since it's >> totally wrong if the length of label is more than BTRFS_LABEL_SIZE -1, >> we can not just truncating the label and return it in this case. > > This for me is sufficient, or we could copy all the label buffer, > without further check: > > copy_to_user(arg, label, BTRFS_LABEL_SIZE) That sounds ok to me, but it's better to limit the length to be 'BTRFS_LABEL_SIZE - 1' bytes, or else, it would copy 256 bytes back to the user space if the label length is beyond or equal to the array limits. > > >> Add BUG_ON(strlen(label) > BTRFS_LABEL_SIZE - 1) is reasonable instead. > > I agree with Stefan, this is not a correct use of BUG_ON; a warning is > sufficient (there is un-correct data read from disk). Maybe like following? size_t len = strlen(label); if (len > BTRFS_LABEL_SIZE - 1) { WARN(1, "btrfs: device label has weird length %zu bytes, " "it will be truncated to %d bytes.\n", len, BTRFS_LABEL_SIZE - 1); len = BTRFS_LABEL_SIZE - 1; } I'll post a new patch with those changes if no other objections. Happy Christmas. -Jeff > >> >> Thanks, >> -Jeff >>> >>>> + mutex_unlock(&root->fs_info->volume_mutex); >>>> + >>>> + return ret ? -EFAULT : 0; >>>> +} >>>> + >>>> long btrfs_ioctl(struct file *file, unsigned int >>>> cmd, unsigned long arg) >>>> { >>>> @@ -3797,6 +3810,8 @@ long btrfs_ioctl(struct file *file, unsigned int >>>> return btrfs_ioctl_qgroup_create(root, argp); >>>> case BTRFS_IOC_QGROUP_LIMIT: >>>> return btrfs_ioctl_qgroup_limit(root, argp); >>>> + case BTRFS_IOC_GET_FSLABEL: >>>> + return btrfs_ioctl_get_fslabel(file, argp); >>>> } >>>> >>>> return -ENOTTY; >>>> diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h >>>> index 731e287..5b2cbef 100644 >>>> --- a/fs/btrfs/ioctl.h >>>> +++ b/fs/btrfs/ioctl.h >>>> @@ -451,6 +451,8 @@ struct btrfs_ioctl_send_args { >>>> struct btrfs_ioctl_qgroup_create_args) >>>> #define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \ >>>> struct btrfs_ioctl_qgroup_limit_args) >>>> +#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ >>>> + char[BTRFS_LABEL_SIZE]) >>>> #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ >>>> struct btrfs_ioctl_get_dev_stats) >>>> #endif >>> >>> >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html >> > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system 2012-12-24 8:07 ` Jeff Liu @ 2012-12-24 13:46 ` Goffredo Baroncelli 2012-12-24 15:10 ` Jeff Liu 0 siblings, 1 reply; 12+ messages in thread From: Goffredo Baroncelli @ 2012-12-24 13:46 UTC (permalink / raw) To: Jeff Liu; +Cc: linux-btrfs, anand.jain, miaox, dsterba, Stefan Behrens Hi Jeff, On 12/24/2012 09:07 AM, Jeff Liu wrote: > On 12/22/2012 01:36 AM, Goffredo Baroncelli wrote: >> On 12/21/2012 07:42 AM, Jeff Liu wrote: [...] >>> I don't think we should replace strlen() with strnlen() since it's >>> totally wrong if the length of label is more than BTRFS_LABEL_SIZE -1, >>> we can not just truncating the label and return it in this case. >> >> This for me is sufficient, or we could copy all the label buffer, >> without further check: >> >> copy_to_user(arg, label, BTRFS_LABEL_SIZE) > That sounds ok to me, but it's better to limit the length to be > 'BTRFS_LABEL_SIZE - 1' bytes, or else, it would copy 256 bytes back to > the user space if the label length is beyond or equal to the array limits. Sorry I don't understand your reply. The ioctl has as argument an array of BTRFS_LABEL_SIZE characters, so it should not be any problem of page fault (with the exception of an user who passes a shorter array). So it wouldn't be any problem to copy BTRFS_LABEL_SIZE character, or I am missing something ? The question is another. Is a kernel responsibility to assure that the returned string is zero terminated ? If yes (and I think so) we should truncate the string before the copy: label[BTRFS_LABEL_SIZE-1] = 0; copy_to_user(arg, label, BTRFS_LABEL_SIZE); >> >> >>> Add BUG_ON(strlen(label) > BTRFS_LABEL_SIZE - 1) is reasonable instead. >> >> I agree with Stefan, this is not a correct use of BUG_ON; a warning is >> sufficient (there is un-correct data read from disk). > Maybe like following? > > size_t len = strlen(label); If label (who is an array read from the disk) is not zero terminated, this would lead to a possible page fault. I suggest to use strnlen() or similar. > > if (len > BTRFS_LABEL_SIZE - 1) { > WARN(1, "btrfs: device label has weird length %zu bytes, " > "it will be truncated to %d bytes.\n", > len, BTRFS_LABEL_SIZE - 1); > > len = BTRFS_LABEL_SIZE - 1; > } As message I suggest: WARN(1, "btrfs: device label is not zero terminated, it will be truncated to %d bytes.\n", BTRFS_LABEL-1 ); NOTE: it is suggested to not span the string on more lines, to help searching in the source a messages with grep. It is an exception of the rule of the max 80 columns text width. Happy Christmas you too GB > > I'll post a new patch with those changes if no other objections. > > Happy Christmas. > -Jeff >> >>> >>> Thanks, >>> -Jeff >>>> >>>>> + mutex_unlock(&root->fs_info->volume_mutex); >>>>> + >>>>> + return ret ? -EFAULT : 0; >>>>> +} >>>>> + >>>>> long btrfs_ioctl(struct file *file, unsigned int >>>>> cmd, unsigned long arg) >>>>> { >>>>> @@ -3797,6 +3810,8 @@ long btrfs_ioctl(struct file *file, unsigned int >>>>> return btrfs_ioctl_qgroup_create(root, argp); >>>>> case BTRFS_IOC_QGROUP_LIMIT: >>>>> return btrfs_ioctl_qgroup_limit(root, argp); >>>>> + case BTRFS_IOC_GET_FSLABEL: >>>>> + return btrfs_ioctl_get_fslabel(file, argp); >>>>> } >>>>> >>>>> return -ENOTTY; >>>>> diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h >>>>> index 731e287..5b2cbef 100644 >>>>> --- a/fs/btrfs/ioctl.h >>>>> +++ b/fs/btrfs/ioctl.h >>>>> @@ -451,6 +451,8 @@ struct btrfs_ioctl_send_args { >>>>> struct btrfs_ioctl_qgroup_create_args) >>>>> #define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \ >>>>> struct btrfs_ioctl_qgroup_limit_args) >>>>> +#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ >>>>> + char[BTRFS_LABEL_SIZE]) >>>>> #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ >>>>> struct btrfs_ioctl_get_dev_stats) >>>>> #endif >>>> >>>> >>> >>> -- >>> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in >>> the body of a message to majordomo@vger.kernel.org >>> More majordomo info at http://vger.kernel.org/majordomo-info.html >>> >> >> > > -- gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it> Key fingerprint BBF5 1610 0B64 DAC6 5F7D 17B2 0EDA 9B37 8B82 E0B5 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system 2012-12-24 13:46 ` Goffredo Baroncelli @ 2012-12-24 15:10 ` Jeff Liu 0 siblings, 0 replies; 12+ messages in thread From: Jeff Liu @ 2012-12-24 15:10 UTC (permalink / raw) To: kreijack Cc: Goffredo Baroncelli, linux-btrfs, anand.jain, miaox, dsterba, Stefan Behrens On 12/24/2012 09:46 PM, Goffredo Baroncelli wrote: > Hi Jeff, > > On 12/24/2012 09:07 AM, Jeff Liu wrote: >> On 12/22/2012 01:36 AM, Goffredo Baroncelli wrote: >>> On 12/21/2012 07:42 AM, Jeff Liu wrote: > [...] >>>> I don't think we should replace strlen() with strnlen() since it's >>>> totally wrong if the length of label is more than BTRFS_LABEL_SIZE -1, >>>> we can not just truncating the label and return it in this case. >>> >>> This for me is sufficient, or we could copy all the label buffer, >>> without further check: >>> >>> copy_to_user(arg, label, BTRFS_LABEL_SIZE) >> That sounds ok to me, but it's better to limit the length to be >> 'BTRFS_LABEL_SIZE - 1' bytes, or else, it would copy 256 bytes back to >> the user space if the label length is beyond or equal to the array limits. > > Sorry I don't understand your reply. The ioctl has as argument an array > of BTRFS_LABEL_SIZE characters, so it should not be any problem of page > fault (with the exception of an user who passes a shorter array). So it > wouldn't be any problem to copy > BTRFS_LABEL_SIZE character, or I am missing something ? We can copy label length up to BTRFS_LABEL_SIZE back to the user space, but please see my response which were shown as following. > > The question is another. Is a kernel responsibility to assure that the > returned string is zero terminated ? If yes (and I think so) we should > truncate the string before the copy: On both the old btrfslabel.c->change_label_unmounted() and the new ioctl(BTRFS_IOC_SET_FSLABE), we all made the terminated character to be NUL(i.e. actually, the maximum length is 255), so that it's better to assure that the returned string to be same as well IMO. > > label[BTRFS_LABEL_SIZE-1] = 0; > copy_to_user(arg, label, BTRFS_LABEL_SIZE); This definitely works, please see my response below again. > >>> >>> >>>> Add BUG_ON(strlen(label) > BTRFS_LABEL_SIZE - 1) is reasonable instead. >>> >>> I agree with Stefan, this is not a correct use of BUG_ON; a warning is >>> sufficient (there is un-correct data read from disk). >> Maybe like following? >> >> size_t len = strlen(label); As we have already evaluated the real length of the label, why not just use it to indicate the length that will be copied back? > > If label (who is an array read from the disk) is not zero terminated, > this would lead to a possible page fault. I suggest to use strnlen() or > similar. Good point, that would make code better, i.e. avoid page fault. :) > >> >> if (len > BTRFS_LABEL_SIZE - 1) { >> WARN(1, "btrfs: device label has weird length %zu bytes, " >> "it will be truncated to %d bytes.\n", >> len, BTRFS_LABEL_SIZE - 1); >> >> len = BTRFS_LABEL_SIZE - 1; >> } > > As message I suggest: > > WARN(1, "btrfs: device label is not zero terminated, it will be > truncated to %d bytes.\n", > BTRFS_LABEL-1 ); Ok, I'd like to follow up with your suggestions as am not english native. > > > NOTE: it is suggested to not span the string on more lines, to help > searching in the source a messages with grep. It is an exception of the > rule of the max 80 columns text width. That's why I splitted the warning info into two lines. Thanks, -Jeff > > Happy Christmas you too > GB > >> >> I'll post a new patch with those changes if no other objections. >> >> Happy Christmas. >> -Jeff >>> >>>> >>>> Thanks, >>>> -Jeff >>>>> >>>>>> + mutex_unlock(&root->fs_info->volume_mutex); >>>>>> + >>>>>> + return ret ? -EFAULT : 0; >>>>>> +} >>>>>> + >>>>>> long btrfs_ioctl(struct file *file, unsigned int >>>>>> cmd, unsigned long arg) >>>>>> { >>>>>> @@ -3797,6 +3810,8 @@ long btrfs_ioctl(struct file *file, unsigned int >>>>>> return btrfs_ioctl_qgroup_create(root, argp); >>>>>> case BTRFS_IOC_QGROUP_LIMIT: >>>>>> return btrfs_ioctl_qgroup_limit(root, argp); >>>>>> + case BTRFS_IOC_GET_FSLABEL: >>>>>> + return btrfs_ioctl_get_fslabel(file, argp); >>>>>> } >>>>>> >>>>>> return -ENOTTY; >>>>>> diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h >>>>>> index 731e287..5b2cbef 100644 >>>>>> --- a/fs/btrfs/ioctl.h >>>>>> +++ b/fs/btrfs/ioctl.h >>>>>> @@ -451,6 +451,8 @@ struct btrfs_ioctl_send_args { >>>>>> struct btrfs_ioctl_qgroup_create_args) >>>>>> #define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \ >>>>>> struct btrfs_ioctl_qgroup_limit_args) >>>>>> +#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ >>>>>> + char[BTRFS_LABEL_SIZE]) >>>>>> #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ >>>>>> struct btrfs_ioctl_get_dev_stats) >>>>>> #endif >>>>> >>>>> >>>> >>>> -- >>>> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in >>>> the body of a message to majordomo@vger.kernel.org >>>> More majordomo info at http://vger.kernel.org/majordomo-info.html >>>> >>> >>> >> >> > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC PATCH v7 2/2] Btrfs: Add a new ioctl to set/change the label of a mounted file system 2012-12-20 8:43 [RFC PATCH v7 0/2] Btrfs: get/set label of a mounted file system Jeff Liu 2012-12-20 8:43 ` [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the " Jeff Liu @ 2012-12-20 8:43 ` Jeff Liu 2012-12-20 20:19 ` Goffredo Baroncelli 2012-12-27 17:34 ` David Sterba 1 sibling, 2 replies; 12+ messages in thread From: Jeff Liu @ 2012-12-20 8:43 UTC (permalink / raw) To: linux-btrfs; +Cc: anand.jain, miaox, kreijack, dsterba With the new ioctl(2) BTRFS_IOC_SET_FSLABEL, we can set/change the label of a mounted file system. Signed-off-by: Jie Liu <jeff.liu@oracle.com> Signed-off-by: Anand Jain <anand.jain@oracle.com> Cc: Miao Xie <miaox@cn.fujitsu.com> Cc: Goffredo Baroncelli <kreijack@inwind.it> Cc: David Sterba <dsterba@suse.cz> --- fs/btrfs/ioctl.c | 39 +++++++++++++++++++++++++++++++++++++++ fs/btrfs/ioctl.h | 2 ++ 2 files changed, 41 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 6a2488a..99aa812 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3712,6 +3712,43 @@ static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) return ret ? -EFAULT : 0; } +static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg) +{ + struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; + struct btrfs_super_block *super_block = root->fs_info->super_copy; + struct btrfs_trans_handle *trans; + char label[BTRFS_LABEL_SIZE]; + int ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (copy_from_user(label, arg, sizeof(label))) + return -EFAULT; + + if (strnlen(label, BTRFS_LABEL_SIZE) == BTRFS_LABEL_SIZE) + return -EINVAL; + + ret = mnt_want_write_file(file); + if (ret) + return ret; + + mutex_lock(&root->fs_info->volume_mutex); + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + goto out_unlock; + } + + strcpy(super_block->label, label); + ret = btrfs_end_transaction(trans, root); + +out_unlock: + mutex_unlock(&root->fs_info->volume_mutex); + mnt_drop_write_file(file); + return ret; +} + long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -3812,6 +3849,8 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_qgroup_limit(root, argp); case BTRFS_IOC_GET_FSLABEL: return btrfs_ioctl_get_fslabel(file, argp); + case BTRFS_IOC_SET_FSLABEL: + return btrfs_ioctl_set_fslabel(file, argp); } return -ENOTTY; diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 5b2cbef..2abe239 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -453,6 +453,8 @@ struct btrfs_ioctl_send_args { struct btrfs_ioctl_qgroup_limit_args) #define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ char[BTRFS_LABEL_SIZE]) +#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \ + char[BTRFS_LABEL_SIZE]) #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ struct btrfs_ioctl_get_dev_stats) #endif -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [RFC PATCH v7 2/2] Btrfs: Add a new ioctl to set/change the label of a mounted file system 2012-12-20 8:43 ` [RFC PATCH v7 2/2] Btrfs: Add a new ioctl to set/change " Jeff Liu @ 2012-12-20 20:19 ` Goffredo Baroncelli 2012-12-27 17:34 ` David Sterba 1 sibling, 0 replies; 12+ messages in thread From: Goffredo Baroncelli @ 2012-12-20 20:19 UTC (permalink / raw) To: Jeff Liu; +Cc: linux-btrfs, anand.jain, miaox, dsterba On 12/20/2012 09:43 AM, Jeff Liu wrote: > With the new ioctl(2) BTRFS_IOC_SET_FSLABEL, we can set/change the label of a mounted file system. > > Signed-off-by: Jie Liu <jeff.liu@oracle.com> > Signed-off-by: Anand Jain <anand.jain@oracle.com> > Cc: Miao Xie <miaox@cn.fujitsu.com> > Cc: Goffredo Baroncelli <kreijack@inwind.it> > Cc: David Sterba <dsterba@suse.cz> Reviewed-by: Goffredo Baroncelli <kreijack@inwind.it> > --- > fs/btrfs/ioctl.c | 39 +++++++++++++++++++++++++++++++++++++++ > fs/btrfs/ioctl.h | 2 ++ > 2 files changed, 41 insertions(+) > > diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c > index 6a2488a..99aa812 100644 > --- a/fs/btrfs/ioctl.c > +++ b/fs/btrfs/ioctl.c > @@ -3712,6 +3712,43 @@ static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) > return ret ? -EFAULT : 0; > } > > +static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg) > +{ > + struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; > + struct btrfs_super_block *super_block = root->fs_info->super_copy; > + struct btrfs_trans_handle *trans; > + char label[BTRFS_LABEL_SIZE]; > + int ret; > + > + if (!capable(CAP_SYS_ADMIN)) > + return -EPERM; > + > + if (copy_from_user(label, arg, sizeof(label))) > + return -EFAULT; > + > + if (strnlen(label, BTRFS_LABEL_SIZE) == BTRFS_LABEL_SIZE) > + return -EINVAL; > + > + ret = mnt_want_write_file(file); > + if (ret) > + return ret; > + > + mutex_lock(&root->fs_info->volume_mutex); > + trans = btrfs_start_transaction(root, 1); > + if (IS_ERR(trans)) { > + ret = PTR_ERR(trans); > + goto out_unlock; > + } > + > + strcpy(super_block->label, label); > + ret = btrfs_end_transaction(trans, root); > + > +out_unlock: > + mutex_unlock(&root->fs_info->volume_mutex); > + mnt_drop_write_file(file); > + return ret; > +} > + > long btrfs_ioctl(struct file *file, unsigned int > cmd, unsigned long arg) > { > @@ -3812,6 +3849,8 @@ long btrfs_ioctl(struct file *file, unsigned int > return btrfs_ioctl_qgroup_limit(root, argp); > case BTRFS_IOC_GET_FSLABEL: > return btrfs_ioctl_get_fslabel(file, argp); > + case BTRFS_IOC_SET_FSLABEL: > + return btrfs_ioctl_set_fslabel(file, argp); > } > > return -ENOTTY; > diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h > index 5b2cbef..2abe239 100644 > --- a/fs/btrfs/ioctl.h > +++ b/fs/btrfs/ioctl.h > @@ -453,6 +453,8 @@ struct btrfs_ioctl_send_args { > struct btrfs_ioctl_qgroup_limit_args) > #define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ > char[BTRFS_LABEL_SIZE]) > +#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \ > + char[BTRFS_LABEL_SIZE]) > #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ > struct btrfs_ioctl_get_dev_stats) > #endif -- gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it> Key fingerprint BBF5 1610 0B64 DAC6 5F7D 17B2 0EDA 9B37 8B82 E0B5 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH v7 2/2] Btrfs: Add a new ioctl to set/change the label of a mounted file system 2012-12-20 8:43 ` [RFC PATCH v7 2/2] Btrfs: Add a new ioctl to set/change " Jeff Liu 2012-12-20 20:19 ` Goffredo Baroncelli @ 2012-12-27 17:34 ` David Sterba 1 sibling, 0 replies; 12+ messages in thread From: David Sterba @ 2012-12-27 17:34 UTC (permalink / raw) To: Jeff Liu; +Cc: linux-btrfs, anand.jain, miaox, kreijack, dsterba On Thu, Dec 20, 2012 at 04:43:06PM +0800, Jeff Liu wrote: > With the new ioctl(2) BTRFS_IOC_SET_FSLABEL, we can set/change the label of a mounted file system. > > Signed-off-by: Jie Liu <jeff.liu@oracle.com> > Signed-off-by: Anand Jain <anand.jain@oracle.com> > Cc: Miao Xie <miaox@cn.fujitsu.com> > Cc: Goffredo Baroncelli <kreijack@inwind.it> > Cc: David Sterba <dsterba@suse.cz> Reviewed-by: David Sterba <dsterba@suse.cz> ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2012-12-27 17:34 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-12-20 8:43 [RFC PATCH v7 0/2] Btrfs: get/set label of a mounted file system Jeff Liu 2012-12-20 8:43 ` [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the " Jeff Liu 2012-12-20 20:18 ` Goffredo Baroncelli 2012-12-21 6:42 ` Jeff Liu 2012-12-21 8:50 ` Stefan Behrens 2012-12-21 17:36 ` Goffredo Baroncelli 2012-12-24 8:07 ` Jeff Liu 2012-12-24 13:46 ` Goffredo Baroncelli 2012-12-24 15:10 ` Jeff Liu 2012-12-20 8:43 ` [RFC PATCH v7 2/2] Btrfs: Add a new ioctl to set/change " Jeff Liu 2012-12-20 20:19 ` Goffredo Baroncelli 2012-12-27 17:34 ` David Sterba
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).