Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * security/tomoyo/gc.c
0004  *
0005  * Copyright (C) 2005-2011  NTT DATA CORPORATION
0006  */
0007 
0008 #include "common.h"
0009 #include <linux/kthread.h>
0010 #include <linux/slab.h>
0011 
0012 /**
0013  * tomoyo_memory_free - Free memory for elements.
0014  *
0015  * @ptr:  Pointer to allocated memory.
0016  *
0017  * Returns nothing.
0018  *
0019  * Caller holds tomoyo_policy_lock mutex.
0020  */
0021 static inline void tomoyo_memory_free(void *ptr)
0022 {
0023     tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= ksize(ptr);
0024     kfree(ptr);
0025 }
0026 
0027 /* The list for "struct tomoyo_io_buffer". */
0028 static LIST_HEAD(tomoyo_io_buffer_list);
0029 /* Lock for protecting tomoyo_io_buffer_list. */
0030 static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
0031 
0032 /**
0033  * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
0034  *
0035  * @element: Pointer to "struct list_head".
0036  *
0037  * Returns true if @element is used by /sys/kernel/security/tomoyo/ users,
0038  * false otherwise.
0039  */
0040 static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
0041 {
0042     struct tomoyo_io_buffer *head;
0043     bool in_use = false;
0044 
0045     spin_lock(&tomoyo_io_buffer_list_lock);
0046     list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
0047         head->users++;
0048         spin_unlock(&tomoyo_io_buffer_list_lock);
0049         mutex_lock(&head->io_sem);
0050         if (head->r.domain == element || head->r.group == element ||
0051             head->r.acl == element || &head->w.domain->list == element)
0052             in_use = true;
0053         mutex_unlock(&head->io_sem);
0054         spin_lock(&tomoyo_io_buffer_list_lock);
0055         head->users--;
0056         if (in_use)
0057             break;
0058     }
0059     spin_unlock(&tomoyo_io_buffer_list_lock);
0060     return in_use;
0061 }
0062 
0063 /**
0064  * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
0065  *
0066  * @string: String to check.
0067  *
0068  * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
0069  * false otherwise.
0070  */
0071 static bool tomoyo_name_used_by_io_buffer(const char *string)
0072 {
0073     struct tomoyo_io_buffer *head;
0074     const size_t size = strlen(string) + 1;
0075     bool in_use = false;
0076 
0077     spin_lock(&tomoyo_io_buffer_list_lock);
0078     list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
0079         int i;
0080 
0081         head->users++;
0082         spin_unlock(&tomoyo_io_buffer_list_lock);
0083         mutex_lock(&head->io_sem);
0084         for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
0085             const char *w = head->r.w[i];
0086 
0087             if (w < string || w > string + size)
0088                 continue;
0089             in_use = true;
0090             break;
0091         }
0092         mutex_unlock(&head->io_sem);
0093         spin_lock(&tomoyo_io_buffer_list_lock);
0094         head->users--;
0095         if (in_use)
0096             break;
0097     }
0098     spin_unlock(&tomoyo_io_buffer_list_lock);
0099     return in_use;
0100 }
0101 
0102 /**
0103  * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
0104  *
0105  * @element: Pointer to "struct list_head".
0106  *
0107  * Returns nothing.
0108  */
0109 static inline void tomoyo_del_transition_control(struct list_head *element)
0110 {
0111     struct tomoyo_transition_control *ptr =
0112         container_of(element, typeof(*ptr), head.list);
0113 
0114     tomoyo_put_name(ptr->domainname);
0115     tomoyo_put_name(ptr->program);
0116 }
0117 
0118 /**
0119  * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
0120  *
0121  * @element: Pointer to "struct list_head".
0122  *
0123  * Returns nothing.
0124  */
0125 static inline void tomoyo_del_aggregator(struct list_head *element)
0126 {
0127     struct tomoyo_aggregator *ptr =
0128         container_of(element, typeof(*ptr), head.list);
0129 
0130     tomoyo_put_name(ptr->original_name);
0131     tomoyo_put_name(ptr->aggregated_name);
0132 }
0133 
0134 /**
0135  * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
0136  *
0137  * @element: Pointer to "struct list_head".
0138  *
0139  * Returns nothing.
0140  */
0141 static inline void tomoyo_del_manager(struct list_head *element)
0142 {
0143     struct tomoyo_manager *ptr =
0144         container_of(element, typeof(*ptr), head.list);
0145 
0146     tomoyo_put_name(ptr->manager);
0147 }
0148 
0149 /**
0150  * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
0151  *
0152  * @element: Pointer to "struct list_head".
0153  *
0154  * Returns nothing.
0155  */
0156 static void tomoyo_del_acl(struct list_head *element)
0157 {
0158     struct tomoyo_acl_info *acl =
0159         container_of(element, typeof(*acl), list);
0160 
0161     tomoyo_put_condition(acl->cond);
0162     switch (acl->type) {
0163     case TOMOYO_TYPE_PATH_ACL:
0164         {
0165             struct tomoyo_path_acl *entry
0166                 = container_of(acl, typeof(*entry), head);
0167             tomoyo_put_name_union(&entry->name);
0168         }
0169         break;
0170     case TOMOYO_TYPE_PATH2_ACL:
0171         {
0172             struct tomoyo_path2_acl *entry
0173                 = container_of(acl, typeof(*entry), head);
0174             tomoyo_put_name_union(&entry->name1);
0175             tomoyo_put_name_union(&entry->name2);
0176         }
0177         break;
0178     case TOMOYO_TYPE_PATH_NUMBER_ACL:
0179         {
0180             struct tomoyo_path_number_acl *entry
0181                 = container_of(acl, typeof(*entry), head);
0182             tomoyo_put_name_union(&entry->name);
0183             tomoyo_put_number_union(&entry->number);
0184         }
0185         break;
0186     case TOMOYO_TYPE_MKDEV_ACL:
0187         {
0188             struct tomoyo_mkdev_acl *entry
0189                 = container_of(acl, typeof(*entry), head);
0190             tomoyo_put_name_union(&entry->name);
0191             tomoyo_put_number_union(&entry->mode);
0192             tomoyo_put_number_union(&entry->major);
0193             tomoyo_put_number_union(&entry->minor);
0194         }
0195         break;
0196     case TOMOYO_TYPE_MOUNT_ACL:
0197         {
0198             struct tomoyo_mount_acl *entry
0199                 = container_of(acl, typeof(*entry), head);
0200             tomoyo_put_name_union(&entry->dev_name);
0201             tomoyo_put_name_union(&entry->dir_name);
0202             tomoyo_put_name_union(&entry->fs_type);
0203             tomoyo_put_number_union(&entry->flags);
0204         }
0205         break;
0206     case TOMOYO_TYPE_ENV_ACL:
0207         {
0208             struct tomoyo_env_acl *entry =
0209                 container_of(acl, typeof(*entry), head);
0210 
0211             tomoyo_put_name(entry->env);
0212         }
0213         break;
0214     case TOMOYO_TYPE_INET_ACL:
0215         {
0216             struct tomoyo_inet_acl *entry =
0217                 container_of(acl, typeof(*entry), head);
0218 
0219             tomoyo_put_group(entry->address.group);
0220             tomoyo_put_number_union(&entry->port);
0221         }
0222         break;
0223     case TOMOYO_TYPE_UNIX_ACL:
0224         {
0225             struct tomoyo_unix_acl *entry =
0226                 container_of(acl, typeof(*entry), head);
0227 
0228             tomoyo_put_name_union(&entry->name);
0229         }
0230         break;
0231     case TOMOYO_TYPE_MANUAL_TASK_ACL:
0232         {
0233             struct tomoyo_task_acl *entry =
0234                 container_of(acl, typeof(*entry), head);
0235 
0236             tomoyo_put_name(entry->domainname);
0237         }
0238         break;
0239     }
0240 }
0241 
0242 /**
0243  * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info".
0244  *
0245  * @element: Pointer to "struct list_head".
0246  *
0247  * Returns nothing.
0248  *
0249  * Caller holds tomoyo_policy_lock mutex.
0250  */
0251 static inline void tomoyo_del_domain(struct list_head *element)
0252 {
0253     struct tomoyo_domain_info *domain =
0254         container_of(element, typeof(*domain), list);
0255     struct tomoyo_acl_info *acl;
0256     struct tomoyo_acl_info *tmp;
0257 
0258     /*
0259      * Since this domain is referenced from neither
0260      * "struct tomoyo_io_buffer" nor "struct cred"->security, we can delete
0261      * elements without checking for is_deleted flag.
0262      */
0263     list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
0264         tomoyo_del_acl(&acl->list);
0265         tomoyo_memory_free(acl);
0266     }
0267     tomoyo_put_name(domain->domainname);
0268 }
0269 
0270 /**
0271  * tomoyo_del_condition - Delete members in "struct tomoyo_condition".
0272  *
0273  * @element: Pointer to "struct list_head".
0274  *
0275  * Returns nothing.
0276  */
0277 void tomoyo_del_condition(struct list_head *element)
0278 {
0279     struct tomoyo_condition *cond = container_of(element, typeof(*cond),
0280                              head.list);
0281     const u16 condc = cond->condc;
0282     const u16 numbers_count = cond->numbers_count;
0283     const u16 names_count = cond->names_count;
0284     const u16 argc = cond->argc;
0285     const u16 envc = cond->envc;
0286     unsigned int i;
0287     const struct tomoyo_condition_element *condp
0288         = (const struct tomoyo_condition_element *) (cond + 1);
0289     struct tomoyo_number_union *numbers_p
0290         = (struct tomoyo_number_union *) (condp + condc);
0291     struct tomoyo_name_union *names_p
0292         = (struct tomoyo_name_union *) (numbers_p + numbers_count);
0293     const struct tomoyo_argv *argv
0294         = (const struct tomoyo_argv *) (names_p + names_count);
0295     const struct tomoyo_envp *envp
0296         = (const struct tomoyo_envp *) (argv + argc);
0297 
0298     for (i = 0; i < numbers_count; i++)
0299         tomoyo_put_number_union(numbers_p++);
0300     for (i = 0; i < names_count; i++)
0301         tomoyo_put_name_union(names_p++);
0302     for (i = 0; i < argc; argv++, i++)
0303         tomoyo_put_name(argv->value);
0304     for (i = 0; i < envc; envp++, i++) {
0305         tomoyo_put_name(envp->name);
0306         tomoyo_put_name(envp->value);
0307     }
0308 }
0309 
0310 /**
0311  * tomoyo_del_name - Delete members in "struct tomoyo_name".
0312  *
0313  * @element: Pointer to "struct list_head".
0314  *
0315  * Returns nothing.
0316  */
0317 static inline void tomoyo_del_name(struct list_head *element)
0318 {
0319     /* Nothing to do. */
0320 }
0321 
0322 /**
0323  * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
0324  *
0325  * @element: Pointer to "struct list_head".
0326  *
0327  * Returns nothing.
0328  */
0329 static inline void tomoyo_del_path_group(struct list_head *element)
0330 {
0331     struct tomoyo_path_group *member =
0332         container_of(element, typeof(*member), head.list);
0333 
0334     tomoyo_put_name(member->member_name);
0335 }
0336 
0337 /**
0338  * tomoyo_del_group - Delete "struct tomoyo_group".
0339  *
0340  * @element: Pointer to "struct list_head".
0341  *
0342  * Returns nothing.
0343  */
0344 static inline void tomoyo_del_group(struct list_head *element)
0345 {
0346     struct tomoyo_group *group =
0347         container_of(element, typeof(*group), head.list);
0348 
0349     tomoyo_put_name(group->group_name);
0350 }
0351 
0352 /**
0353  * tomoyo_del_address_group - Delete members in "struct tomoyo_address_group".
0354  *
0355  * @element: Pointer to "struct list_head".
0356  *
0357  * Returns nothing.
0358  */
0359 static inline void tomoyo_del_address_group(struct list_head *element)
0360 {
0361     /* Nothing to do. */
0362 }
0363 
0364 /**
0365  * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
0366  *
0367  * @element: Pointer to "struct list_head".
0368  *
0369  * Returns nothing.
0370  */
0371 static inline void tomoyo_del_number_group(struct list_head *element)
0372 {
0373     /* Nothing to do. */
0374 }
0375 
0376 /**
0377  * tomoyo_try_to_gc - Try to kfree() an entry.
0378  *
0379  * @type:    One of values in "enum tomoyo_policy_id".
0380  * @element: Pointer to "struct list_head".
0381  *
0382  * Returns nothing.
0383  *
0384  * Caller holds tomoyo_policy_lock mutex.
0385  */
0386 static void tomoyo_try_to_gc(const enum tomoyo_policy_id type,
0387                  struct list_head *element)
0388 {
0389     /*
0390      * __list_del_entry() guarantees that the list element became no longer
0391      * reachable from the list which the element was originally on (e.g.
0392      * tomoyo_domain_list). Also, synchronize_srcu() guarantees that the
0393      * list element became no longer referenced by syscall users.
0394      */
0395     __list_del_entry(element);
0396     mutex_unlock(&tomoyo_policy_lock);
0397     synchronize_srcu(&tomoyo_ss);
0398     /*
0399      * However, there are two users which may still be using the list
0400      * element. We need to defer until both users forget this element.
0401      *
0402      * Don't kfree() until "struct tomoyo_io_buffer"->r.{domain,group,acl}
0403      * and "struct tomoyo_io_buffer"->w.domain forget this element.
0404      */
0405     if (tomoyo_struct_used_by_io_buffer(element))
0406         goto reinject;
0407     switch (type) {
0408     case TOMOYO_ID_TRANSITION_CONTROL:
0409         tomoyo_del_transition_control(element);
0410         break;
0411     case TOMOYO_ID_MANAGER:
0412         tomoyo_del_manager(element);
0413         break;
0414     case TOMOYO_ID_AGGREGATOR:
0415         tomoyo_del_aggregator(element);
0416         break;
0417     case TOMOYO_ID_GROUP:
0418         tomoyo_del_group(element);
0419         break;
0420     case TOMOYO_ID_PATH_GROUP:
0421         tomoyo_del_path_group(element);
0422         break;
0423     case TOMOYO_ID_ADDRESS_GROUP:
0424         tomoyo_del_address_group(element);
0425         break;
0426     case TOMOYO_ID_NUMBER_GROUP:
0427         tomoyo_del_number_group(element);
0428         break;
0429     case TOMOYO_ID_CONDITION:
0430         tomoyo_del_condition(element);
0431         break;
0432     case TOMOYO_ID_NAME:
0433         /*
0434          * Don't kfree() until all "struct tomoyo_io_buffer"->r.w[]
0435          * forget this element.
0436          */
0437         if (tomoyo_name_used_by_io_buffer
0438             (container_of(element, typeof(struct tomoyo_name),
0439                   head.list)->entry.name))
0440             goto reinject;
0441         tomoyo_del_name(element);
0442         break;
0443     case TOMOYO_ID_ACL:
0444         tomoyo_del_acl(element);
0445         break;
0446     case TOMOYO_ID_DOMAIN:
0447         /*
0448          * Don't kfree() until all "struct cred"->security forget this
0449          * element.
0450          */
0451         if (atomic_read(&container_of
0452                 (element, typeof(struct tomoyo_domain_info),
0453                  list)->users))
0454             goto reinject;
0455         break;
0456     case TOMOYO_MAX_POLICY:
0457         break;
0458     }
0459     mutex_lock(&tomoyo_policy_lock);
0460     if (type == TOMOYO_ID_DOMAIN)
0461         tomoyo_del_domain(element);
0462     tomoyo_memory_free(element);
0463     return;
0464 reinject:
0465     /*
0466      * We can safely reinject this element here because
0467      * (1) Appending list elements and removing list elements are protected
0468      *     by tomoyo_policy_lock mutex.
0469      * (2) Only this function removes list elements and this function is
0470      *     exclusively executed by tomoyo_gc_mutex mutex.
0471      * are true.
0472      */
0473     mutex_lock(&tomoyo_policy_lock);
0474     list_add_rcu(element, element->prev);
0475 }
0476 
0477 /**
0478  * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
0479  *
0480  * @id:          One of values in "enum tomoyo_policy_id".
0481  * @member_list: Pointer to "struct list_head".
0482  *
0483  * Returns nothing.
0484  */
0485 static void tomoyo_collect_member(const enum tomoyo_policy_id id,
0486                   struct list_head *member_list)
0487 {
0488     struct tomoyo_acl_head *member;
0489     struct tomoyo_acl_head *tmp;
0490 
0491     list_for_each_entry_safe(member, tmp, member_list, list) {
0492         if (!member->is_deleted)
0493             continue;
0494         member->is_deleted = TOMOYO_GC_IN_PROGRESS;
0495         tomoyo_try_to_gc(id, &member->list);
0496     }
0497 }
0498 
0499 /**
0500  * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info".
0501  *
0502  * @list: Pointer to "struct list_head".
0503  *
0504  * Returns nothing.
0505  */
0506 static void tomoyo_collect_acl(struct list_head *list)
0507 {
0508     struct tomoyo_acl_info *acl;
0509     struct tomoyo_acl_info *tmp;
0510 
0511     list_for_each_entry_safe(acl, tmp, list, list) {
0512         if (!acl->is_deleted)
0513             continue;
0514         acl->is_deleted = TOMOYO_GC_IN_PROGRESS;
0515         tomoyo_try_to_gc(TOMOYO_ID_ACL, &acl->list);
0516     }
0517 }
0518 
0519 /**
0520  * tomoyo_collect_entry - Try to kfree() deleted elements.
0521  *
0522  * Returns nothing.
0523  */
0524 static void tomoyo_collect_entry(void)
0525 {
0526     int i;
0527     enum tomoyo_policy_id id;
0528     struct tomoyo_policy_namespace *ns;
0529 
0530     mutex_lock(&tomoyo_policy_lock);
0531     {
0532         struct tomoyo_domain_info *domain;
0533         struct tomoyo_domain_info *tmp;
0534 
0535         list_for_each_entry_safe(domain, tmp, &tomoyo_domain_list,
0536                      list) {
0537             tomoyo_collect_acl(&domain->acl_info_list);
0538             if (!domain->is_deleted || atomic_read(&domain->users))
0539                 continue;
0540             tomoyo_try_to_gc(TOMOYO_ID_DOMAIN, &domain->list);
0541         }
0542     }
0543     list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
0544         for (id = 0; id < TOMOYO_MAX_POLICY; id++)
0545             tomoyo_collect_member(id, &ns->policy_list[id]);
0546         for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
0547             tomoyo_collect_acl(&ns->acl_group[i]);
0548     }
0549     {
0550         struct tomoyo_shared_acl_head *ptr;
0551         struct tomoyo_shared_acl_head *tmp;
0552 
0553         list_for_each_entry_safe(ptr, tmp, &tomoyo_condition_list,
0554                      list) {
0555             if (atomic_read(&ptr->users) > 0)
0556                 continue;
0557             atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
0558             tomoyo_try_to_gc(TOMOYO_ID_CONDITION, &ptr->list);
0559         }
0560     }
0561     list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
0562         for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
0563             struct list_head *list = &ns->group_list[i];
0564             struct tomoyo_group *group;
0565             struct tomoyo_group *tmp;
0566 
0567             switch (i) {
0568             case 0:
0569                 id = TOMOYO_ID_PATH_GROUP;
0570                 break;
0571             case 1:
0572                 id = TOMOYO_ID_NUMBER_GROUP;
0573                 break;
0574             default:
0575                 id = TOMOYO_ID_ADDRESS_GROUP;
0576                 break;
0577             }
0578             list_for_each_entry_safe(group, tmp, list, head.list) {
0579                 tomoyo_collect_member(id, &group->member_list);
0580                 if (!list_empty(&group->member_list) ||
0581                     atomic_read(&group->head.users) > 0)
0582                     continue;
0583                 atomic_set(&group->head.users,
0584                        TOMOYO_GC_IN_PROGRESS);
0585                 tomoyo_try_to_gc(TOMOYO_ID_GROUP,
0586                          &group->head.list);
0587             }
0588         }
0589     }
0590     for (i = 0; i < TOMOYO_MAX_HASH; i++) {
0591         struct list_head *list = &tomoyo_name_list[i];
0592         struct tomoyo_shared_acl_head *ptr;
0593         struct tomoyo_shared_acl_head *tmp;
0594 
0595         list_for_each_entry_safe(ptr, tmp, list, list) {
0596             if (atomic_read(&ptr->users) > 0)
0597                 continue;
0598             atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
0599             tomoyo_try_to_gc(TOMOYO_ID_NAME, &ptr->list);
0600         }
0601     }
0602     mutex_unlock(&tomoyo_policy_lock);
0603 }
0604 
0605 /**
0606  * tomoyo_gc_thread - Garbage collector thread function.
0607  *
0608  * @unused: Unused.
0609  *
0610  * Returns 0.
0611  */
0612 static int tomoyo_gc_thread(void *unused)
0613 {
0614     /* Garbage collector thread is exclusive. */
0615     static DEFINE_MUTEX(tomoyo_gc_mutex);
0616 
0617     if (!mutex_trylock(&tomoyo_gc_mutex))
0618         goto out;
0619     tomoyo_collect_entry();
0620     {
0621         struct tomoyo_io_buffer *head;
0622         struct tomoyo_io_buffer *tmp;
0623 
0624         spin_lock(&tomoyo_io_buffer_list_lock);
0625         list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list,
0626                      list) {
0627             if (head->users)
0628                 continue;
0629             list_del(&head->list);
0630             kfree(head->read_buf);
0631             kfree(head->write_buf);
0632             kfree(head);
0633         }
0634         spin_unlock(&tomoyo_io_buffer_list_lock);
0635     }
0636     mutex_unlock(&tomoyo_gc_mutex);
0637 out:
0638     /* This acts as do_exit(0). */
0639     return 0;
0640 }
0641 
0642 /**
0643  * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users.
0644  *
0645  * @head:        Pointer to "struct tomoyo_io_buffer".
0646  * @is_register: True if register, false if unregister.
0647  *
0648  * Returns nothing.
0649  */
0650 void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register)
0651 {
0652     bool is_write = false;
0653 
0654     spin_lock(&tomoyo_io_buffer_list_lock);
0655     if (is_register) {
0656         head->users = 1;
0657         list_add(&head->list, &tomoyo_io_buffer_list);
0658     } else {
0659         is_write = head->write_buf != NULL;
0660         if (!--head->users) {
0661             list_del(&head->list);
0662             kfree(head->read_buf);
0663             kfree(head->write_buf);
0664             kfree(head);
0665         }
0666     }
0667     spin_unlock(&tomoyo_io_buffer_list_lock);
0668     if (is_write)
0669         kthread_run(tomoyo_gc_thread, NULL, "GC for TOMOYO");
0670 }